diff --git a/CMakeLists.txt b/CMakeLists.txt index 7307acd..3e7d8cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/invodb/btree/btree_node.cpp b/invodb/btree/btree_node.cpp index 2991488..aca49a8 100644 --- a/invodb/btree/btree_node.cpp +++ b/invodb/btree/btree_node.cpp @@ -1,5 +1,18 @@ // -// Created by i on 2021/10/24. +// Created by YuhangQ on 2021/10/25. // #include "btree_node.h" + +std::map 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]; +} diff --git a/invodb/btree/btree_node.h b/invodb/btree/btree_node.h index a55bb43..7709add 100644 --- a/invodb/btree/btree_node.h +++ b/invodb/btree/btree_node.h @@ -7,22 +7,102 @@ #include #include +#include +#include +#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 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 arr[127]; + static std::map map; + int address; + int n_size; + bool leaf; }; #endif //INVODB_BTREE_NODE_H diff --git a/invodb/btree/btree_uuid.cpp b/invodb/btree/btree_uuid.cpp new file mode 100644 index 0000000..86215a5 --- /dev/null +++ b/invodb/btree/btree_uuid.cpp @@ -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; isize(); 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; ival[lLeaf->insert(cur->key[i])] = cur->val[i]; + for(int i=mid; im; 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; iinsert(cur->key[i]); + for(int i=0; i<=mid; i++) newLChild->val[i] = cur->val[i]; + + 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) { + 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; isize(); 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; iinsert(p->link[i].key, p->link[i].value); + for(int i=mid; im; i++) rnode->insert(p->link[i].key, p->link[i].value); + } +} +*/ + diff --git a/invodb/btree/btree_uuid.h b/invodb/btree/btree_uuid.h new file mode 100644 index 0000000..4127a31 --- /dev/null +++ b/invodb/btree/btree_uuid.h @@ -0,0 +1,25 @@ +// +// Created by YuhangQ on 2021/10/25. +// + +#ifndef INVODB_BTREE_UUID_H +#define INVODB_BTREE_UUID_H + +#include + +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 diff --git a/invodb/invodb.cpp b/invodb/invodb.cpp deleted file mode 100644 index 73fb18e..0000000 --- a/invodb/invodb.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// -// Created by YuhangQ on 2021/10/9. -// - -#include "invodb.h" - diff --git a/invodb/invodb.h b/invodb/invodb.h deleted file mode 100644 index e2ef890..0000000 --- a/invodb/invodb.h +++ /dev/null @@ -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 diff --git a/invodb/main.cpp b/invodb/main.cpp index b1968f3..52e4007 100644 --- a/invodb/main.cpp +++ b/invodb/main.cpp @@ -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; } \ No newline at end of file diff --git a/invodb/main.h b/invodb/main.h index 9ad4342..b4d5c0e 100644 --- a/invodb/main.h +++ b/invodb/main.h @@ -6,6 +6,7 @@ #define INVODB_MAIN_H #include -#include "models/collection.h" +#include + #endif //INVODB_MAIN_H diff --git a/invodb/models/collection.cpp b/invodb/models/collection.cpp index bceed5e..dff3bbf 100644 --- a/invodb/models/collection.cpp +++ b/invodb/models/collection.cpp @@ -3,7 +3,6 @@ // #include "collection.h" -#include "utils/uuid.h" Collection::Collection(const std::string &name, const int &firstPage) { Logger::info("load Collection: ", name); diff --git a/invodb/models/collection.h b/invodb/models/collection.h index 08d2b7b..b4e8ca7 100644 --- a/invodb/models/collection.h +++ b/invodb/models/collection.h @@ -7,11 +7,13 @@ #include "file/page_manager.h" #include "utils/logger.h" +#include "btree/btree_uuid.h" #include "json.h" #include #include #include #include +#include "utils/uuid.h" class Collection { public: diff --git a/invodb/models/json.h b/invodb/models/json.h index 9dbfe2c..fdff838 100644 --- a/invodb/models/json.h +++ b/invodb/models/json.h @@ -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: }; diff --git a/invodb/utils/uuid.h b/invodb/utils/uuid.h index 1c3bc63..d73c5f9 100644 --- a/invodb/utils/uuid.h +++ b/invodb/utils/uuid.h @@ -8,8 +8,7 @@ #include #include -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)));