mirror of
https://github.com/YuhangQ/InvoDB.git
synced 2025-01-25 22:20:58 +00:00
btree insert finished!
This commit is contained in:
parent
b26cf470d1
commit
177cee9f91
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
test.invodb
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#define INVODB_MAIN_H
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <models/collection.h>
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user