mirror of
https://github.com/YuhangQ/InvoDB.git
synced 2025-01-27 15:10:57 +00:00
btree finished!
This commit is contained in:
parent
ef021d48a6
commit
ba0180e057
@ -8,18 +8,19 @@
|
|||||||
#include "btree/node.h"
|
#include "btree/node.h"
|
||||||
#include "utils/uuid.h"
|
#include "utils/uuid.h"
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
class BTree {
|
class BTree {
|
||||||
public:
|
public:
|
||||||
BTree(const int& address);
|
BTree(const int& address);
|
||||||
void insert(const KT &key, const VT &value);
|
void insert(const KT &key, const int &value);
|
||||||
void update(const KT &key, const VT &value);
|
void update(const KT &key, const int &value);
|
||||||
void remove(const KT &key);
|
void remove(const KT &key);
|
||||||
|
bool exists(const KT &key);
|
||||||
int getNodeSize();
|
int getNodeSize();
|
||||||
VT find(const KT &key);
|
int find(const KT &key);
|
||||||
int size();
|
int size();
|
||||||
private:
|
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);
|
bool canCoalesce(int curAdd, int sibAdd);
|
||||||
void coalesce(int curAdd, int sibAdd);
|
void coalesce(int curAdd, int sibAdd);
|
||||||
bool canRedistribute(int curAdd, int sibAdd);
|
bool canRedistribute(int curAdd, int sibAdd);
|
||||||
@ -31,23 +32,24 @@ private:
|
|||||||
int n_size;
|
int n_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE> BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>
|
// BTree<M_SIZE, KT, K_SIZE> BTreeNode<M_SIZE, KT, K_SIZE>
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
|
||||||
BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::BTree(const int& address) {
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
|
BTree<M_SIZE, KT, K_SIZE>::BTree(const int& address) {
|
||||||
root = address;
|
root = address;
|
||||||
n_size = 0;
|
n_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insert(const KT &key, const VT &value) {
|
void BTree<M_SIZE, KT, K_SIZE>::insert(const KT &key, const int &value) {
|
||||||
if(find(key) != -1) {
|
if(exists(key)) {
|
||||||
throw "keySet already exists.";
|
throw "keySet already exists.";
|
||||||
}
|
}
|
||||||
|
|
||||||
n_size++;
|
n_size++;
|
||||||
|
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(findNode(key));
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(findNode(key));
|
||||||
|
|
||||||
// insert directly
|
// insert directly
|
||||||
if(cur->size < cur->m - 1) {
|
if(cur->size < cur->m - 1) {
|
||||||
@ -60,43 +62,43 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insert(const KT &key, const VT &valu
|
|||||||
split(key, value, cur->parent, cur->address);
|
split(key, value, cur->parent, cur->address);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::update(const KT &key, const VT &value) {
|
void BTree<M_SIZE, KT, K_SIZE>::update(const KT &key, const int &value) {
|
||||||
if(find(key) == -1) {
|
if(!exists(key)) {
|
||||||
throw "keySet doesn't exists.";
|
throw "keySet doesn't exists.";
|
||||||
}
|
}
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(findNode(key));
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(findNode(key));
|
||||||
cur->linkSet[cur->findPos(key)] = value;
|
cur->linkSet[cur->findPos(key)] = value;
|
||||||
cur->save();
|
cur->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::remove(const KT &key) {
|
void BTree<M_SIZE, KT, K_SIZE>::remove(const KT &key) {
|
||||||
if(find(key) == -1) {
|
if(!exists(key)) {
|
||||||
throw "keySet doesn't exists.";
|
throw "keySet already exists.";
|
||||||
}
|
}
|
||||||
n_size--;
|
n_size--;
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(findNode(key));
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(findNode(key));
|
||||||
removeEntry(cur->address, key, find(key));
|
removeEntry(cur->address, key, find(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
VT BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::find(const KT &key) {
|
int BTree<M_SIZE, KT, K_SIZE>::find(const KT &key) {
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(findNode(key));
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(findNode(key));
|
||||||
for(int i=0; i<cur->size; i++) {
|
for(int i=0; i<cur->size; i++) {
|
||||||
if(key == cur->keySet[i]) return cur->linkSet[i];
|
if(key == cur->keySet[i]) return cur->linkSet[i];
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
int BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::size() {
|
int BTree<M_SIZE, KT, K_SIZE>::size() {
|
||||||
return n_size;
|
return n_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::removeEntry(int curAdd, const std::string &key, const int &pointer) {
|
void BTree<M_SIZE, KT, K_SIZE>::removeEntry(int curAdd, const KT &key, const int &pointer) {
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
|
||||||
int pos = cur->findPos(key);
|
int pos = cur->findPos(key);
|
||||||
if(pos == -1) return;
|
if(pos == -1) return;
|
||||||
for(int i=pos; i<cur->size-1; i++) {
|
for(int i=pos; i<cur->size-1; i++) {
|
||||||
@ -110,7 +112,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::removeEntry(int curAdd, const std::s
|
|||||||
|
|
||||||
if(curAdd == root && !cur->leaf && cur->size == 0) {
|
if(curAdd == root && !cur->leaf && cur->size == 0) {
|
||||||
root = cur->linkSet[0];
|
root = cur->linkSet[0];
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>* root = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->linkSet[0]);
|
auto root = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->linkSet[0]);
|
||||||
root->parent = 0;
|
root->parent = 0;
|
||||||
root->save();
|
root->save();
|
||||||
cur->release();
|
cur->release();
|
||||||
@ -132,21 +134,21 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::removeEntry(int curAdd, const std::s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
bool BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::canCoalesce(int curAdd, int sibAdd) {
|
bool BTree<M_SIZE, KT, K_SIZE>::canCoalesce(int curAdd, int sibAdd) {
|
||||||
if(sibAdd == 0) return false;
|
if(sibAdd == 0) return false;
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
|
||||||
auto sib = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sibAdd);
|
auto sib = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sibAdd);
|
||||||
if(cur->parent != sib->parent) return false;
|
if(cur->parent != sib->parent) return false;
|
||||||
return (cur->size + sib->size <= BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::m - 1 - !cur->leaf);
|
return (cur->size + sib->size <= BTreeNode<M_SIZE, KT, K_SIZE>::m - 1 - !cur->leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
|
void BTree<M_SIZE, KT, K_SIZE>::coalesce(int curAdd, int sibAdd) {
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
|
||||||
auto sib = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sibAdd);
|
auto sib = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sibAdd);
|
||||||
auto parent = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->parent);
|
auto parent = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->parent);
|
||||||
std::string *k;
|
KT *k;
|
||||||
for(int i=0; i<parent->size; i++) {
|
for(int i=0; i<parent->size; i++) {
|
||||||
if((parent->linkSet[i] == curAdd && parent->linkSet[i+1] == sibAdd)
|
if((parent->linkSet[i] == curAdd && parent->linkSet[i+1] == sibAdd)
|
||||||
|| (parent->linkSet[i] == sibAdd && parent->linkSet[i+1] == curAdd)) {
|
|| (parent->linkSet[i] == sibAdd && parent->linkSet[i+1] == curAdd)) {
|
||||||
@ -154,7 +156,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>* newNode = nullptr;
|
BTreeNode<M_SIZE, KT, K_SIZE>* newNode = nullptr;
|
||||||
if(cur->left == sibAdd) {
|
if(cur->left == sibAdd) {
|
||||||
if(!cur->leaf) sib->insert(*k);
|
if(!cur->leaf) sib->insert(*k);
|
||||||
for(int i=0; i<cur->size; i++) {
|
for(int i=0; i<cur->size; i++) {
|
||||||
@ -163,7 +165,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
|
|||||||
sib->linkSet[sib->size] = cur->linkSet[cur->size];
|
sib->linkSet[sib->size] = cur->linkSet[cur->size];
|
||||||
sib->right = cur->right;
|
sib->right = cur->right;
|
||||||
if(cur->right) {
|
if(cur->right) {
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *right = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->right);
|
BTreeNode<M_SIZE, KT, K_SIZE> *right = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->right);
|
||||||
right->left = sib->address;
|
right->left = sib->address;
|
||||||
right->save();
|
right->save();
|
||||||
}
|
}
|
||||||
@ -181,7 +183,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
|
|||||||
cur->right = sib->right;
|
cur->right = sib->right;
|
||||||
|
|
||||||
if(sib->right) {
|
if(sib->right) {
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *right = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sib->right);
|
BTreeNode<M_SIZE, KT, K_SIZE> *right = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sib->right);
|
||||||
right->left = cur->address;
|
right->left = cur->address;
|
||||||
right->save();
|
right->save();
|
||||||
}
|
}
|
||||||
@ -192,27 +194,27 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
|
|||||||
}
|
}
|
||||||
if(newNode->leaf) return;
|
if(newNode->leaf) return;
|
||||||
for(int i=0; i<=newNode->size; i++) {
|
for(int i=0; i<=newNode->size; i++) {
|
||||||
auto child = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(newNode->linkSet[i]);
|
auto child = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(newNode->linkSet[i]);
|
||||||
child->parent = newNode->address;
|
child->parent = newNode->address;
|
||||||
child->save();
|
child->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
bool BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::canRedistribute(int curAdd, int sibAdd) {
|
bool BTree<M_SIZE, KT, K_SIZE>::canRedistribute(int curAdd, int sibAdd) {
|
||||||
if(sibAdd == 0) return false;
|
if(sibAdd == 0) return false;
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
|
||||||
auto sib = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sibAdd);
|
auto sib = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sibAdd);
|
||||||
if(cur->parent != sib->parent) return false;
|
if(cur->parent != sib->parent) return false;
|
||||||
return sib->size > ((sib->m - !sib->leaf) / 2);
|
return sib->size > ((sib->m - !sib->leaf) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::redistribute(int curAdd, int sibAdd) {
|
void BTree<M_SIZE, KT, K_SIZE>::redistribute(int curAdd, int sibAdd) {
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
|
||||||
auto sib = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sibAdd);
|
auto sib = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sibAdd);
|
||||||
auto parent = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->parent);
|
auto parent = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->parent);
|
||||||
std::string k;
|
KT k;
|
||||||
int pos;
|
int pos;
|
||||||
for(pos=0; pos<parent->size; pos++) {
|
for(pos=0; pos<parent->size; pos++) {
|
||||||
if((parent->linkSet[pos] == curAdd && parent->linkSet[pos+1] == sibAdd)
|
if((parent->linkSet[pos] == curAdd && parent->linkSet[pos+1] == sibAdd)
|
||||||
@ -231,7 +233,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::redistribute(int curAdd, int sibAdd)
|
|||||||
parent->keySet[pos] = sib->keySet[sib->size-1];
|
parent->keySet[pos] = sib->keySet[sib->size-1];
|
||||||
}
|
}
|
||||||
if(!cur->leaf) {
|
if(!cur->leaf) {
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *child = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sib->linkSet[sib->size - cur->leaf]);
|
BTreeNode<M_SIZE, KT, K_SIZE> *child = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sib->linkSet[sib->size - cur->leaf]);
|
||||||
child->parent = cur->address;
|
child->parent = cur->address;
|
||||||
child->save();
|
child->save();
|
||||||
}
|
}
|
||||||
@ -254,7 +256,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::redistribute(int curAdd, int sibAdd)
|
|||||||
}
|
}
|
||||||
parent->keySet[pos] = sib->keySet[0];
|
parent->keySet[pos] = sib->keySet[0];
|
||||||
if(!cur->leaf) {
|
if(!cur->leaf) {
|
||||||
auto child = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sib->linkSet[0]);
|
auto child = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sib->linkSet[0]);
|
||||||
child->parent = cur->address;
|
child->parent = cur->address;
|
||||||
child->save();
|
child->save();
|
||||||
}
|
}
|
||||||
@ -271,17 +273,17 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::redistribute(int curAdd, int sibAdd)
|
|||||||
parent->save();
|
parent->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
int BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::findNode(const KT &key) {
|
int BTree<M_SIZE, KT, K_SIZE>::findNode(const KT &key) {
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(root);
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(root);
|
||||||
while(!cur->leaf) {
|
while(!cur->leaf) {
|
||||||
for(int i=0; i<cur->size; i++) {
|
for(int i=0; i<cur->size; i++) {
|
||||||
if(key < cur->keySet[i]) {
|
if(key < cur->keySet[i]) {
|
||||||
cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->linkSet[i]);
|
cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->linkSet[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(i == cur->size - 1) {
|
if(i == cur->size - 1) {
|
||||||
cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->linkSet[i + 1]);
|
cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->linkSet[i + 1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,14 +291,14 @@ int BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::findNode(const KT &key) {
|
|||||||
return cur->address;
|
return cur->address;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::split(const KT &key, int address, int parentAdd, int curAdd) {
|
void BTree<M_SIZE, KT, K_SIZE>::split(const KT &key, int address, int parentAdd, int curAdd) {
|
||||||
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
|
||||||
|
|
||||||
cur->linkSet[cur->insert(key)] = address;
|
cur->linkSet[cur->insert(key)] = address;
|
||||||
|
|
||||||
auto lLeaf = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(PageManager::Instance().allocate());
|
auto lLeaf = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
||||||
auto rLeaf = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(PageManager::Instance().allocate());
|
auto rLeaf = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
||||||
|
|
||||||
int mid = (cur->m / 2);
|
int mid = (cur->m / 2);
|
||||||
for(int i=0; i<mid; i++) lLeaf->linkSet[lLeaf->insert(cur->keySet[i])] = cur->linkSet[i];
|
for(int i=0; i<mid; i++) lLeaf->linkSet[lLeaf->insert(cur->keySet[i])] = cur->linkSet[i];
|
||||||
@ -307,13 +309,13 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::split(const KT &key, int address, in
|
|||||||
rLeaf->right = cur->right;
|
rLeaf->right = cur->right;
|
||||||
|
|
||||||
if(cur->left) {
|
if(cur->left) {
|
||||||
auto curLeft = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->left);
|
auto curLeft = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->left);
|
||||||
curLeft->right = lLeaf->address;
|
curLeft->right = lLeaf->address;
|
||||||
curLeft->save();
|
curLeft->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cur->right) {
|
if(cur->right) {
|
||||||
auto curRight = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->right);
|
auto curRight = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->right);
|
||||||
curRight->left = rLeaf->address;
|
curRight->left = rLeaf->address;
|
||||||
curRight->save();
|
curRight->save();
|
||||||
}
|
}
|
||||||
@ -321,7 +323,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::split(const KT &key, int address, in
|
|||||||
cur->release();
|
cur->release();
|
||||||
|
|
||||||
if(cur->address == root) {
|
if(cur->address == root) {
|
||||||
auto newRoot = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(PageManager::Instance().allocate());
|
auto newRoot = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
||||||
newRoot->insert(rLeaf->keySet[0]);
|
newRoot->insert(rLeaf->keySet[0]);
|
||||||
newRoot->linkSet[0] = lLeaf->address;
|
newRoot->linkSet[0] = lLeaf->address;
|
||||||
newRoot->linkSet[1] = rLeaf->address;
|
newRoot->linkSet[1] = rLeaf->address;
|
||||||
@ -340,11 +342,11 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::split(const KT &key, int address, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insertInternal(const KT &key, int curAdd, int lLeafAdd, int rLeafAdd) {
|
void BTree<M_SIZE, KT, K_SIZE>::insertInternal(const KT &key, int curAdd, int lLeafAdd, int rLeafAdd) {
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
|
BTreeNode<M_SIZE, KT, K_SIZE> *cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *lLeaf = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(lLeafAdd);
|
BTreeNode<M_SIZE, KT, K_SIZE> *lLeaf = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(lLeafAdd);
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *rLeaf = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(rLeafAdd);
|
BTreeNode<M_SIZE, KT, K_SIZE> *rLeaf = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(rLeafAdd);
|
||||||
|
|
||||||
if(cur->size < cur->m - 1) {
|
if(cur->size < cur->m - 1) {
|
||||||
int pos = cur->insert(key);
|
int pos = cur->insert(key);
|
||||||
@ -357,8 +359,8 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insertInternal(const KT &key, int cu
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto newLChild = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(PageManager::Instance().allocate());
|
auto newLChild = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
||||||
auto newRChild = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(PageManager::Instance().allocate());
|
auto newRChild = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
||||||
newLChild->leaf = false;
|
newLChild->leaf = false;
|
||||||
newRChild->leaf = false;
|
newRChild->leaf = false;
|
||||||
newLChild->right = newRChild->address;
|
newLChild->right = newRChild->address;
|
||||||
@ -367,13 +369,13 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insertInternal(const KT &key, int cu
|
|||||||
newRChild->right = cur->right;
|
newRChild->right = cur->right;
|
||||||
|
|
||||||
if(cur->left) {
|
if(cur->left) {
|
||||||
auto curLeft = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->left);
|
auto curLeft = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->left);
|
||||||
curLeft->right = newLChild->address;
|
curLeft->right = newLChild->address;
|
||||||
curLeft->save();
|
curLeft->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cur->right) {
|
if(cur->right) {
|
||||||
auto curRight = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->right);
|
auto curRight = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->right);
|
||||||
curRight->left = newRChild->address;
|
curRight->left = newRChild->address;
|
||||||
curRight->save();
|
curRight->save();
|
||||||
}
|
}
|
||||||
@ -391,12 +393,12 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::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=mid+1; i<=cur->m; i++) newRChild->linkSet[i-mid-1] = cur->linkSet[i];
|
||||||
|
|
||||||
for(int i=0; i<=newLChild->size; i++) {
|
for(int i=0; i<=newLChild->size; i++) {
|
||||||
auto child = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(newLChild->linkSet[i]);
|
auto child = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(newLChild->linkSet[i]);
|
||||||
child->parent = newLChild->address;
|
child->parent = newLChild->address;
|
||||||
child->save();
|
child->save();
|
||||||
}
|
}
|
||||||
for(int i=0; i<=newRChild->size; i++) {
|
for(int i=0; i<=newRChild->size; i++) {
|
||||||
auto child = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(newRChild->linkSet[i]);
|
auto child = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(newRChild->linkSet[i]);
|
||||||
child->parent = newRChild->address;
|
child->parent = newRChild->address;
|
||||||
child->save();
|
child->save();
|
||||||
}
|
}
|
||||||
@ -404,7 +406,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insertInternal(const KT &key, int cu
|
|||||||
cur->release();
|
cur->release();
|
||||||
|
|
||||||
if(cur->address == root) {
|
if(cur->address == root) {
|
||||||
auto newRoot = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(PageManager::Instance().allocate());
|
auto newRoot = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
||||||
newRoot->insert(cur->keySet[mid]);
|
newRoot->insert(cur->keySet[mid]);
|
||||||
newRoot->linkSet[0] = newLChild->address;
|
newRoot->linkSet[0] = newLChild->address;
|
||||||
newRoot->linkSet[1] = newRChild->address;
|
newRoot->linkSet[1] = newRChild->address;
|
||||||
@ -423,12 +425,20 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insertInternal(const KT &key, int cu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
int BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNodeSize() {
|
int BTree<M_SIZE, KT, K_SIZE>::getNodeSize() {
|
||||||
auto p = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(root);
|
auto p = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(root);
|
||||||
return p->save();
|
return p->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE> BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
|
bool BTree<M_SIZE, KT, K_SIZE>::exists(const KT &key) {
|
||||||
|
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(findNode(key));
|
||||||
|
for(int i=0; i<cur->size; i++) {
|
||||||
|
if(key == cur->keySet[i]) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //INVODB_BTREE_H
|
#endif //INVODB_BTREE_H
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include "file/page_manager.h"
|
#include "file/page_manager.h"
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
class BTreeNode {
|
class BTreeNode {
|
||||||
public:
|
public:
|
||||||
static BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>* getNode(const int &address);
|
static BTreeNode<M_SIZE, KT, K_SIZE>* getNode(const int &address);
|
||||||
static BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>* release(const int &address);
|
static BTreeNode<M_SIZE, KT, K_SIZE>* release(const int &address);
|
||||||
int insert(KT const &key);
|
int insert(KT const &key);
|
||||||
int findPos(KT const &key);
|
int findPos(KT const &key);
|
||||||
void release();
|
void release();
|
||||||
@ -34,7 +34,7 @@ public:
|
|||||||
return size == maxCount;
|
return size == maxCount;
|
||||||
}
|
}
|
||||||
KT keySet[m + 1];
|
KT keySet[m + 1];
|
||||||
VT linkSet[m + 1];
|
int linkSet[m + 1];
|
||||||
int parent;
|
int parent;
|
||||||
int left;
|
int left;
|
||||||
int right;
|
int right;
|
||||||
@ -45,8 +45,8 @@ private:
|
|||||||
BTreeNode(const int& address);
|
BTreeNode(const int& address);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::BTreeNode(const int& address): address(address) {
|
BTreeNode<M_SIZE, KT, K_SIZE>::BTreeNode(const int& address): address(address) {
|
||||||
clear();
|
clear();
|
||||||
StoragePage page = PageManager::Instance().getPage(address);
|
StoragePage page = PageManager::Instance().getPage(address);
|
||||||
int p = 0;
|
int p = 0;
|
||||||
@ -74,46 +74,33 @@ BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::BTreeNode(const int& address): addres
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(std::is_same<VT, std::string>::value) {
|
for (int i = 0; i <= m; i++) {
|
||||||
for(int i=0; i<m; i++) {
|
linkSet[i] = *(int*)(&page[p]);
|
||||||
std::string *str = (std::string*)&linkSet[i];
|
p += 4;
|
||||||
bool flag = true;
|
|
||||||
for(int j=0; j<V_SIZE; j++) {
|
|
||||||
char c = page[p++];
|
|
||||||
if(c == '\0') flag = false;
|
|
||||||
if(!flag) continue;
|
|
||||||
str->push_back(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i <= m; i++) {
|
|
||||||
linkSet[i] = *(VT*)(&page[p]);
|
|
||||||
p += V_SIZE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(const int &address) {
|
BTreeNode<M_SIZE, KT, K_SIZE> *BTreeNode<M_SIZE, KT, K_SIZE>::getNode(const int &address) {
|
||||||
if(address < 4) {
|
if(address < 4) {
|
||||||
throw "invalid address!";
|
throw "invalid address!";
|
||||||
}
|
}
|
||||||
static std::map<int, BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>*> map;
|
static std::map<int, BTreeNode<M_SIZE, KT, K_SIZE>*> map;
|
||||||
if(map.count(address) == 0) {
|
if(map.count(address) == 0) {
|
||||||
delete map[address];
|
delete map[address];
|
||||||
map[address] = new BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>(address);
|
map[address] = new BTreeNode<M_SIZE, KT, K_SIZE>(address);
|
||||||
}
|
}
|
||||||
return map[address];
|
return map[address];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::release(const int &address) {
|
BTreeNode<M_SIZE, KT, K_SIZE> *BTreeNode<M_SIZE, KT, K_SIZE>::release(const int &address) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
int BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insert(const KT &key) {
|
int BTreeNode<M_SIZE, KT, K_SIZE>::insert(const KT &key) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
while(pos < size && key > keySet[pos]) pos++;
|
while(pos < size && key > keySet[pos]) pos++;
|
||||||
linkSet[size + 1] = linkSet[size];
|
linkSet[size + 1] = linkSet[size];
|
||||||
@ -126,28 +113,28 @@ int BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insert(const KT &key) {
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
int BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::findPos(const KT &key) {
|
int BTreeNode<M_SIZE, KT, K_SIZE>::findPos(const KT &key) {
|
||||||
int pos = std::lower_bound(keySet, keySet+size, key) - keySet;
|
int pos = std::lower_bound(keySet, keySet+size, key) - keySet;
|
||||||
if(pos == size || keySet[pos] != key) return -1;
|
if(pos == size || keySet[pos] != key) return -1;
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::release() {
|
void BTreeNode<M_SIZE, KT, K_SIZE>::release() {
|
||||||
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::release(this->address);
|
BTreeNode<M_SIZE, KT, K_SIZE>::release(this->address);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
void BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::clear() {
|
void BTreeNode<M_SIZE, KT, K_SIZE>::clear() {
|
||||||
for(int i=0; i<m+1; i++) keySet[i].clear(), linkSet[i] = 0;
|
for(int i=0; i<m+1; i++) keySet[i].clear(), linkSet[i] = 0;
|
||||||
size = 0;
|
size = 0;
|
||||||
leaf = false;
|
leaf = false;
|
||||||
parent = 0;
|
parent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
int BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::save() {
|
int BTreeNode<M_SIZE, KT, K_SIZE>::save() {
|
||||||
StoragePage page(address);
|
StoragePage page(address);
|
||||||
int p = 0;
|
int p = 0;
|
||||||
page.setIntStartFrom(p, size); p += 4;
|
page.setIntStartFrom(p, size); p += 4;
|
||||||
@ -169,17 +156,9 @@ int BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::save() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(std::is_same<VT, std::string>::value) {
|
for (int i = 0; i <= m; i++) {
|
||||||
for(int i=0; i<m; i++) {
|
page.setStartFrom(p, &linkSet[i], 4);
|
||||||
std::string *str = (std::string*)&linkSet[i];
|
p += 4;
|
||||||
page.setStartFrom(p, str->c_str(), str->size());
|
|
||||||
p += V_SIZE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i <= m; i++) {
|
|
||||||
page.setStartFrom(p, &linkSet[i], V_SIZE);
|
|
||||||
p += V_SIZE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p >= 1024) {
|
if(p >= 1024) {
|
||||||
|
@ -13,7 +13,7 @@ int main() {
|
|||||||
srand(t);
|
srand(t);
|
||||||
printf("seed: %d\n", 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");
|
PageManager::loadDatabase("test.invodb");
|
||||||
Collection::loadCollections();
|
Collection::loadCollections();
|
||||||
@ -40,21 +40,20 @@ int main() {
|
|||||||
|
|
||||||
void testAndBenchmark(int n) {
|
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());
|
printf("nodeSize: %d\n", btree->getNodeSize());
|
||||||
|
|
||||||
|
|
||||||
clock_t start = clock();
|
clock_t start = clock();
|
||||||
|
|
||||||
std::map<std::string, double> map;
|
std::map<std::string, int> map;
|
||||||
|
|
||||||
for(int i=0; i<n; i++) {
|
for(int i=0; i<n; i++) {
|
||||||
int opt = rand() % 4;
|
int opt = rand() % 4;
|
||||||
// insert
|
// insert
|
||||||
if(opt <= 1) {
|
if(opt <= 1) {
|
||||||
std::string uuid = generateUUID();
|
std::string uuid = generateUUID();
|
||||||
double addr = (double)rand() / 100;
|
int addr = rand();
|
||||||
btree->insert(uuid, addr);
|
btree->insert(uuid, addr);
|
||||||
map[uuid] = addr;
|
map[uuid] = addr;
|
||||||
}
|
}
|
||||||
@ -64,7 +63,7 @@ void testAndBenchmark(int n) {
|
|||||||
auto it = map.begin();
|
auto it = map.begin();
|
||||||
std::advance(it, rand() % map.size());
|
std::advance(it, rand() % map.size());
|
||||||
std::string uuid = it->first;
|
std::string uuid = it->first;
|
||||||
double addr = (double)rand() / 100;
|
double addr = rand();
|
||||||
map[uuid] = addr;
|
map[uuid] = addr;
|
||||||
btree->update(uuid, addr);
|
btree->update(uuid, addr);
|
||||||
}
|
}
|
||||||
@ -88,10 +87,9 @@ void testAndBenchmark(int n) {
|
|||||||
printf("test res k-v: %d\n", map.size());
|
printf("test res k-v: %d\n", map.size());
|
||||||
|
|
||||||
for(auto it=map.begin(); it != map.end(); it++) {
|
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) {
|
if(btree->find(it->first) != it->second) {
|
||||||
printf("BTree has BUG!\n");
|
printf("BTree has BUG!\n");
|
||||||
//exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user