btree init

This commit is contained in:
YuhangQ 2021-10-25 22:07:18 +08:00
parent f5a93fae0f
commit 612005483a
13 changed files with 314 additions and 46 deletions

View File

@ -8,4 +8,4 @@ include_directories(./invodb)
add_executable(InvoDB
invodb/main.cpp
invodb/main.h invodb/file/page_manager.cpp invodb/file/page_manager.h invodb/models/json.cpp invodb/models/json.h invodb/invodb.cpp invodb/invodb.h invodb/models/collection.cpp invodb/models/collection.h invodb/file/storage_page.cpp invodb/file/storage_page.h invodb/utils/logger.h invodb/utils/uuid.h invodb/btree/btree_node.cpp invodb/btree/btree_node.h)
invodb/main.h invodb/file/page_manager.cpp invodb/file/page_manager.h invodb/models/json.cpp invodb/models/json.h invodb/models/collection.cpp invodb/models/collection.h invodb/file/storage_page.cpp invodb/file/storage_page.h invodb/utils/logger.h invodb/utils/uuid.h invodb/btree/btree_node.h invodb/btree/btree_uuid.cpp invodb/btree/btree_uuid.h invodb/btree/btree_node.cpp)

View File

@ -1,5 +1,18 @@
//
// Created by i on 2021/10/24.
// Created by YuhangQ on 2021/10/25.
//
#include "btree_node.h"
std::map<int, BTreeNodeUUID*> BTreeNodeUUID::map;
BTreeNodeUUID *BTreeNodeUUID::getNode(const int &address) {
if(address == 0) {
printf("???");
exit(0);
}
if(map.count(address) == 0) {
map[address] = new BTreeNodeUUID(address);
}
return map[address];
}

View File

@ -7,22 +7,102 @@
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include "file/page_manager.h"
/**
* m = 16
* value string max 56
* (56 + 4)*16 + 4 * 16 = 1024
* m = 28
* value string max
* (32 + 4)*28 + 5 = 1013
*/
class BTreeNode {
class BTreeNodeUUID {
public:
BTreeNode() { memset(arr, 0, sizeof(arr)); }
static BTreeNodeUUID* getNode(const int& address);
BTreeNodeUUID(const int& address):address(address) {
clear();
StoragePage page = PageManager::Instance().getPage(address);
for(int i=0; i<28; i++) {
for(int j=0; j<32; j++) {
key[i] += page[i * 32 + j];
}
}
int p = 28 * 32;
for(int i=0; i<m+1; i++) {
val[i] = page.getIntStartFrom(p);
p += 4;
}
leaf = !page[1013];
parent = page.getIntStartFrom(1014);
}
bool isLeaf() {
return leaf;
}
void setLeaf(const bool& value) {
leaf = value;
}
void updateParent() {
if(isLeaf()) return;
for(int i=0; i<=size(); i++) {
}
}
int size() {
return n_size;
}
int insert(const std::string uuid) {
int pos = 0;
while(pos < n_size && uuid > key[pos]) pos++;
val[n_size + 1] = val[n_size];
for(int i=n_size; i>pos; i--) {
key[i] = key[i - 1];
val[i] = val[i - 1];
}
key[pos] = uuid;
n_size++;
return pos;
}
void print() {
printf("---------BTreeNode---------\n");
for(int i=0; i<size(); i++) {
printf("%s %d\n", key[i].c_str(), val[i]);
}
}
void clear() {
for(int i=0; i<m; i++) key[i].clear(), val[i] = 0;
n_size = 0;
leaf = false;
parent = 0;
}
int getAddress() { return address; }
void save() {
StoragePage page(address);
for(int i=0; i<28; i++) {
for(int j=0; j<32; j++) {
page[i * 32 + j] = key[i][j];
}
}
int p = 28 * 32;
for(int i=0; i<m+1; i++) {
page.setIntStartFrom(p, val[i]);
p += 4;
}
page[1013] = !leaf;
page.setIntStartFrom(1014, parent);
page.save();
}
static const int m = 28;
std::string key[m];
int val[m+1];
int parent;
private:
struct NodeValue {
char key[56];
int value;
};
std::pair<char *, int> arr[127];
static std::map<int, BTreeNodeUUID*> map;
int address;
int n_size;
bool leaf;
};
#endif //INVODB_BTREE_NODE_H

159
invodb/btree/btree_uuid.cpp Normal file
View File

@ -0,0 +1,159 @@
//
// Created by YuhangQ on 2021/10/25.
//
#include "btree_uuid.h"
BTreeUUID::BTreeUUID(const int& address) {
root = BTreeNodeUUID::getNode(address);
}
void BTreeUUID::insert(const char *uuid, int address) {
BTreeNodeUUID* cur = root;
BTreeNodeUUID* parent = nullptr;
while(!cur->isLeaf()) {
parent = cur;
for(int i=0; i<cur->size(); i++) {
if(uuid < cur->key[i]) {
cur = BTreeNodeUUID::getNode(cur->val[i]);
break;
}
if(i == cur->size() - 1) {
cur = BTreeNodeUUID::getNode(cur->val[i + 1]);
break;
}
}
cur->parent = cur->getAddress();
}
// insert directly
if(cur->size() < cur->m - 1) {
cur->val[cur->insert(uuid)] = address;
cur->save();
return;
}
// split
split(uuid, address, parent, cur);
}
void BTreeUUID::split(std::string uuid, int address, BTreeNodeUUID *parent, BTreeNodeUUID *cur) {
cur->val[cur->insert(uuid)] = address;
BTreeNodeUUID* lLeaf = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
BTreeNodeUUID* rLeaf = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
int mid = (cur->m / 2);
for(int i=0; i<mid; i++) lLeaf->val[lLeaf->insert(cur->key[i])] = cur->val[i];
for(int i=mid; i<cur->m; i++) rLeaf->val[rLeaf->insert(cur->key[i])] = cur->val[i];
if(cur == root) {
BTreeNodeUUID* newRoot = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
newRoot->insert(rLeaf->key[0]);
newRoot->val[0] = lLeaf->getAddress();
newRoot->val[1] = rLeaf->getAddress();
newRoot->setLeaf(false);
root = newRoot;
lLeaf->parent = rLeaf->parent = root->getAddress();
newRoot->save();
lLeaf->save();
rLeaf->save();
} else insertInternal(rLeaf->key[0], parent, lLeaf, rLeaf);
}
void BTreeUUID::insertInternal(std::string uuid, BTreeNodeUUID *cur, BTreeNodeUUID *lLeaf, BTreeNodeUUID *rLeaf) {
if(cur->size() < cur->m - 1) {
int pos = cur->insert(uuid);
cur->val[pos] = lLeaf->getAddress();
cur->val[pos+1] = rLeaf->getAddress();
lLeaf->parent = rLeaf->parent = root->getAddress();
cur->save();
lLeaf->save();
rLeaf->save();
return;
}
BTreeNodeUUID* newLChild = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
BTreeNodeUUID* newRChild = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
newLChild->setLeaf(false);
newRChild->setLeaf(false);
int pos = cur->insert(uuid);
cur->val[pos] = lLeaf->getAddress();
cur->val[pos+1] = rLeaf->getAddress();
int mid = cur->size() / 2;
for(int i=0; i<mid; i++) newLChild->insert(cur->key[i]);
for(int i=0; i<=mid; i++) newLChild->val[i] = cur->val[i];
for(int i=mid+1; i<cur->m; i++) newRChild->insert(cur->key[i]);
for(int i=mid+1; i<=cur->m; i++) newRChild->val[i-mid-1] = cur->val[i];
if(cur == root) {
BTreeNodeUUID* newRoot = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
newRoot->insert(cur->key[mid]);
newRoot->val[0] = newLChild->getAddress();
newRoot->val[1] = newRChild->getAddress();
newRoot->setLeaf(false);
root = newRoot;
newLChild->parent = newRChild->parent = root->getAddress();
newRoot->save();
newLChild->save();
newRChild->save();
} else {
insertInternal(cur->key[mid], BTreeNodeUUID::getNode(cur->parent), newLChild, newRChild);
}
}
void BTreeUUID::print() {
innerPrint(root);
}
void BTreeUUID::innerPrint(BTreeNodeUUID *cur) {
if(cur == root) {
cnt = 0;
}
if(cur->isLeaf()) cnt += cur->size();
printf("---------%d(%d)count=%d&sum=%d--------\n", cur->getAddress(), cur->isLeaf(), cur->size(), cnt);
for(int i=0; i<cur->size(); i++) {
printf("%d:%s ", i, cur->key[i].substr(0, 4).c_str());
}
printf("\n");
for(int i=0; i<=cur->size(); i++) {
printf("%d:%d ", i, cur->val[i]);
}
printf("\n");
if(cur->isLeaf()) return;
for(int i=0; i<=cur->size(); i++) {
innerPrint(BTreeNodeUUID::getNode(cur->val[i]));
}
}
/*
void BTreeUUID::innerInsert(BTreeNodeUUID* &p, BTreeNodeUUID* f, const char *uuid, int address) {
if(p == nullptr) {
p = new BTreeNodeUUID(PageManager::Instance().allocate());
p->insert(uuid, address);
return;
}
p->insert(uuid, address);
p->print();
// full
if(p->size() == p->m) {
int mid = p->m / 2;
BTreeNodeUUID* lnode = new BTreeNodeUUID(PageManager::Instance().allocate());
BTreeNodeUUID* rnode = new BTreeNodeUUID(PageManager::Instance().allocate());
for(int i=0; i<mid; i++) lnode->insert(p->link[i].key, p->link[i].value);
for(int i=mid; i<p->m; i++) rnode->insert(p->link[i].key, p->link[i].value);
}
}
*/

25
invodb/btree/btree_uuid.h Normal file
View File

@ -0,0 +1,25 @@
//
// Created by YuhangQ on 2021/10/25.
//
#ifndef INVODB_BTREE_UUID_H
#define INVODB_BTREE_UUID_H
#include <btree/btree_node.h>
class BTreeUUID {
public:
BTreeUUID(const int& address);
~BTreeUUID() { delete root; };
void insert(const char* uuid, int address);
void print();
void innerPrint(BTreeNodeUUID* cur);
private:
void split(std::string uuid, int address, BTreeNodeUUID* parent, BTreeNodeUUID* cur);
void insertInternal(std::string uuid, BTreeNodeUUID* cur, BTreeNodeUUID* lLeaf, BTreeNodeUUID* rLeaf);
BTreeNodeUUID *root;
int cnt;
};
#endif //INVODB_BTREE_UUID_H

View File

@ -1,6 +0,0 @@
//
// Created by YuhangQ on 2021/10/9.
//
#include "invodb.h"

View File

@ -1,20 +0,0 @@
//
// Created by YuhangQ on 2021/10/9.
//
#ifndef INVODB_INVODB_H
#define INVODB_INVODB_H
#include "models/json.h"
#include "models/collection.h"
class InvoDB {
public:
Collection createCollection();
Collection getCollection();
void deleteCollection();
};
#endif //INVODB_INVODB_H

View File

@ -5,17 +5,34 @@
#include "main.h"
int main() {
srand(time(NULL));
system("rm -rf test.invodb && touch test.invodb");
PageManager::loadDatabase("test.invodb");
Collection::loadCollections();
PageManager& manager = PageManager::Instance();
//Collection::createCollection("hello");
Collection &col = Collection::getCollection("hello");
Collection *col;
try {
col = &Collection::getCollection("hello");
} catch(const char *error) {
Collection::createCollection("hello");
}
JSON json("{\"hello\": 1}");
col.insert(json);
col->insert(json);
BTreeUUID *btree = new BTreeUUID(PageManager::Instance().allocate());
char uuid[32];
for(int i=0; i<1000; i++) {
generateUUID(uuid);
btree->insert(uuid, PageManager::Instance().allocate());
}
btree->print();
return 0;
}

View File

@ -6,6 +6,7 @@
#define INVODB_MAIN_H
#include <iostream>
#include "models/collection.h"
#include <models/collection.h>
#endif //INVODB_MAIN_H

View File

@ -3,7 +3,6 @@
//
#include "collection.h"
#include "utils/uuid.h"
Collection::Collection(const std::string &name, const int &firstPage) {
Logger::info<std::string, std::string>("load Collection: ", name);

View File

@ -7,11 +7,13 @@
#include "file/page_manager.h"
#include "utils/logger.h"
#include "btree/btree_uuid.h"
#include "json.h"
#include <map>
#include <set>
#include <algorithm>
#include <cstring>
#include "utils/uuid.h"
class Collection {
public:

View File

@ -16,7 +16,6 @@ class JSON : public Document {
public:
JSON(std::string json): Document() { this->Parse(json.c_str()); }
JSON(const char *json): Document() { this->Parse(json); }
std::string ToString();
private:
};

View File

@ -8,8 +8,7 @@
#include <iostream>
#include <string>
void generateUUID(char *uuid) {
srand(time(NULL));
inline void generateUUID(char *uuid) {
for(int i=0; i<32; i++) {
int randn = rand() % 36;
uuid[i] = (randn < 26 ? ('a' + randn) : ('0' + (randn - 26)));