mirror of
https://github.com/YuhangQ/InvoDB.git
synced 2025-01-26 06:30:57 +00:00
btree init
This commit is contained in:
parent
f5a93fae0f
commit
612005483a
@ -8,4 +8,4 @@ include_directories(./invodb)
|
||||
|
||||
add_executable(InvoDB
|
||||
invodb/main.cpp
|
||||
invodb/main.h invodb/file/page_manager.cpp invodb/file/page_manager.h invodb/models/json.cpp invodb/models/json.h invodb/invodb.cpp invodb/invodb.h invodb/models/collection.cpp invodb/models/collection.h invodb/file/storage_page.cpp invodb/file/storage_page.h invodb/utils/logger.h invodb/utils/uuid.h invodb/btree/btree_node.cpp invodb/btree/btree_node.h)
|
||||
invodb/main.h invodb/file/page_manager.cpp invodb/file/page_manager.h invodb/models/json.cpp invodb/models/json.h invodb/models/collection.cpp invodb/models/collection.h invodb/file/storage_page.cpp invodb/file/storage_page.h invodb/utils/logger.h invodb/utils/uuid.h invodb/btree/btree_node.h invodb/btree/btree_uuid.cpp invodb/btree/btree_uuid.h invodb/btree/btree_node.cpp)
|
||||
|
@ -1,5 +1,18 @@
|
||||
//
|
||||
// Created by i on 2021/10/24.
|
||||
// Created by YuhangQ on 2021/10/25.
|
||||
//
|
||||
|
||||
#include "btree_node.h"
|
||||
|
||||
std::map<int, BTreeNodeUUID*> BTreeNodeUUID::map;
|
||||
|
||||
BTreeNodeUUID *BTreeNodeUUID::getNode(const int &address) {
|
||||
if(address == 0) {
|
||||
printf("???");
|
||||
exit(0);
|
||||
}
|
||||
if(map.count(address) == 0) {
|
||||
map[address] = new BTreeNodeUUID(address);
|
||||
}
|
||||
return map[address];
|
||||
}
|
||||
|
@ -7,22 +7,102 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "file/page_manager.h"
|
||||
|
||||
/**
|
||||
* m = 16
|
||||
* value string max 56
|
||||
* (56 + 4)*16 + 4 * 16 = 1024
|
||||
* m = 28
|
||||
* value string max
|
||||
* (32 + 4)*28 + 5 = 1013
|
||||
*/
|
||||
|
||||
class BTreeNode {
|
||||
|
||||
class BTreeNodeUUID {
|
||||
public:
|
||||
BTreeNode() { memset(arr, 0, sizeof(arr)); }
|
||||
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++) {
|
||||
|
||||
}
|
||||
}
|
||||
int size() {
|
||||
return n_size;
|
||||
}
|
||||
int insert(const std::string uuid) {
|
||||
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--) {
|
||||
key[i] = key[i - 1];
|
||||
val[i] = val[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 val[m+1];
|
||||
int parent;
|
||||
private:
|
||||
struct NodeValue {
|
||||
char key[56];
|
||||
int value;
|
||||
};
|
||||
std::pair<char *, int> arr[127];
|
||||
static std::map<int, BTreeNodeUUID*> map;
|
||||
int address;
|
||||
int n_size;
|
||||
bool leaf;
|
||||
};
|
||||
|
||||
#endif //INVODB_BTREE_NODE_H
|
||||
|
159
invodb/btree/btree_uuid.cpp
Normal file
159
invodb/btree/btree_uuid.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/10/25.
|
||||
//
|
||||
|
||||
#include "btree_uuid.h"
|
||||
|
||||
BTreeUUID::BTreeUUID(const int& address) {
|
||||
root = BTreeNodeUUID::getNode(address);
|
||||
}
|
||||
|
||||
void BTreeUUID::insert(const char *uuid, int address) {
|
||||
|
||||
BTreeNodeUUID* cur = root;
|
||||
BTreeNodeUUID* parent = nullptr;
|
||||
|
||||
while(!cur->isLeaf()) {
|
||||
parent = cur;
|
||||
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) {
|
||||
cur = BTreeNodeUUID::getNode(cur->val[i + 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cur->parent = cur->getAddress();
|
||||
}
|
||||
|
||||
// insert directly
|
||||
if(cur->size() < cur->m - 1) {
|
||||
cur->val[cur->insert(uuid)] = address;
|
||||
cur->save();
|
||||
return;
|
||||
}
|
||||
|
||||
// split
|
||||
split(uuid, address, parent, cur);
|
||||
}
|
||||
|
||||
void BTreeUUID::split(std::string uuid, int address, BTreeNodeUUID *parent, BTreeNodeUUID *cur) {
|
||||
|
||||
cur->val[cur->insert(uuid)] = address;
|
||||
|
||||
BTreeNodeUUID* lLeaf = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
|
||||
BTreeNodeUUID* rLeaf = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
|
||||
|
||||
int mid = (cur->m / 2);
|
||||
for(int i=0; i<mid; i++) lLeaf->val[lLeaf->insert(cur->key[i])] = cur->val[i];
|
||||
for(int i=mid; i<cur->m; i++) rLeaf->val[rLeaf->insert(cur->key[i])] = cur->val[i];
|
||||
|
||||
if(cur == 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->save();
|
||||
lLeaf->save();
|
||||
rLeaf->save();
|
||||
} else insertInternal(rLeaf->key[0], parent, lLeaf, rLeaf);
|
||||
}
|
||||
|
||||
void BTreeUUID::insertInternal(std::string uuid, BTreeNodeUUID *cur, BTreeNodeUUID *lLeaf, BTreeNodeUUID *rLeaf) {
|
||||
|
||||
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->save();
|
||||
lLeaf->save();
|
||||
rLeaf->save();
|
||||
return;
|
||||
}
|
||||
BTreeNodeUUID* newLChild = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
|
||||
BTreeNodeUUID* newRChild = BTreeNodeUUID::getNode(PageManager::Instance().allocate());
|
||||
newLChild->setLeaf(false);
|
||||
newRChild->setLeaf(false);
|
||||
|
||||
int pos = cur->insert(uuid);
|
||||
cur->val[pos] = lLeaf->getAddress();
|
||||
cur->val[pos+1] = rLeaf->getAddress();
|
||||
|
||||
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];
|
||||
|
||||
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) {
|
||||
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->save();
|
||||
newLChild->save();
|
||||
newRChild->save();
|
||||
|
||||
|
||||
} else {
|
||||
insertInternal(cur->key[mid], BTreeNodeUUID::getNode(cur->parent), newLChild, newRChild);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BTreeUUID::print() {
|
||||
innerPrint(root);
|
||||
}
|
||||
|
||||
void BTreeUUID::innerPrint(BTreeNodeUUID *cur) {
|
||||
if(cur == 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++) {
|
||||
printf("%d:%s ", i, cur->key[i].substr(0, 4).c_str());
|
||||
}
|
||||
printf("\n");
|
||||
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++) {
|
||||
innerPrint(BTreeNodeUUID::getNode(cur->val[i]));
|
||||
}
|
||||
}
|
||||
/*
|
||||
void BTreeUUID::innerInsert(BTreeNodeUUID* &p, BTreeNodeUUID* f, const char *uuid, int address) {
|
||||
if(p == nullptr) {
|
||||
p = new BTreeNodeUUID(PageManager::Instance().allocate());
|
||||
p->insert(uuid, address);
|
||||
return;
|
||||
}
|
||||
p->insert(uuid, address);
|
||||
p->print();
|
||||
// full
|
||||
if(p->size() == p->m) {
|
||||
int mid = p->m / 2;
|
||||
BTreeNodeUUID* lnode = new BTreeNodeUUID(PageManager::Instance().allocate());
|
||||
BTreeNodeUUID* rnode = new BTreeNodeUUID(PageManager::Instance().allocate());
|
||||
for(int i=0; i<mid; i++) lnode->insert(p->link[i].key, p->link[i].value);
|
||||
for(int i=mid; i<p->m; i++) rnode->insert(p->link[i].key, p->link[i].value);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
25
invodb/btree/btree_uuid.h
Normal file
25
invodb/btree/btree_uuid.h
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/10/25.
|
||||
//
|
||||
|
||||
#ifndef INVODB_BTREE_UUID_H
|
||||
#define INVODB_BTREE_UUID_H
|
||||
|
||||
#include <btree/btree_node.h>
|
||||
|
||||
class BTreeUUID {
|
||||
public:
|
||||
BTreeUUID(const int& address);
|
||||
~BTreeUUID() { delete root; };
|
||||
void insert(const char* uuid, int address);
|
||||
void print();
|
||||
void innerPrint(BTreeNodeUUID* cur);
|
||||
private:
|
||||
void split(std::string uuid, int address, BTreeNodeUUID* parent, BTreeNodeUUID* cur);
|
||||
void insertInternal(std::string uuid, BTreeNodeUUID* cur, BTreeNodeUUID* lLeaf, BTreeNodeUUID* rLeaf);
|
||||
BTreeNodeUUID *root;
|
||||
int cnt;
|
||||
};
|
||||
|
||||
|
||||
#endif //INVODB_BTREE_UUID_H
|
@ -1,6 +0,0 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/10/9.
|
||||
//
|
||||
|
||||
#include "invodb.h"
|
||||
|
@ -1,20 +0,0 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/10/9.
|
||||
//
|
||||
|
||||
#ifndef INVODB_INVODB_H
|
||||
#define INVODB_INVODB_H
|
||||
|
||||
#include "models/json.h"
|
||||
#include "models/collection.h"
|
||||
|
||||
class InvoDB {
|
||||
public:
|
||||
Collection createCollection();
|
||||
Collection getCollection();
|
||||
void deleteCollection();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //INVODB_INVODB_H
|
@ -5,17 +5,34 @@
|
||||
#include "main.h"
|
||||
|
||||
int main() {
|
||||
srand(time(NULL));
|
||||
|
||||
system("rm -rf test.invodb && touch test.invodb");
|
||||
|
||||
PageManager::loadDatabase("test.invodb");
|
||||
Collection::loadCollections();
|
||||
|
||||
PageManager& manager = PageManager::Instance();
|
||||
|
||||
//Collection::createCollection("hello");
|
||||
Collection &col = Collection::getCollection("hello");
|
||||
Collection *col;
|
||||
try {
|
||||
col = &Collection::getCollection("hello");
|
||||
} catch(const char *error) {
|
||||
Collection::createCollection("hello");
|
||||
}
|
||||
|
||||
JSON json("{\"hello\": 1}");
|
||||
col.insert(json);
|
||||
col->insert(json);
|
||||
|
||||
|
||||
BTreeUUID *btree = new BTreeUUID(PageManager::Instance().allocate());
|
||||
char uuid[32];
|
||||
for(int i=0; i<1000; i++) {
|
||||
generateUUID(uuid);
|
||||
btree->insert(uuid, PageManager::Instance().allocate());
|
||||
}
|
||||
|
||||
btree->print();
|
||||
|
||||
return 0;
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
#define INVODB_MAIN_H
|
||||
|
||||
#include <iostream>
|
||||
#include "models/collection.h"
|
||||
#include <models/collection.h>
|
||||
|
||||
|
||||
#endif //INVODB_MAIN_H
|
||||
|
@ -3,7 +3,6 @@
|
||||
//
|
||||
|
||||
#include "collection.h"
|
||||
#include "utils/uuid.h"
|
||||
|
||||
Collection::Collection(const std::string &name, const int &firstPage) {
|
||||
Logger::info<std::string, std::string>("load Collection: ", name);
|
||||
|
@ -7,11 +7,13 @@
|
||||
|
||||
#include "file/page_manager.h"
|
||||
#include "utils/logger.h"
|
||||
#include "btree/btree_uuid.h"
|
||||
#include "json.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "utils/uuid.h"
|
||||
|
||||
class Collection {
|
||||
public:
|
||||
|
@ -16,7 +16,6 @@ class JSON : public Document {
|
||||
public:
|
||||
JSON(std::string json): Document() { this->Parse(json.c_str()); }
|
||||
JSON(const char *json): Document() { this->Parse(json); }
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
};
|
||||
|
@ -8,8 +8,7 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
void generateUUID(char *uuid) {
|
||||
srand(time(NULL));
|
||||
inline void generateUUID(char *uuid) {
|
||||
for(int i=0; i<32; i++) {
|
||||
int randn = rand() % 36;
|
||||
uuid[i] = (randn < 26 ? ('a' + randn) : ('0' + (randn - 26)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user