btree benchmark

This commit is contained in:
YuhangQ 2021-10-29 09:55:24 +08:00
parent db7b2bf33e
commit fabb655eca
6 changed files with 94 additions and 81 deletions

View File

@ -7,6 +7,9 @@
std::map<int, NodeUUID*> NodeUUID::map; std::map<int, NodeUUID*> NodeUUID::map;
NodeUUID *NodeUUID::getNode(const int &address) { NodeUUID *NodeUUID::getNode(const int &address) {
if(address == 0) {
throw "fuck";
}
if(map.count(address) == 0) { if(map.count(address) == 0) {
delete map[address]; delete map[address];
map[address] = new NodeUUID(address); map[address] = new NodeUUID(address);
@ -98,3 +101,6 @@ void NodeUUID::release() {
NodeUUID *NodeUUID::release(const int &address) { NodeUUID *NodeUUID::release(const int &address) {
return nullptr; return nullptr;
} }

View File

@ -19,7 +19,6 @@ int BTreeUUID::find(const std::string& uuid) {
int BTreeUUID::findNode(const std::string& uuid) { int BTreeUUID::findNode(const std::string& uuid) {
NodeUUID* cur = NodeUUID::getNode(root); NodeUUID* cur = NodeUUID::getNode(root);
while(!cur->leaf) { while(!cur->leaf) {
int parent = cur->address;
for(int i=0; i<cur->size; i++) { for(int i=0; i<cur->size; i++) {
if(uuid < cur->key[i]) { if(uuid < cur->key[i]) {
cur = NodeUUID::getNode(cur->val[i]); cur = NodeUUID::getNode(cur->val[i]);
@ -30,31 +29,27 @@ int BTreeUUID::findNode(const std::string& uuid) {
break; break;
} }
} }
//if(cur->parent != parent) cur->parent = parent;
//cur->save();
} }
return cur->address; return cur->address;
} }
void BTreeUUID::update(const std::string &uuid, int address) {
if(find(uuid) == -1) {
throw "key doesn't exists.";
}
NodeUUID* cur = NodeUUID::getNode(findNode(uuid));
cur->val[cur->findPos(uuid)] = address;
cur->save();
}
void BTreeUUID::insert(const std::string& uuid, int address) { void BTreeUUID::insert(const std::string& uuid, int address) {
if(find(uuid) != -1) {
throw "key already exists.";
}
NodeUUID* cur = NodeUUID::getNode(root); n_size++;
NodeUUID* parent = nullptr;
while(!cur->leaf) { NodeUUID* cur = NodeUUID::getNode(findNode(uuid));
parent = cur;
for(int i=0; i<cur->size; i++) {
if(uuid < cur->key[i]) {
cur = NodeUUID::getNode(cur->val[i]);
break;
}
if(i == cur->size - 1) {
cur = NodeUUID::getNode(cur->val[i + 1]);
break;
}
}
}
// insert directly // insert directly
if(cur->size < cur->m - 1) { if(cur->size < cur->m - 1) {
@ -64,13 +59,11 @@ void BTreeUUID::insert(const std::string& uuid, int address) {
} }
// split // split
if(parent == nullptr) split(uuid, address, 0, cur->address); split(uuid, address, cur->parent, cur->address);
else split(uuid, address, parent->address, cur->address);
} }
void BTreeUUID::split(const std::string& uuid, int address, int parentAddr, int curAddr) { void BTreeUUID::split(const std::string& uuid, int address, int parentAddr, int curAddr) {
NodeUUID* parent = NodeUUID::getNode(parentAddr);
NodeUUID* cur = NodeUUID::getNode(curAddr); NodeUUID* cur = NodeUUID::getNode(curAddr);
cur->val[cur->insert(uuid)] = address; cur->val[cur->insert(uuid)] = address;
@ -116,7 +109,7 @@ void BTreeUUID::split(const std::string& uuid, int address, int parentAddr, int
} else { } else {
lLeaf->save(); lLeaf->save();
rLeaf->save(); rLeaf->save();
insertInternal(rLeaf->key[0], parent->address, lLeaf->address, rLeaf->address); insertInternal(rLeaf->key[0], cur->parent, lLeaf->address, rLeaf->address);
} }
} }
@ -203,7 +196,7 @@ void BTreeUUID::insertInternal(const std::string& uuid, int curAddr, int lLeafAd
} }
} }
/*
void BTreeUUID::print() { void BTreeUUID::print() {
innerPrint(NodeUUID::getNode(root)); innerPrint(NodeUUID::getNode(root));
} }
@ -235,10 +228,14 @@ void BTreeUUID::innerPrint(NodeUUID *cur) {
} }
} }
*/
void BTreeUUID::remove(const std::string &uuid) { void BTreeUUID::remove(const std::string &uuid) {
if(find(uuid) == -1) {
throw "key doesn't exists.";
}
n_size--;
NodeUUID* cur = NodeUUID::getNode(findNode(uuid)); NodeUUID* cur = NodeUUID::getNode(findNode(uuid));
if(find(uuid) == -1) printf("ohFUCK\n");
removeEntry(cur->address, uuid, find(uuid)); removeEntry(cur->address, uuid, find(uuid));
} }
@ -428,14 +425,62 @@ void BTreeUUID::redistribute(int curAddr, int sibAddr) {
parent->save(); parent->save();
} }
int BTreeUUID::test() { int BTreeUUID::size() {
NodeUUID* cur = NodeUUID::getNode(findNode("\0")); return n_size;
int sum = cur->size;
while(cur->right) {
cur = NodeUUID::getNode(cur->right);
sum += cur->size;
} }
return sum;
void BTreeUUID::testAndBenchmark(const int& n) {
clock_t start = clock();
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();
int addr = rand();
insert(uuid, addr);
map[uuid] = addr;
}
// update
else if(opt == 2) {
if(map.size() == 0) continue;
auto it = map.begin();
std::advance(it, rand() % map.size());
std::string uuid = it->first;
int addr = rand();
map[uuid] = addr;
update(uuid, addr);
}
// remove
else {
if(map.size() == 0) continue;
auto it = map.begin();
std::advance(it, rand() % map.size());
std::string uuid = it->first;
map.erase(uuid);
remove(uuid);
}
}
if(map.size() != size()) {
printf("%d %d\n", map.size(), size());
printf("BTree has BUG!\n");
exit(0);
}
for(auto it=map.begin(); it != map.end(); it++) {
if(find(it->first) != it->second) {
printf("BTree has BUG!\n");
exit(0);
}
}
clock_t end = clock();
printf("BTree pass the test with n=%d, time=%fs!\n", n, (double)(end - start) / CLOCKS_PER_SEC);
} }

View File

@ -12,10 +12,12 @@ class BTreeUUID {
public: public:
BTreeUUID(const int& address); BTreeUUID(const int& address);
void insert(const std::string& uuid, int address); void insert(const std::string& uuid, int address);
void update(const std::string& uuid, int address);
void remove(const std::string& uuid); void remove(const std::string& uuid);
int find(const std::string& uuid); int find(const std::string& uuid);
void print(); void print();
int test(); void testAndBenchmark(const int& n);
int size();
private: private:
void removeEntry(int curAddr, const std::string& uuid, const int& pointer); void removeEntry(int curAddr, const std::string& uuid, const int& pointer);
bool canCoalesce(int curAddr, int sibAddr); bool canCoalesce(int curAddr, int sibAddr);
@ -27,7 +29,7 @@ private:
void split(const std::string& uuid, int address, int parentAddr, int curAddr); void split(const std::string& uuid, int address, int parentAddr, int curAddr);
void insertInternal(const std::string& uuid, int curAddr, int lLeafAddr, int rLeafAddr); void insertInternal(const std::string& uuid, int curAddr, int lLeafAddr, int rLeafAddr);
int root; int root;
int cnt; int n_size;
}; };

View File

@ -4,51 +4,10 @@
#include "main.h" #include "main.h"
void benchmark() {
BTreeUUID *btree = new BTreeUUID(PageManager::Instance().allocate());
char uuid[33]; uuid[32] = '\0';
std::vector<std::pair<std::string, int>> v;
const int n = 100000;
for(int i=0; i<n; i++) {
generateUUID(uuid);
int addr = PageManager::Instance().allocate();
v.push_back(std::make_pair(uuid, addr));
btree->insert(uuid, addr);
}
for(int i=0; i<100000; i++) {
std::swap(v[rand()%v.size()], v[rand()%v.size()]);
}
for(int i=0; i<v.size(); i++) {
int addr = btree->find(v[i].first);
if(addr != v[i].second) {
printf("fuck\n");
exit(0);
}
}
for(int i=0; i<v.size(); i++) {
if(i < v.size() / 2) {
btree->remove(v[i].first);
} else {
int addr = btree->find(v[i].first);
if(addr != v[i].second) {
printf("fuck\n");
exit(0);
}
}
}
}
int main() { int main() {
int t = time(0); int t = time(0);
//srand(1635418590); //srand(1635418590);
srand(1635423140); 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");
@ -69,7 +28,8 @@ int main() {
JSON json("{\"hello\": 1}"); JSON json("{\"hello\": 1}");
col->insert(json); col->insert(json);
benchmark(); BTreeUUID *btree = new BTreeUUID(PageManager::Instance().allocate());
btree->testAndBenchmark(1000);
return 0; return 0;
} }

View File

@ -10,11 +10,9 @@ Collection::Collection(const std::string &name, const int &firstPage) {
void Collection::insert(JSON &json) { void Collection::insert(JSON &json) {
if(!json.HasMember("__Invo_ID__")) { if(!json.HasMember("__Invo_ID__")) {
char uuid[32];
generateUUID(uuid);
Document::AllocatorType &allocator = json.GetAllocator(); Document::AllocatorType &allocator = json.GetAllocator();
Value invoid (kStringType); Value invoid (kStringType);
invoid.SetString(uuid, 32); invoid.SetString(generateUUID().c_str(), 32);
json.AddMember("__Invo_ID__", invoid, allocator); json.AddMember("__Invo_ID__", invoid, allocator);
} }
Logger::info<std::string, std::string>("INSERT ", json.ToString()); Logger::info<std::string, std::string>("INSERT ", json.ToString());

View File

@ -8,11 +8,13 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
inline void generateUUID(char *uuid) { inline std::string generateUUID() {
char uuid[33]; uuid[32] = '\0';
for(int i=0; i<32; i++) { for(int i=0; i<32; i++) {
int randn = rand() % 36; int randn = rand() % 36;
uuid[i] = (randn < 26 ? ('a' + randn) : ('0' + (randn - 26))); uuid[i] = (randn < 26 ? ('a' + randn) : ('0' + (randn - 26)));
} }
return std::string(uuid, 32);
} }
inline std::string appropriateString(const std::string& s, const int& offset) { inline std::string appropriateString(const std::string& s, const int& offset) {