From 177cee9f913a72eb402be9fb2485038127dc843c Mon Sep 17 00:00:00 2001 From: YuhangQ Date: Tue, 26 Oct 2021 12:29:59 +0800 Subject: [PATCH] btree insert finished! --- .gitignore | 1 + invodb/btree/btree_node.cpp | 84 ++++++++++++++++++++-- invodb/btree/btree_node.h | 103 ++++----------------------- invodb/btree/btree_uuid.cpp | 131 ++++++++++++++++++++++------------- invodb/btree/btree_uuid.h | 7 +- invodb/file/page_manager.cpp | 1 + invodb/file/storage_page.h | 2 +- invodb/main.cpp | 4 +- invodb/main.h | 2 + invodb/models/collection.cpp | 1 - 10 files changed, 188 insertions(+), 148 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d28bdd --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +test.invodb \ No newline at end of file diff --git a/invodb/btree/btree_node.cpp b/invodb/btree/btree_node.cpp index aca49a8..2fea8c2 100644 --- a/invodb/btree/btree_node.cpp +++ b/invodb/btree/btree_node.cpp @@ -7,12 +7,86 @@ std::map BTreeNodeUUID::map; BTreeNodeUUID *BTreeNodeUUID::getNode(const int &address) { - if(address == 0) { - printf("???"); - exit(0); - } - if(map.count(address) == 0) { + if(true || map.count(address) == 0) { map[address] = new BTreeNodeUUID(address); } return map[address]; } + +BTreeNodeUUID::BTreeNodeUUID(const int& address):address(address) { + clear(); + StoragePage page = PageManager::Instance().getPage(address); + int p = 0; + size = page.getIntStartFrom(p); + p += 4; + parent = page.getIntStartFrom(p); + p += 4; + left = page.getIntStartFrom(p); + p += 4; + right = page.getIntStartFrom(p); + p += 4; + leaf = !page.getIntStartFrom(p); + p += 4; + for(int i=0; i key[pos]) pos++; + val[size + 1] = val[size]; + for(int i=size; i>pos; i--) { + val[i] = val[i - 1]; + key[i] = key[i - 1]; + } + key[pos] = uuid; + size++; + return pos; +} + +void BTreeNodeUUID::print() { + printf("---------BTreeNode---------\n"); + for(int i=0; iparent; - child.parent = address; - child.save(); - } - } - int size() { - return n_size; - } - int insert(const std::string uuid) { - -// static int cnt = 0; -// if(!isLeaf() && size() >= 27) { -// if(cnt) throw "fuck"; -// cnt++; -// } - 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--) { - val[i] = val[i - 1]; - key[i] = key[i - 1]; - } - key[pos] = uuid; - n_size++; - return pos; - } - void print() { - printf("---------BTreeNode---------\n"); - for(int i=0; i map; - int address; - int n_size; + int left; + int right; bool leaf; + int size; + int address; +private: + BTreeNodeUUID(const int& address); + static std::map map; + }; #endif //INVODB_BTREE_NODE_H diff --git a/invodb/btree/btree_uuid.cpp b/invodb/btree/btree_uuid.cpp index c47a65a..357ae27 100644 --- a/invodb/btree/btree_uuid.cpp +++ b/invodb/btree/btree_uuid.cpp @@ -5,41 +5,46 @@ #include "btree_uuid.h" BTreeUUID::BTreeUUID(const int& address) { - root = BTreeNodeUUID::getNode(address); + root = address; } void BTreeUUID::insert(const char *uuid, int address) { - BTreeNodeUUID* cur = root; + BTreeNodeUUID* cur = BTreeNodeUUID::getNode(root); BTreeNodeUUID* parent = nullptr; - while(!cur->isLeaf()) { + while(!cur->leaf) { parent = cur; - for(int i=0; isize(); i++) { + for(int i=0; isize; i++) { if(uuid < cur->key[i]) { cur = BTreeNodeUUID::getNode(cur->val[i]); break; } - if(i == cur->size() - 1) { + if(i == cur->size - 1) { cur = BTreeNodeUUID::getNode(cur->val[i + 1]); break; } } - cur->parent = parent->getAddress(); + cur->parent = parent->address; + cur->save(); } // insert directly - if(cur->size() < cur->m - 1) { + if(cur->size < cur->m - 1) { cur->val[cur->insert(uuid)] = address; cur->save(); return; } // split - split(uuid, address, parent, cur); + if(parent == nullptr) split(uuid, address, 0, cur->address); + else split(uuid, address, parent->address, cur->address); } -void BTreeUUID::split(std::string uuid, int address, BTreeNodeUUID *parent, BTreeNodeUUID *cur) { +void BTreeUUID::split(std::string uuid, int address, int parentAddr, int curAddr) { + + BTreeNodeUUID* parent = BTreeNodeUUID::getNode(parentAddr); + BTreeNodeUUID* cur = BTreeNodeUUID::getNode(curAddr); cur->val[cur->insert(uuid)] = address; @@ -48,30 +53,42 @@ void BTreeUUID::split(std::string uuid, int address, BTreeNodeUUID *parent, BTre int mid = (cur->m / 2); for(int i=0; ival[lLeaf->insert(cur->key[i])] = cur->val[i]; + lLeaf->right = rLeaf->address; + lLeaf->left = cur->left; for(int i=mid; im; i++) rLeaf->val[rLeaf->insert(cur->key[i])] = cur->val[i]; + rLeaf->left = rLeaf->address; + rLeaf->right = cur->right; - if(cur == root) { + if(cur->address == 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->val[0] = lLeaf->address; + newRoot->val[1] = rLeaf->address; + newRoot->leaf = false; + root = newRoot->address; + lLeaf->parent = rLeaf->parent = root; newRoot->save(); lLeaf->save(); rLeaf->save(); - } else insertInternal(rLeaf->key[0], parent, lLeaf, rLeaf); + } else { + lLeaf->save(); + rLeaf->save(); + insertInternal(rLeaf->key[0], parent->address, lLeaf->address, rLeaf->address); + } } -void BTreeUUID::insertInternal(std::string uuid, BTreeNodeUUID *cur, BTreeNodeUUID *lLeaf, BTreeNodeUUID *rLeaf) { +void BTreeUUID::insertInternal(std::string uuid, int curAddr, int lLeafAddr, int rLeafAddr) { - if(cur->size() < cur->m - 1) { + BTreeNodeUUID *cur = BTreeNodeUUID::getNode(curAddr); + BTreeNodeUUID *lLeaf = BTreeNodeUUID::getNode(lLeafAddr); + BTreeNodeUUID *rLeaf = BTreeNodeUUID::getNode(rLeafAddr); + + 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->val[pos] = lLeaf->address; + cur->val[pos+1] = rLeaf->address; + lLeaf->parent = rLeaf->parent = root; cur->save(); lLeaf->save(); rLeaf->save(); @@ -80,19 +97,14 @@ void BTreeUUID::insertInternal(std::string uuid, BTreeNodeUUID *cur, BTreeNodeUU BTreeNodeUUID* newLChild = BTreeNodeUUID::getNode(PageManager::Instance().allocate()); BTreeNodeUUID* newRChild = BTreeNodeUUID::getNode(PageManager::Instance().allocate()); - newLChild->setLeaf(false); - newRChild->setLeaf(false); - - if(cur->size() != 27) { - printf("%d %d %d p:%d cur:%d\n", cur->size(), cur->isLeaf(), cur==root, cur->parent, cur->getAddress()); - exit(0); - } + newLChild->leaf = false; + newRChild->leaf = false; int pos = cur->insert(uuid); - cur->val[pos] = lLeaf->getAddress(); - cur->val[pos+1] = rLeaf->getAddress(); + cur->val[pos] = lLeaf->address; + cur->val[pos+1] = rLeaf->address; - int mid = cur->size() / 2; + int mid = cur->size / 2; for(int i=0; iinsert(cur->key[i]); for(int i=0; i<=mid; i++) newLChild->val[i] = cur->val[i]; @@ -100,46 +112,70 @@ void BTreeUUID::insertInternal(std::string uuid, BTreeNodeUUID *cur, BTreeNodeUU for(int i=mid+1; im; 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) { + lLeaf->save(); + rLeaf->save(); + + if(cur->address == 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->val[0] = newLChild->address; + newRoot->val[1] = newRChild->address; + newRoot->leaf = false; + root = newRoot->address; + newLChild->parent = newRChild->parent = root; newRoot->save(); newLChild->save(); newRChild->save(); } else { - insertInternal(cur->key[mid], BTreeNodeUUID::getNode(cur->parent), newLChild, newRChild); + newLChild->save(); + newRChild->save(); + if(cur->parent == 0) throw "fuck"; + insertInternal(cur->key[mid], cur->parent, newLChild->address, newRChild->address); } - } void BTreeUUID::print() { - innerPrint(root); + innerPrint(BTreeNodeUUID::getNode(root)); } void BTreeUUID::innerPrint(BTreeNodeUUID *cur) { - if(cur == root) { + if(cur->address == 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; isize(); i++) { + if(cur->leaf) cnt += cur->size; + printf("---------%d(%d)count=%d&sum=%d---l:%d,r:%d-----\n", cur->address, cur->leaf, cur->size, cnt, cur->left, cur->right); + for(int i=0; isize; i++) { printf("%d:%s ", i, cur->key[i].substr(0, 4).c_str()); } printf("\n"); - for(int i=0; i<=cur->size(); i++) { + 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++) { + + + if(cur->leaf) return; + for(int i=0; i<=cur->size; i++) { innerPrint(BTreeNodeUUID::getNode(cur->val[i])); } + + + /* + BTreeNodeUUID test = *cur; + test.address = PageManager::Instance().allocate(); + test.print(); + + + test.save(); + + BTreeNodeUUID test2 = *BTreeNodeUUID::getNode(test.address); + + printf("test: size:%d l:%d r:%d\n", test2.size, test2.left, test2.right); + test2.print(); + */ + + } /* void BTreeUUID::innerInsert(BTreeNodeUUID* &p, BTreeNodeUUID* f, const char *uuid, int address) { @@ -161,3 +197,4 @@ void BTreeUUID::innerInsert(BTreeNodeUUID* &p, BTreeNodeUUID* f, const char *uui } */ + diff --git a/invodb/btree/btree_uuid.h b/invodb/btree/btree_uuid.h index 0b44d13..d489557 100644 --- a/invodb/btree/btree_uuid.h +++ b/invodb/btree/btree_uuid.h @@ -10,14 +10,13 @@ class BTreeUUID { public: BTreeUUID(const int& address); - ~BTreeUUID() { delete root; }; void insert(const char* uuid, int address); void print(); private: void innerPrint(BTreeNodeUUID* cur); - void split(std::string uuid, int address, BTreeNodeUUID* parent, BTreeNodeUUID* cur); - void insertInternal(std::string uuid, BTreeNodeUUID* cur, BTreeNodeUUID* lLeaf, BTreeNodeUUID* rLeaf); - BTreeNodeUUID *root; + void split(std::string uuid, int address, int parentAddr, int curAddr); + void insertInternal(std::string uuid, int curAddr, int lLeafAddr, int rLeafAddr); + int root; int cnt; }; diff --git a/invodb/file/page_manager.cpp b/invodb/file/page_manager.cpp index 4f5face..1f839bb 100644 --- a/invodb/file/page_manager.cpp +++ b/invodb/file/page_manager.cpp @@ -22,6 +22,7 @@ void PageManager::setPage(const int &index, const StoragePage &page) { stream.clear(); stream.seekg(index * 1024); stream.write(page, 1024); + stream.flush(); } int PageManager::allocate() { diff --git a/invodb/file/storage_page.h b/invodb/file/storage_page.h index 71c5e00..90b902a 100644 --- a/invodb/file/storage_page.h +++ b/invodb/file/storage_page.h @@ -24,7 +24,7 @@ public: void setStringStartFrom(const int &index, const char *str); int *intArray(); StoragePage(const int& id) { memset(page, 0, sizeof(page)); this->address = id; } - char& operator[] (int index) { return this->page[index]; } + char& operator[] (int index) { if(index>=1024 || index < 0) throw "overflow"; else return this->page[index]; } operator const char *() const { return this->page; } operator char *() { return this->page; } int getAddress(); diff --git a/invodb/main.cpp b/invodb/main.cpp index 63ced14..911e34b 100644 --- a/invodb/main.cpp +++ b/invodb/main.cpp @@ -14,6 +14,7 @@ int main() { PageManager& manager = PageManager::Instance(); + Collection *col; try { col = &Collection::getCollection("hello"); @@ -24,10 +25,9 @@ int main() { JSON json("{\"hello\": 1}"); col->insert(json); - BTreeUUID *btree = new BTreeUUID(PageManager::Instance().allocate()); char uuid[32]; - for(int i=0; i<100000; i++) { + for(int i=0; i<1000000; i++) { generateUUID(uuid); btree->insert(uuid, PageManager::Instance().allocate()); } diff --git a/invodb/main.h b/invodb/main.h index b4d5c0e..38d6d77 100644 --- a/invodb/main.h +++ b/invodb/main.h @@ -6,6 +6,8 @@ #define INVODB_MAIN_H #include +#include +#include #include diff --git a/invodb/models/collection.cpp b/invodb/models/collection.cpp index dff3bbf..7aa8a7d 100644 --- a/invodb/models/collection.cpp +++ b/invodb/models/collection.cpp @@ -9,7 +9,6 @@ Collection::Collection(const std::string &name, const int &firstPage) { } void Collection::insert(JSON &json) { - if(!json.HasMember("__Invo_ID__")) { char uuid[32]; generateUUID(uuid);