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

View File

@ -19,7 +19,6 @@ int BTreeUUID::find(const std::string& uuid) {
int BTreeUUID::findNode(const std::string& uuid) {
NodeUUID* cur = NodeUUID::getNode(root);
while(!cur->leaf) {
int parent = cur->address;
for(int i=0; i<cur->size; i++) {
if(uuid < cur->key[i]) {
cur = NodeUUID::getNode(cur->val[i]);
@ -30,32 +29,28 @@ int BTreeUUID::findNode(const std::string& uuid) {
break;
}
}
//if(cur->parent != parent) cur->parent = parent;
//cur->save();
}
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) {
NodeUUID* cur = NodeUUID::getNode(root);
NodeUUID* parent = nullptr;
while(!cur->leaf) {
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;
}
}
if(find(uuid) != -1) {
throw "key already exists.";
}
n_size++;
NodeUUID* cur = NodeUUID::getNode(findNode(uuid));
// insert directly
if(cur->size < cur->m - 1) {
cur->val[cur->insert(uuid)] = address;
@ -64,13 +59,11 @@ void BTreeUUID::insert(const std::string& uuid, int address) {
}
// split
if(parent == nullptr) split(uuid, address, 0, cur->address);
else split(uuid, address, parent->address, cur->address);
split(uuid, address, cur->parent, cur->address);
}
void BTreeUUID::split(const std::string& uuid, int address, int parentAddr, int curAddr) {
NodeUUID* parent = NodeUUID::getNode(parentAddr);
NodeUUID* cur = NodeUUID::getNode(curAddr);
cur->val[cur->insert(uuid)] = address;
@ -116,7 +109,7 @@ void BTreeUUID::split(const std::string& uuid, int address, int parentAddr, int
} else {
lLeaf->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() {
innerPrint(NodeUUID::getNode(root));
}
@ -235,10 +228,14 @@ void BTreeUUID::innerPrint(NodeUUID *cur) {
}
}
*/
void BTreeUUID::remove(const std::string &uuid) {
if(find(uuid) == -1) {
throw "key doesn't exists.";
}
n_size--;
NodeUUID* cur = NodeUUID::getNode(findNode(uuid));
if(find(uuid) == -1) printf("ohFUCK\n");
removeEntry(cur->address, uuid, find(uuid));
}
@ -428,14 +425,62 @@ void BTreeUUID::redistribute(int curAddr, int sibAddr) {
parent->save();
}
int BTreeUUID::test() {
NodeUUID* cur = NodeUUID::getNode(findNode("\0"));
int sum = cur->size;
while(cur->right) {
cur = NodeUUID::getNode(cur->right);
sum += cur->size;
int BTreeUUID::size() {
return n_size;
}
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);
}
}
return sum;
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:
BTreeUUID(const int& address);
void insert(const std::string& uuid, int address);
void update(const std::string& uuid, int address);
void remove(const std::string& uuid);
int find(const std::string& uuid);
void print();
int test();
void testAndBenchmark(const int& n);
int size();
private:
void removeEntry(int curAddr, const std::string& uuid, const int& pointer);
bool canCoalesce(int curAddr, int sibAddr);
@ -27,7 +29,7 @@ private:
void split(const std::string& uuid, int address, int parentAddr, int curAddr);
void insertInternal(const std::string& uuid, int curAddr, int lLeafAddr, int rLeafAddr);
int root;
int cnt;
int n_size;
};

View File

@ -4,51 +4,10 @@
#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 t = time(0);
//srand(1635418590);
srand(1635423140);
srand(t);
printf("seed: %d\n", t);
system("rm -rf test.invodb && touch test.invodb");
@ -69,7 +28,8 @@ int main() {
JSON json("{\"hello\": 1}");
col->insert(json);
benchmark();
BTreeUUID *btree = new BTreeUUID(PageManager::Instance().allocate());
btree->testAndBenchmark(1000);
return 0;
}

View File

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

View File

@ -8,11 +8,13 @@
#include <iostream>
#include <string>
inline void generateUUID(char *uuid) {
inline std::string generateUUID() {
char uuid[33]; uuid[32] = '\0';
for(int i=0; i<32; i++) {
int randn = rand() % 36;
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) {