btree finished!

This commit is contained in:
YuhangQ 2021-10-30 20:52:06 +08:00
parent ef021d48a6
commit ba0180e057
3 changed files with 131 additions and 144 deletions

View File

@ -8,18 +8,19 @@
#include "btree/node.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 {
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<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;
n_size = 0;
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insert(const KT &key, const VT &value) {
if(find(key) != -1) {
template<int M_SIZE, typename KT, int K_SIZE>
void BTree<M_SIZE, KT, K_SIZE>::insert(const KT &key, const int &value) {
if(exists(key)) {
throw "keySet already exists.";
}
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
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);
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::update(const KT &key, const VT &value) {
if(find(key) == -1) {
template<int M_SIZE, typename KT, int K_SIZE>
void BTree<M_SIZE, KT, K_SIZE>::update(const KT &key, const int &value) {
if(!exists(key)) {
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->save();
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::remove(const KT &key) {
if(find(key) == -1) {
throw "keySet doesn't exists.";
template<int M_SIZE, typename KT, int K_SIZE>
void BTree<M_SIZE, KT, K_SIZE>::remove(const KT &key) {
if(!exists(key)) {
throw "keySet already exists.";
}
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));
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
VT BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::find(const KT &key) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(findNode(key));
template<int M_SIZE, typename KT, int K_SIZE>
int BTree<M_SIZE, KT, K_SIZE>::find(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 cur->linkSet[i];
}
return -1;
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
int BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::size() {
template<int M_SIZE, typename KT, int K_SIZE>
int BTree<M_SIZE, KT, K_SIZE>::size() {
return n_size;
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::removeEntry(int curAdd, const std::string &key, const int &pointer) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
template<int M_SIZE, typename KT, int K_SIZE>
void BTree<M_SIZE, KT, K_SIZE>::removeEntry(int curAdd, const KT &key, const int &pointer) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
int pos = cur->findPos(key);
if(pos == -1) return;
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) {
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->save();
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>
bool BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::canCoalesce(int curAdd, int sibAdd) {
template<int M_SIZE, typename KT, int K_SIZE>
bool BTree<M_SIZE, KT, K_SIZE>::canCoalesce(int curAdd, int sibAdd) {
if(sibAdd == 0) return false;
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
auto sib = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sibAdd);
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
auto sib = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sibAdd);
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>
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
auto sib = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sibAdd);
auto parent = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->parent);
std::string *k;
template<int M_SIZE, typename KT, int K_SIZE>
void BTree<M_SIZE, KT, K_SIZE>::coalesce(int curAdd, int sibAdd) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
auto sib = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sibAdd);
auto parent = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->parent);
KT *k;
for(int i=0; i<parent->size; 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<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
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->leaf) sib->insert(*k);
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->right = 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->save();
}
@ -181,7 +183,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
cur->right = 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->save();
}
@ -192,27 +194,27 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::coalesce(int curAdd, int sibAdd) {
}
if(newNode->leaf) return;
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->save();
}
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
bool BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::canRedistribute(int curAdd, int sibAdd) {
template<int M_SIZE, typename KT, int K_SIZE>
bool BTree<M_SIZE, KT, K_SIZE>::canRedistribute(int curAdd, int sibAdd) {
if(sibAdd == 0) return false;
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
auto sib = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sibAdd);
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
auto sib = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sibAdd);
if(cur->parent != sib->parent) return false;
return sib->size > ((sib->m - !sib->leaf) / 2);
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::redistribute(int curAdd, int sibAdd) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
auto sib = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(sibAdd);
auto parent = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(cur->parent);
std::string k;
template<int M_SIZE, typename KT, int K_SIZE>
void BTree<M_SIZE, KT, K_SIZE>::redistribute(int curAdd, int sibAdd) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
auto sib = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(sibAdd);
auto parent = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(cur->parent);
KT k;
int pos;
for(pos=0; pos<parent->size; pos++) {
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];
}
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->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];
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->save();
}
@ -271,17 +273,17 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::redistribute(int curAdd, int sibAdd)
parent->save();
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
int BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::findNode(const KT &key) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(root);
template<int M_SIZE, typename KT, int K_SIZE>
int BTree<M_SIZE, KT, K_SIZE>::findNode(const KT &key) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(root);
while(!cur->leaf) {
for(int i=0; i<cur->size; 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;
}
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;
}
}
@ -289,14 +291,14 @@ int BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::findNode(const KT &key) {
return cur->address;
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::split(const KT &key, int address, int parentAdd, int curAdd) {
auto cur = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(curAdd);
template<int M_SIZE, typename KT, int K_SIZE>
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>::getNode(curAdd);
cur->linkSet[cur->insert(key)] = address;
auto lLeaf = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(PageManager::Instance().allocate());
auto rLeaf = 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>::getNode(PageManager::Instance().allocate());
int mid = (cur->m / 2);
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;
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->save();
}
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->save();
}
@ -321,7 +323,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::split(const KT &key, int address, in
cur->release();
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->linkSet[0] = lLeaf->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>
void BTree<M_SIZE, KT, K_SIZE, VT, V_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, VT, V_SIZE> *lLeaf = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(lLeafAdd);
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *rLeaf = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(rLeafAdd);
template<int M_SIZE, typename KT, int K_SIZE>
void BTree<M_SIZE, KT, K_SIZE>::insertInternal(const KT &key, int curAdd, int lLeafAdd, int rLeafAdd) {
BTreeNode<M_SIZE, KT, K_SIZE> *cur = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(curAdd);
BTreeNode<M_SIZE, KT, K_SIZE> *lLeaf = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(lLeafAdd);
BTreeNode<M_SIZE, KT, K_SIZE> *rLeaf = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(rLeafAdd);
if(cur->size < cur->m - 1) {
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;
}
auto newLChild = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(PageManager::Instance().allocate());
auto newRChild = 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>::getNode(PageManager::Instance().allocate());
newLChild->leaf = false;
newRChild->leaf = false;
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;
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->save();
}
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->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=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->save();
}
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->save();
}
@ -404,7 +406,7 @@ void BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insertInternal(const KT &key, int cu
cur->release();
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->linkSet[0] = newLChild->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>
int BTree<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNodeSize() {
auto p = BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(root);
template<int M_SIZE, typename KT, int K_SIZE>
int BTree<M_SIZE, KT, K_SIZE>::getNodeSize() {
auto p = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(root);
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

View File

@ -12,11 +12,11 @@
#include <type_traits>
#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 {
public:
static BTreeNode<M_SIZE, KT, K_SIZE, VT, V_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>* getNode(const int &address);
static BTreeNode<M_SIZE, KT, K_SIZE>* 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<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::BTreeNode(const int& address): address(address) {
template<int M_SIZE, typename KT, int K_SIZE>
BTreeNode<M_SIZE, KT, K_SIZE>::BTreeNode(const int& address): address(address) {
clear();
StoragePage page = PageManager::Instance().getPage(address);
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++) {
std::string *str = (std::string*)&linkSet[i];
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;
}
for (int i = 0; i <= m; i++) {
linkSet[i] = *(int*)(&page[p]);
p += 4;
}
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::getNode(const int &address) {
template<int M_SIZE, typename KT, int K_SIZE>
BTreeNode<M_SIZE, KT, K_SIZE> *BTreeNode<M_SIZE, KT, K_SIZE>::getNode(const int &address) {
if(address < 4) {
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) {
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];
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE> *BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::release(const int &address) {
template<int M_SIZE, typename KT, int K_SIZE>
BTreeNode<M_SIZE, KT, K_SIZE> *BTreeNode<M_SIZE, KT, K_SIZE>::release(const int &address) {
return nullptr;
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
int BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insert(const KT &key) {
template<int M_SIZE, typename KT, int K_SIZE>
int BTreeNode<M_SIZE, KT, K_SIZE>::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<M_SIZE, KT, K_SIZE, VT, V_SIZE>::insert(const KT &key) {
return pos;
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
int BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::findPos(const KT &key) {
template<int M_SIZE, typename KT, int K_SIZE>
int BTreeNode<M_SIZE, KT, K_SIZE>::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<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
void BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::release() {
BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::release(this->address);
template<int M_SIZE, typename KT, int K_SIZE>
void BTreeNode<M_SIZE, KT, K_SIZE>::release() {
BTreeNode<M_SIZE, KT, K_SIZE>::release(this->address);
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
void BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::clear() {
template<int M_SIZE, typename KT, int K_SIZE>
void BTreeNode<M_SIZE, KT, K_SIZE>::clear() {
for(int i=0; i<m+1; i++) keySet[i].clear(), linkSet[i] = 0;
size = 0;
leaf = false;
parent = 0;
}
template<int M_SIZE, typename KT, int K_SIZE, typename VT, int V_SIZE>
int BTreeNode<M_SIZE, KT, K_SIZE, VT, V_SIZE>::save() {
template<int M_SIZE, typename KT, int K_SIZE>
int BTreeNode<M_SIZE, KT, K_SIZE>::save() {
StoragePage page(address);
int p = 0;
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++) {
std::string *str = (std::string*)&linkSet[i];
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;
}
for (int i = 0; i <= m; i++) {
page.setStartFrom(p, &linkSet[i], 4);
p += 4;
}
if(p >= 1024) {

View File

@ -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<std::string, double> map;
std::map<std::string, int> map;
for(int i=0; i<n; i++) {
int opt = rand() % 4;
// insert
if(opt <= 1) {
std::string uuid = generateUUID();
double addr = (double)rand() / 100;
int addr = rand();
btree->insert(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);
}
}