btree insert finished!

This commit is contained in:
YuhangQ 2021-10-26 12:29:59 +08:00
parent b26cf470d1
commit 177cee9f91
10 changed files with 188 additions and 148 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test.invodb

View File

@ -7,12 +7,86 @@
std::map<int, BTreeNodeUUID*> BTreeNodeUUID::map;
BTreeNodeUUID *BTreeNodeUUID::getNode(const int &address) {
if(address == 0) {
printf("???");
exit(0);
}
if(map.count(address) == 0) {
if(true || map.count(address) == 0) {
map[address] = new BTreeNodeUUID(address);
}
return map[address];
}
BTreeNodeUUID::BTreeNodeUUID(const int& address):address(address) {
clear();
StoragePage page = PageManager::Instance().getPage(address);
int p = 0;
size = page.getIntStartFrom(p);
p += 4;
parent = page.getIntStartFrom(p);
p += 4;
left = page.getIntStartFrom(p);
p += 4;
right = page.getIntStartFrom(p);
p += 4;
leaf = !page.getIntStartFrom(p);
p += 4;
for(int i=0; i<m; i++) {
for(int j=0; j<32; j++) {
key[i] += page[p++];
}
}
for(int i=0; i<m+1; i++) {
val[i] = page.getIntStartFrom(p);
p += 4;
}
}
int BTreeNodeUUID::insert(const std::string uuid) {
int pos = 0;
while(pos < size && uuid > key[pos]) pos++;
val[size + 1] = val[size];
for(int i=size; i>pos; i--) {
val[i] = val[i - 1];
key[i] = key[i - 1];
}
key[pos] = uuid;
size++;
return pos;
}
void BTreeNodeUUID::print() {
printf("---------BTreeNode---------\n");
for(int i=0; i<size; i++) {
printf("%s %d\n", key[i].c_str(), val[i]);
}
}
void BTreeNodeUUID::clear() {
for(int i=0; i<m+1; i++) key[i].clear(), val[i] = 0;
size = 0;
leaf = false;
parent = 0;
}
void BTreeNodeUUID::save() {
StoragePage page(address);
int p = 0;
page.setIntStartFrom(p, size);
p += 4;
page.setIntStartFrom(p, parent);
p += 4;
page.setIntStartFrom(p, left);
p += 4;
page.setIntStartFrom(p, right);
p += 4;
page.setIntStartFrom(p, !leaf);
p += 4;
for(int i=0; i<m; i++) {
for(int j=0; j<32; j++) {
page[p++] = key[i][j];
}
}
for(int i=0; i<m+1; i++) {
page.setIntStartFrom(p, val[i]);
p += 4;
}
page.save();
}

View File

@ -12,7 +12,7 @@
#include "file/page_manager.h"
/**
* m = 28
* m = 27
* value string max
* (32 + 4)*28 + 5 = 1013
*/
@ -21,96 +21,23 @@
class BTreeNodeUUID {
public:
static BTreeNodeUUID* getNode(const int& address);
BTreeNodeUUID(const int& address):address(address) {
clear();
StoragePage page = PageManager::Instance().getPage(address);
for(int i=0; i<28; i++) {
for(int j=0; j<32; j++) {
key[i] += page[i * 32 + j];
}
}
int p = 28 * 32;
for(int i=0; i<m+1; i++) {
val[i] = page.getIntStartFrom(p);
p += 4;
}
leaf = !page[1013];
parent = page.getIntStartFrom(1014);
}
bool isLeaf() {
return leaf;
}
void setLeaf(const bool& value) {
leaf = value;
}
void updateParent() {
if(isLeaf()) return;
for(int i=0; i<=size(); i++) {
BTreeNodeUUID child = getNode(val[i])->parent;
child.parent = address;
child.save();
}
}
int size() {
return n_size;
}
int insert(const std::string uuid) {
// static int cnt = 0;
// if(!isLeaf() && size() >= 27) {
// if(cnt) throw "fuck";
// cnt++;
// }
int pos = 0;
while(pos < n_size && uuid > key[pos]) pos++;
val[n_size + 1] = val[n_size];
for(int i=n_size; i>pos; i--) {
val[i] = val[i - 1];
key[i] = key[i - 1];
}
key[pos] = uuid;
n_size++;
return pos;
}
void print() {
printf("---------BTreeNode---------\n");
for(int i=0; i<size(); i++) {
printf("%s %d\n", key[i].c_str(), val[i]);
}
}
void clear() {
for(int i=0; i<m; i++) key[i].clear(), val[i] = 0;
n_size = 0;
leaf = false;
parent = 0;
}
int getAddress() { return address; }
void save() {
StoragePage page(address);
for(int i=0; i<28; i++) {
for(int j=0; j<32; j++) {
page[i * 32 + j] = key[i][j];
}
}
int p = 28 * 32;
for(int i=0; i<m+1; i++) {
page.setIntStartFrom(p, val[i]);
p += 4;
}
page[1013] = !leaf;
page.setIntStartFrom(1014, parent);
page.save();
}
static const int m = 28;
std::string key[m];
int insert(const std::string uuid);
void print();
void clear();
void save();
static const int m = 27;
std::string key[m+1];
int val[m+1];
int parent;
private:
static std::map<int, BTreeNodeUUID*> map;
int address;
int n_size;
int left;
int right;
bool leaf;
int size;
int address;
private:
BTreeNodeUUID(const int& address);
static std::map<int, BTreeNodeUUID*> map;
};
#endif //INVODB_BTREE_NODE_H

View File

@ -5,41 +5,46 @@
#include "btree_uuid.h"
BTreeUUID::BTreeUUID(const int& address) {
root = BTreeNodeUUID::getNode(address);
root = address;
}
void BTreeUUID::insert(const char *uuid, int address) {
BTreeNodeUUID* cur = root;
BTreeNodeUUID* cur = BTreeNodeUUID::getNode(root);
BTreeNodeUUID* parent = nullptr;
while(!cur->isLeaf()) {
while(!cur->leaf) {
parent = cur;
for(int i=0; i<cur->size(); i++) {
for(int i=0; i<cur->size; i++) {
if(uuid < cur->key[i]) {
cur = BTreeNodeUUID::getNode(cur->val[i]);
break;
}
if(i == cur->size() - 1) {
if(i == cur->size - 1) {
cur = BTreeNodeUUID::getNode(cur->val[i + 1]);
break;
}
}
cur->parent = parent->getAddress();
cur->parent = parent->address;
cur->save();
}
// insert directly
if(cur->size() < cur->m - 1) {
if(cur->size < cur->m - 1) {
cur->val[cur->insert(uuid)] = address;
cur->save();
return;
}
// split
split(uuid, address, parent, cur);
if(parent == nullptr) split(uuid, address, 0, cur->address);
else split(uuid, address, parent->address, cur->address);
}
void BTreeUUID::split(std::string uuid, int address, BTreeNodeUUID *parent, BTreeNodeUUID *cur) {
void BTreeUUID::split(std::string uuid, int address, int parentAddr, int curAddr) {
BTreeNodeUUID* parent = BTreeNodeUUID::getNode(parentAddr);
BTreeNodeUUID* cur = BTreeNodeUUID::getNode(curAddr);
cur->val[cur->insert(uuid)] = address;
@ -48,30 +53,42 @@ void BTreeUUID::split(std::string uuid, int address, BTreeNodeUUID *parent, BTre
int mid = (cur->m / 2);
for(int i=0; i<mid; i++) lLeaf->val[lLeaf->insert(cur->key[i])] = cur->val[i];
lLeaf->right = rLeaf->address;
lLeaf->left = cur->left;
for(int i=mid; i<cur->m; i++) rLeaf->val[rLeaf->insert(cur->key[i])] = cur->val[i];
rLeaf->left = rLeaf->address;
rLeaf->right = cur->right;
if(cur == root) {
if(cur->address == root) {
BTreeNodeUUID* newRoot = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
newRoot->insert(rLeaf->key[0]);
newRoot->val[0] = lLeaf->getAddress();
newRoot->val[1] = rLeaf->getAddress();
newRoot->setLeaf(false);
root = newRoot;
lLeaf->parent = rLeaf->parent = root->getAddress();
newRoot->val[0] = lLeaf->address;
newRoot->val[1] = rLeaf->address;
newRoot->leaf = false;
root = newRoot->address;
lLeaf->parent = rLeaf->parent = root;
newRoot->save();
lLeaf->save();
rLeaf->save();
} else insertInternal(rLeaf->key[0], parent, lLeaf, rLeaf);
} else {
lLeaf->save();
rLeaf->save();
insertInternal(rLeaf->key[0], parent->address, lLeaf->address, rLeaf->address);
}
}
void BTreeUUID::insertInternal(std::string uuid, BTreeNodeUUID *cur, BTreeNodeUUID *lLeaf, BTreeNodeUUID *rLeaf) {
void BTreeUUID::insertInternal(std::string uuid, int curAddr, int lLeafAddr, int rLeafAddr) {
if(cur->size() < cur->m - 1) {
BTreeNodeUUID *cur = BTreeNodeUUID::getNode(curAddr);
BTreeNodeUUID *lLeaf = BTreeNodeUUID::getNode(lLeafAddr);
BTreeNodeUUID *rLeaf = BTreeNodeUUID::getNode(rLeafAddr);
if(cur->size < cur->m - 1) {
int pos = cur->insert(uuid);
cur->val[pos] = lLeaf->getAddress();
cur->val[pos+1] = rLeaf->getAddress();
lLeaf->parent = rLeaf->parent = root->getAddress();
cur->val[pos] = lLeaf->address;
cur->val[pos+1] = rLeaf->address;
lLeaf->parent = rLeaf->parent = root;
cur->save();
lLeaf->save();
rLeaf->save();
@ -80,19 +97,14 @@ void BTreeUUID::insertInternal(std::string uuid, BTreeNodeUUID *cur, BTreeNodeUU
BTreeNodeUUID* newLChild = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
BTreeNodeUUID* newRChild = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
newLChild->setLeaf(false);
newRChild->setLeaf(false);
if(cur->size() != 27) {
printf("%d %d %d p:%d cur:%d\n", cur->size(), cur->isLeaf(), cur==root, cur->parent, cur->getAddress());
exit(0);
}
newLChild->leaf = false;
newRChild->leaf = false;
int pos = cur->insert(uuid);
cur->val[pos] = lLeaf->getAddress();
cur->val[pos+1] = rLeaf->getAddress();
cur->val[pos] = lLeaf->address;
cur->val[pos+1] = rLeaf->address;
int mid = cur->size() / 2;
int mid = cur->size / 2;
for(int i=0; i<mid; i++) newLChild->insert(cur->key[i]);
for(int i=0; i<=mid; i++) newLChild->val[i] = cur->val[i];
@ -100,46 +112,70 @@ void BTreeUUID::insertInternal(std::string uuid, BTreeNodeUUID *cur, BTreeNodeUU
for(int i=mid+1; i<cur->m; i++) newRChild->insert(cur->key[i]);
for(int i=mid+1; i<=cur->m; i++) newRChild->val[i-mid-1] = cur->val[i];
if(cur == root) {
lLeaf->save();
rLeaf->save();
if(cur->address == root) {
BTreeNodeUUID* newRoot = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
newRoot->insert(cur->key[mid]);
newRoot->val[0] = newLChild->getAddress();
newRoot->val[1] = newRChild->getAddress();
newRoot->setLeaf(false);
root = newRoot;
newLChild->parent = newRChild->parent = root->getAddress();
newRoot->val[0] = newLChild->address;
newRoot->val[1] = newRChild->address;
newRoot->leaf = false;
root = newRoot->address;
newLChild->parent = newRChild->parent = root;
newRoot->save();
newLChild->save();
newRChild->save();
} else {
insertInternal(cur->key[mid], BTreeNodeUUID::getNode(cur->parent), newLChild, newRChild);
newLChild->save();
newRChild->save();
if(cur->parent == 0) throw "fuck";
insertInternal(cur->key[mid], cur->parent, newLChild->address, newRChild->address);
}
}
void BTreeUUID::print() {
innerPrint(root);
innerPrint(BTreeNodeUUID::getNode(root));
}
void BTreeUUID::innerPrint(BTreeNodeUUID *cur) {
if(cur == root) {
if(cur->address == root) {
cnt = 0;
}
if(cur->isLeaf()) cnt += cur->size();
printf("---------%d(%d)count=%d&sum=%d--------\n", cur->getAddress(), cur->isLeaf(), cur->size(), cnt);
for(int i=0; i<cur->size(); i++) {
if(cur->leaf) cnt += cur->size;
printf("---------%d(%d)count=%d&sum=%d---l:%d,r:%d-----\n", cur->address, cur->leaf, cur->size, cnt, cur->left, cur->right);
for(int i=0; i<cur->size; i++) {
printf("%d:%s ", i, cur->key[i].substr(0, 4).c_str());
}
printf("\n");
for(int i=0; i<=cur->size(); i++) {
for(int i=0; i<=cur->size; i++) {
printf("%d:%d ", i, cur->val[i]);
}
printf("\n");
if(cur->isLeaf()) return;
for(int i=0; i<=cur->size(); i++) {
if(cur->leaf) return;
for(int i=0; i<=cur->size; i++) {
innerPrint(BTreeNodeUUID::getNode(cur->val[i]));
}
/*
BTreeNodeUUID test = *cur;
test.address = PageManager::Instance().allocate();
test.print();
test.save();
BTreeNodeUUID test2 = *BTreeNodeUUID::getNode(test.address);
printf("test: size:%d l:%d r:%d\n", test2.size, test2.left, test2.right);
test2.print();
*/
}
/*
void BTreeUUID::innerInsert(BTreeNodeUUID* &p, BTreeNodeUUID* f, const char *uuid, int address) {
@ -161,3 +197,4 @@ void BTreeUUID::innerInsert(BTreeNodeUUID* &p, BTreeNodeUUID* f, const char *uui
}
*/

View File

@ -10,14 +10,13 @@
class BTreeUUID {
public:
BTreeUUID(const int& address);
~BTreeUUID() { delete root; };
void insert(const char* uuid, int address);
void print();
private:
void innerPrint(BTreeNodeUUID* cur);
void split(std::string uuid, int address, BTreeNodeUUID* parent, BTreeNodeUUID* cur);
void insertInternal(std::string uuid, BTreeNodeUUID* cur, BTreeNodeUUID* lLeaf, BTreeNodeUUID* rLeaf);
BTreeNodeUUID *root;
void split(std::string uuid, int address, int parentAddr, int curAddr);
void insertInternal(std::string uuid, int curAddr, int lLeafAddr, int rLeafAddr);
int root;
int cnt;
};

View File

@ -22,6 +22,7 @@ void PageManager::setPage(const int &index, const StoragePage &page) {
stream.clear();
stream.seekg(index * 1024);
stream.write(page, 1024);
stream.flush();
}
int PageManager::allocate() {

View File

@ -24,7 +24,7 @@ public:
void setStringStartFrom(const int &index, const char *str);
int *intArray();
StoragePage(const int& id) { memset(page, 0, sizeof(page)); this->address = id; }
char& operator[] (int index) { return this->page[index]; }
char& operator[] (int index) { if(index>=1024 || index < 0) throw "overflow"; else return this->page[index]; }
operator const char *() const { return this->page; }
operator char *() { return this->page; }
int getAddress();

View File

@ -14,6 +14,7 @@ int main() {
PageManager& manager = PageManager::Instance();
Collection *col;
try {
col = &Collection::getCollection("hello");
@ -24,10 +25,9 @@ int main() {
JSON json("{\"hello\": 1}");
col->insert(json);
BTreeUUID *btree = new BTreeUUID(PageManager::Instance().allocate());
char uuid[32];
for(int i=0; i<100000; i++) {
for(int i=0; i<1000000; i++) {
generateUUID(uuid);
btree->insert(uuid, PageManager::Instance().allocate());
}

View File

@ -6,6 +6,8 @@
#define INVODB_MAIN_H
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <models/collection.h>

View File

@ -9,7 +9,6 @@ Collection::Collection(const std::string &name, const int &firstPage) {
}
void Collection::insert(JSON &json) {
if(!json.HasMember("__Invo_ID__")) {
char uuid[32];
generateUUID(uuid);