diff --git a/invodb/btree/btree.h b/invodb/btree/btree.h index 8315723..e15c2aa 100644 --- a/invodb/btree/btree.h +++ b/invodb/btree/btree.h @@ -8,18 +8,19 @@ #include "btree/node.h" #include "utils/uuid.h" -template +template class BTree { public: BTree(const int& address); - void insert(const KT &key, const VT &value); - void update(const KT &key, const VT &value); + void insert(const KT &key, const int &value); + void update(const KT &key, const int &value); void remove(const KT &key); + bool exists(const KT &key); int getNodeSize(); - VT find(const KT &key); + int find(const KT &key); int size(); private: - void removeEntry(int curAdd, const std::string& key, const int& pointer); + void removeEntry(int curAdd, const KT& key, const int& pointer); bool canCoalesce(int curAdd, int sibAdd); void coalesce(int curAdd, int sibAdd); bool canRedistribute(int curAdd, int sibAdd); @@ -31,23 +32,24 @@ private: int n_size; }; -// BTree BTreeNode +// BTree BTreeNode -template -BTree::BTree(const int& address) { + +template +BTree::BTree(const int& address) { root = address; n_size = 0; } -template -void BTree::insert(const KT &key, const VT &value) { - if(find(key) != -1) { +template +void BTree::insert(const KT &key, const int &value) { + if(exists(key)) { throw "keySet already exists."; } n_size++; - auto cur = BTreeNode::getNode(findNode(key)); + auto cur = BTreeNode::getNode(findNode(key)); // insert directly if(cur->size < cur->m - 1) { @@ -60,43 +62,43 @@ void BTree::insert(const KT &key, const VT &valu split(key, value, cur->parent, cur->address); } -template -void BTree::update(const KT &key, const VT &value) { - if(find(key) == -1) { +template +void BTree::update(const KT &key, const int &value) { + if(!exists(key)) { throw "keySet doesn't exists."; } - auto cur = BTreeNode::getNode(findNode(key)); + auto cur = BTreeNode::getNode(findNode(key)); cur->linkSet[cur->findPos(key)] = value; cur->save(); } -template -void BTree::remove(const KT &key) { - if(find(key) == -1) { - throw "keySet doesn't exists."; +template +void BTree::remove(const KT &key) { + if(!exists(key)) { + throw "keySet already exists."; } n_size--; - auto cur = BTreeNode::getNode(findNode(key)); + auto cur = BTreeNode::getNode(findNode(key)); removeEntry(cur->address, key, find(key)); } -template -VT BTree::find(const KT &key) { - auto cur = BTreeNode::getNode(findNode(key)); +template +int BTree::find(const KT &key) { + auto cur = BTreeNode::getNode(findNode(key)); for(int i=0; isize; i++) { if(key == cur->keySet[i]) return cur->linkSet[i]; } return -1; } -template -int BTree::size() { +template +int BTree::size() { return n_size; } -template -void BTree::removeEntry(int curAdd, const std::string &key, const int &pointer) { - auto cur = BTreeNode::getNode(curAdd); +template +void BTree::removeEntry(int curAdd, const KT &key, const int &pointer) { + auto cur = BTreeNode::getNode(curAdd); int pos = cur->findPos(key); if(pos == -1) return; for(int i=pos; isize-1; i++) { @@ -110,7 +112,7 @@ void BTree::removeEntry(int curAdd, const std::s if(curAdd == root && !cur->leaf && cur->size == 0) { root = cur->linkSet[0]; - BTreeNode* root = BTreeNode::getNode(cur->linkSet[0]); + auto root = BTreeNode::getNode(cur->linkSet[0]); root->parent = 0; root->save(); cur->release(); @@ -132,21 +134,21 @@ void BTree::removeEntry(int curAdd, const std::s } } -template -bool BTree::canCoalesce(int curAdd, int sibAdd) { +template +bool BTree::canCoalesce(int curAdd, int sibAdd) { if(sibAdd == 0) return false; - auto cur = BTreeNode::getNode(curAdd); - auto sib = BTreeNode::getNode(sibAdd); + auto cur = BTreeNode::getNode(curAdd); + auto sib = BTreeNode::getNode(sibAdd); if(cur->parent != sib->parent) return false; - return (cur->size + sib->size <= BTreeNode::m - 1 - !cur->leaf); + return (cur->size + sib->size <= BTreeNode::m - 1 - !cur->leaf); } -template -void BTree::coalesce(int curAdd, int sibAdd) { - auto cur = BTreeNode::getNode(curAdd); - auto sib = BTreeNode::getNode(sibAdd); - auto parent = BTreeNode::getNode(cur->parent); - std::string *k; +template +void BTree::coalesce(int curAdd, int sibAdd) { + auto cur = BTreeNode::getNode(curAdd); + auto sib = BTreeNode::getNode(sibAdd); + auto parent = BTreeNode::getNode(cur->parent); + KT *k; for(int i=0; isize; i++) { if((parent->linkSet[i] == curAdd && parent->linkSet[i+1] == sibAdd) || (parent->linkSet[i] == sibAdd && parent->linkSet[i+1] == curAdd)) { @@ -154,7 +156,7 @@ void BTree::coalesce(int curAdd, int sibAdd) { break; } } - BTreeNode* newNode = nullptr; + BTreeNode* newNode = nullptr; if(cur->left == sibAdd) { if(!cur->leaf) sib->insert(*k); for(int i=0; isize; i++) { @@ -163,7 +165,7 @@ void BTree::coalesce(int curAdd, int sibAdd) { sib->linkSet[sib->size] = cur->linkSet[cur->size]; sib->right = cur->right; if(cur->right) { - BTreeNode *right = BTreeNode::getNode(cur->right); + BTreeNode *right = BTreeNode::getNode(cur->right); right->left = sib->address; right->save(); } @@ -181,7 +183,7 @@ void BTree::coalesce(int curAdd, int sibAdd) { cur->right = sib->right; if(sib->right) { - BTreeNode *right = BTreeNode::getNode(sib->right); + BTreeNode *right = BTreeNode::getNode(sib->right); right->left = cur->address; right->save(); } @@ -192,27 +194,27 @@ void BTree::coalesce(int curAdd, int sibAdd) { } if(newNode->leaf) return; for(int i=0; i<=newNode->size; i++) { - auto child = BTreeNode::getNode(newNode->linkSet[i]); + auto child = BTreeNode::getNode(newNode->linkSet[i]); child->parent = newNode->address; child->save(); } } -template -bool BTree::canRedistribute(int curAdd, int sibAdd) { +template +bool BTree::canRedistribute(int curAdd, int sibAdd) { if(sibAdd == 0) return false; - auto cur = BTreeNode::getNode(curAdd); - auto sib = BTreeNode::getNode(sibAdd); + auto cur = BTreeNode::getNode(curAdd); + auto sib = BTreeNode::getNode(sibAdd); if(cur->parent != sib->parent) return false; return sib->size > ((sib->m - !sib->leaf) / 2); } -template -void BTree::redistribute(int curAdd, int sibAdd) { - auto cur = BTreeNode::getNode(curAdd); - auto sib = BTreeNode::getNode(sibAdd); - auto parent = BTreeNode::getNode(cur->parent); - std::string k; +template +void BTree::redistribute(int curAdd, int sibAdd) { + auto cur = BTreeNode::getNode(curAdd); + auto sib = BTreeNode::getNode(sibAdd); + auto parent = BTreeNode::getNode(cur->parent); + KT k; int pos; for(pos=0; possize; pos++) { if((parent->linkSet[pos] == curAdd && parent->linkSet[pos+1] == sibAdd) @@ -231,7 +233,7 @@ void BTree::redistribute(int curAdd, int sibAdd) parent->keySet[pos] = sib->keySet[sib->size-1]; } if(!cur->leaf) { - BTreeNode *child = BTreeNode::getNode(sib->linkSet[sib->size - cur->leaf]); + BTreeNode *child = BTreeNode::getNode(sib->linkSet[sib->size - cur->leaf]); child->parent = cur->address; child->save(); } @@ -254,7 +256,7 @@ void BTree::redistribute(int curAdd, int sibAdd) } parent->keySet[pos] = sib->keySet[0]; if(!cur->leaf) { - auto child = BTreeNode::getNode(sib->linkSet[0]); + auto child = BTreeNode::getNode(sib->linkSet[0]); child->parent = cur->address; child->save(); } @@ -271,17 +273,17 @@ void BTree::redistribute(int curAdd, int sibAdd) parent->save(); } -template -int BTree::findNode(const KT &key) { - auto cur = BTreeNode::getNode(root); +template +int BTree::findNode(const KT &key) { + auto cur = BTreeNode::getNode(root); while(!cur->leaf) { for(int i=0; isize; i++) { if(key < cur->keySet[i]) { - cur = BTreeNode::getNode(cur->linkSet[i]); + cur = BTreeNode::getNode(cur->linkSet[i]); break; } if(i == cur->size - 1) { - cur = BTreeNode::getNode(cur->linkSet[i + 1]); + cur = BTreeNode::getNode(cur->linkSet[i + 1]); break; } } @@ -289,14 +291,14 @@ int BTree::findNode(const KT &key) { return cur->address; } -template -void BTree::split(const KT &key, int address, int parentAdd, int curAdd) { - auto cur = BTreeNode::getNode(curAdd); +template +void BTree::split(const KT &key, int address, int parentAdd, int curAdd) { + auto cur = BTreeNode::getNode(curAdd); cur->linkSet[cur->insert(key)] = address; - auto lLeaf = BTreeNode::getNode(PageManager::Instance().allocate()); - auto rLeaf = BTreeNode::getNode(PageManager::Instance().allocate()); + auto lLeaf = BTreeNode::getNode(PageManager::Instance().allocate()); + auto rLeaf = BTreeNode::getNode(PageManager::Instance().allocate()); int mid = (cur->m / 2); for(int i=0; ilinkSet[lLeaf->insert(cur->keySet[i])] = cur->linkSet[i]; @@ -307,13 +309,13 @@ void BTree::split(const KT &key, int address, in rLeaf->right = cur->right; if(cur->left) { - auto curLeft = BTreeNode::getNode(cur->left); + auto curLeft = BTreeNode::getNode(cur->left); curLeft->right = lLeaf->address; curLeft->save(); } if(cur->right) { - auto curRight = BTreeNode::getNode(cur->right); + auto curRight = BTreeNode::getNode(cur->right); curRight->left = rLeaf->address; curRight->save(); } @@ -321,7 +323,7 @@ void BTree::split(const KT &key, int address, in cur->release(); if(cur->address == root) { - auto newRoot = BTreeNode::getNode(PageManager::Instance().allocate()); + auto newRoot = BTreeNode::getNode(PageManager::Instance().allocate()); newRoot->insert(rLeaf->keySet[0]); newRoot->linkSet[0] = lLeaf->address; newRoot->linkSet[1] = rLeaf->address; @@ -340,11 +342,11 @@ void BTree::split(const KT &key, int address, in } } -template -void BTree::insertInternal(const KT &key, int curAdd, int lLeafAdd, int rLeafAdd) { - BTreeNode *cur = BTreeNode::getNode(curAdd); - BTreeNode *lLeaf = BTreeNode::getNode(lLeafAdd); - BTreeNode *rLeaf = BTreeNode::getNode(rLeafAdd); +template +void BTree::insertInternal(const KT &key, int curAdd, int lLeafAdd, int rLeafAdd) { + BTreeNode *cur = BTreeNode::getNode(curAdd); + BTreeNode *lLeaf = BTreeNode::getNode(lLeafAdd); + BTreeNode *rLeaf = BTreeNode::getNode(rLeafAdd); if(cur->size < cur->m - 1) { int pos = cur->insert(key); @@ -357,8 +359,8 @@ void BTree::insertInternal(const KT &key, int cu return; } - auto newLChild = BTreeNode::getNode(PageManager::Instance().allocate()); - auto newRChild = BTreeNode::getNode(PageManager::Instance().allocate()); + auto newLChild = BTreeNode::getNode(PageManager::Instance().allocate()); + auto newRChild = BTreeNode::getNode(PageManager::Instance().allocate()); newLChild->leaf = false; newRChild->leaf = false; newLChild->right = newRChild->address; @@ -367,13 +369,13 @@ void BTree::insertInternal(const KT &key, int cu newRChild->right = cur->right; if(cur->left) { - auto curLeft = BTreeNode::getNode(cur->left); + auto curLeft = BTreeNode::getNode(cur->left); curLeft->right = newLChild->address; curLeft->save(); } if(cur->right) { - auto curRight = BTreeNode::getNode(cur->right); + auto curRight = BTreeNode::getNode(cur->right); curRight->left = newRChild->address; curRight->save(); } @@ -391,12 +393,12 @@ void BTree::insertInternal(const KT &key, int cu for(int i=mid+1; i<=cur->m; i++) newRChild->linkSet[i-mid-1] = cur->linkSet[i]; for(int i=0; i<=newLChild->size; i++) { - auto child = BTreeNode::getNode(newLChild->linkSet[i]); + auto child = BTreeNode::getNode(newLChild->linkSet[i]); child->parent = newLChild->address; child->save(); } for(int i=0; i<=newRChild->size; i++) { - auto child = BTreeNode::getNode(newRChild->linkSet[i]); + auto child = BTreeNode::getNode(newRChild->linkSet[i]); child->parent = newRChild->address; child->save(); } @@ -404,7 +406,7 @@ void BTree::insertInternal(const KT &key, int cu cur->release(); if(cur->address == root) { - auto newRoot = BTreeNode::getNode(PageManager::Instance().allocate()); + auto newRoot = BTreeNode::getNode(PageManager::Instance().allocate()); newRoot->insert(cur->keySet[mid]); newRoot->linkSet[0] = newLChild->address; newRoot->linkSet[1] = newRChild->address; @@ -423,12 +425,20 @@ void BTree::insertInternal(const KT &key, int cu } } -template -int BTree::getNodeSize() { - auto p = BTreeNode::getNode(root); +template +int BTree::getNodeSize() { + auto p = BTreeNode::getNode(root); return p->save(); } -// BTree BTreeNode +template +bool BTree::exists(const KT &key) { + auto cur = BTreeNode::getNode(findNode(key)); + for(int i=0; isize; i++) { + if(key == cur->keySet[i]) return true; + } + return false; +} + #endif //INVODB_BTREE_H diff --git a/invodb/btree/node.h b/invodb/btree/node.h index 6a3c63b..7431150 100644 --- a/invodb/btree/node.h +++ b/invodb/btree/node.h @@ -12,11 +12,11 @@ #include #include "file/page_manager.h" -template +template class BTreeNode { public: - static BTreeNode* getNode(const int &address); - static BTreeNode* release(const int &address); + static BTreeNode* getNode(const int &address); + static BTreeNode* release(const int &address); int insert(KT const &key); int findPos(KT const &key); void release(); @@ -34,7 +34,7 @@ public: return size == maxCount; } KT keySet[m + 1]; - VT linkSet[m + 1]; + int linkSet[m + 1]; int parent; int left; int right; @@ -45,8 +45,8 @@ private: BTreeNode(const int& address); }; -template -BTreeNode::BTreeNode(const int& address): address(address) { +template +BTreeNode::BTreeNode(const int& address): address(address) { clear(); StoragePage page = PageManager::Instance().getPage(address); int p = 0; @@ -74,46 +74,33 @@ BTreeNode::BTreeNode(const int& address): addres } } - if(std::is_same::value) { - for(int i=0; ipush_back(c); - } - } - } else { - for (int i = 0; i <= m; i++) { - linkSet[i] = *(VT*)(&page[p]); - p += V_SIZE; - } + for (int i = 0; i <= m; i++) { + linkSet[i] = *(int*)(&page[p]); + p += 4; } } -template -BTreeNode *BTreeNode::getNode(const int &address) { +template +BTreeNode *BTreeNode::getNode(const int &address) { if(address < 4) { throw "invalid address!"; } - static std::map*> map; + static std::map*> map; if(map.count(address) == 0) { delete map[address]; - map[address] = new BTreeNode(address); + map[address] = new BTreeNode(address); } return map[address]; } -template -BTreeNode *BTreeNode::release(const int &address) { +template +BTreeNode *BTreeNode::release(const int &address) { return nullptr; } -template -int BTreeNode::insert(const KT &key) { +template +int BTreeNode::insert(const KT &key) { int pos = 0; while(pos < size && key > keySet[pos]) pos++; linkSet[size + 1] = linkSet[size]; @@ -126,28 +113,28 @@ int BTreeNode::insert(const KT &key) { return pos; } -template -int BTreeNode::findPos(const KT &key) { +template +int BTreeNode::findPos(const KT &key) { int pos = std::lower_bound(keySet, keySet+size, key) - keySet; if(pos == size || keySet[pos] != key) return -1; return pos; } -template -void BTreeNode::release() { - BTreeNode::release(this->address); +template +void BTreeNode::release() { + BTreeNode::release(this->address); } -template -void BTreeNode::clear() { +template +void BTreeNode::clear() { for(int i=0; i -int BTreeNode::save() { +template +int BTreeNode::save() { StoragePage page(address); int p = 0; page.setIntStartFrom(p, size); p += 4; @@ -169,17 +156,9 @@ int BTreeNode::save() { } } - if(std::is_same::value) { - for(int i=0; ic_str(), str->size()); - p += V_SIZE; - } - } else { - for (int i = 0; i <= m; i++) { - page.setStartFrom(p, &linkSet[i], V_SIZE); - p += V_SIZE; - } + for (int i = 0; i <= m; i++) { + page.setStartFrom(p, &linkSet[i], 4); + p += 4; } if(p >= 1024) { diff --git a/invodb/main.cpp b/invodb/main.cpp index 416300d..246324f 100644 --- a/invodb/main.cpp +++ b/invodb/main.cpp @@ -13,7 +13,7 @@ int main() { srand(t); printf("seed: %d\n", t); - system("rm -rf test.invodb && touch test.invodb"); + //system("rm -rf test.invodb && touch test.invodb"); PageManager::loadDatabase("test.invodb"); Collection::loadCollections(); @@ -40,21 +40,20 @@ int main() { void testAndBenchmark(int n) { + auto btree = new BTree<27, std::string, 32>(PageManager::Instance().allocate()); - auto btree = new BTree<15, std::string, 32, double, 8>(PageManager::Instance().allocate()); printf("nodeSize: %d\n", btree->getNodeSize()); - clock_t start = clock(); - std::map map; + std::map map; for(int i=0; iinsert(uuid, addr); map[uuid] = addr; } @@ -64,7 +63,7 @@ void testAndBenchmark(int n) { auto it = map.begin(); std::advance(it, rand() % map.size()); std::string uuid = it->first; - double addr = (double)rand() / 100; + double addr = rand(); map[uuid] = addr; btree->update(uuid, addr); } @@ -88,10 +87,9 @@ void testAndBenchmark(int n) { printf("test res k-v: %d\n", map.size()); for(auto it=map.begin(); it != map.end(); it++) { - printf("%llf %llf\n", btree->find(it->first), it->second); if(btree->find(it->first) != it->second) { printf("BTree has BUG!\n"); - //exit(0); + exit(0); } }