mirror of
https://github.com/YuhangQ/InvoDB.git
synced 2025-01-26 22:50:56 +00:00
done
This commit is contained in:
parent
a9d5c2c942
commit
e8e6a73266
@ -15,6 +15,7 @@ public:
|
|||||||
void insert(const KT &key, const int &value);
|
void insert(const KT &key, const int &value);
|
||||||
void update(const KT &key, const int &value);
|
void update(const KT &key, const int &value);
|
||||||
void remove(const KT &key);
|
void remove(const KT &key);
|
||||||
|
|
||||||
bool exists(const KT &key);
|
bool exists(const KT &key);
|
||||||
int getNodeSize();
|
int getNodeSize();
|
||||||
int find(const KT &key);
|
int find(const KT &key);
|
||||||
@ -337,7 +338,7 @@ void BTree<KT, K_SIZE>::split(const KT &key, int address, int parentAdd, int cur
|
|||||||
curRight->save();
|
curRight->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->release();
|
|
||||||
|
|
||||||
if(cur->address == root) {
|
if(cur->address == root) {
|
||||||
// auto newRoot = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
// auto newRoot = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
||||||
@ -370,6 +371,7 @@ void BTree<KT, K_SIZE>::split(const KT &key, int address, int parentAdd, int cur
|
|||||||
lLeaf->save();
|
lLeaf->save();
|
||||||
rLeaf->save();
|
rLeaf->save();
|
||||||
insertInternal(rLeaf->keySet[0], cur->parent, lLeaf->address, rLeaf->address);
|
insertInternal(rLeaf->keySet[0], cur->parent, lLeaf->address, rLeaf->address);
|
||||||
|
cur->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,7 +466,7 @@ void BTree<KT, K_SIZE>::insertInternal(const KT &key, int curAdd, int lLeafAdd,
|
|||||||
child->save();
|
child->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->release();
|
|
||||||
|
|
||||||
if(cur->address == root) {
|
if(cur->address == root) {
|
||||||
// auto newRoot = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
// auto newRoot = BTreeNode<M_SIZE, KT, K_SIZE>::getNode(PageManager::Instance().allocate());
|
||||||
@ -499,6 +501,7 @@ void BTree<KT, K_SIZE>::insertInternal(const KT &key, int curAdd, int lLeafAdd,
|
|||||||
newLChild->save();
|
newLChild->save();
|
||||||
newRChild->save();
|
newRChild->save();
|
||||||
insertInternal(cur->keySet[mid], cur->parent, newLChild->address, newRChild->address);
|
insertInternal(cur->keySet[mid], cur->parent, newLChild->address, newRChild->address);
|
||||||
|
cur->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
template<int M_SIZE, typename KT, int K_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
class BTreeNode {
|
class BTreeNode {
|
||||||
public:
|
public:
|
||||||
|
BTreeNode(const int& address);
|
||||||
static std::shared_ptr<BTreeNode<M_SIZE, KT, K_SIZE>> getNode(const int &index);
|
static std::shared_ptr<BTreeNode<M_SIZE, KT, K_SIZE>> getNode(const int &index);
|
||||||
static BTreeNode<M_SIZE, KT, K_SIZE>* release(const int &index);
|
static BTreeNode<M_SIZE, KT, K_SIZE>* release(const int &index);
|
||||||
int insert(KT const &key);
|
int insert(KT const &key);
|
||||||
@ -50,8 +51,6 @@ public:
|
|||||||
bool leaf;
|
bool leaf;
|
||||||
int size;
|
int size;
|
||||||
int address;
|
int address;
|
||||||
private:
|
|
||||||
BTreeNode(const int& address);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
@ -95,17 +94,7 @@ std::shared_ptr<BTreeNode<M_SIZE, KT, K_SIZE>> BTreeNode<M_SIZE, KT, K_SIZE>::ge
|
|||||||
if(index == 0) {
|
if(index == 0) {
|
||||||
throw "invalid address!";
|
throw "invalid address!";
|
||||||
}
|
}
|
||||||
return std::make_shared<BTreeNode<M_SIZE, KT, K_SIZE>>( BTreeNode<M_SIZE, KT, K_SIZE>(index));
|
return std::make_shared<BTreeNode<M_SIZE, KT, K_SIZE>>(index);
|
||||||
static LRUCache<int, BTreeNode<M_SIZE, KT, K_SIZE>> cache(1000000);
|
|
||||||
if(!cache.exist(index)) {
|
|
||||||
auto p = std::make_shared<BTreeNode<M_SIZE, KT, K_SIZE>>( BTreeNode<M_SIZE, KT, K_SIZE>(index));
|
|
||||||
cache.put(index, p);
|
|
||||||
return p;
|
|
||||||
} else {
|
|
||||||
auto p = cache.get(index);
|
|
||||||
cache.put(index, p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int M_SIZE, typename KT, int K_SIZE>
|
template<int M_SIZE, typename KT, int K_SIZE>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "page_manager.h"
|
#include "page_manager.h"
|
||||||
#include "btree/list.h"
|
#include "btree/list.h"
|
||||||
|
|
||||||
List<int, 4>* PageManager::freeList = new List<int, 4>(1);
|
|
||||||
|
|
||||||
int PageManager::loadDatabase(const char *filename) {
|
int PageManager::loadDatabase(const char *filename) {
|
||||||
Instance().stream.open(filename);
|
Instance().stream.open(filename);
|
||||||
@ -19,60 +19,76 @@ int PageManager::loadDatabase(const char *filename) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePage PageManager::getPage(const int &index) {
|
std::shared_ptr<StoragePage> PageManager::getPage(const int &index) {
|
||||||
|
|
||||||
/*
|
|
||||||
if(cache.exist(index)) {
|
if(cache.exist(index)) {
|
||||||
return cache.get(index);
|
return cache.get(index);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
StoragePage page(index);
|
auto page = std::make_shared<StoragePage>(index);
|
||||||
// 调整指针位置
|
// 调整指针位置
|
||||||
stream.clear();
|
stream.clear();
|
||||||
stream.seekg(index * 1024);
|
stream.seekg((long long)index * 1024);
|
||||||
stream.read(page, 1024);
|
stream.read(*page, 1024);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageManager::setPage(const int &index, const StoragePage &page) {
|
void PageManager::setPage(const int &index, const StoragePage &page) {
|
||||||
//cache.put(index, page);
|
cache.put(index, std::make_shared<StoragePage>(page));
|
||||||
|
|
||||||
stream.clear();
|
stream.clear();
|
||||||
stream.seekg(index * 1024);
|
stream.seekg((long long)index * 1024);
|
||||||
stream.write(page, 1024);
|
stream.write(page, 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PageManager::allocate() {
|
int PageManager::allocate() {
|
||||||
|
|
||||||
|
// try to allocate from free block list
|
||||||
|
auto page = getPage(0);
|
||||||
|
int index = page->getIntStartFrom(0);
|
||||||
|
if(index != 0) {
|
||||||
|
auto allocatePage = getPage(index);
|
||||||
|
|
||||||
|
page->setIntStartFrom(0, allocatePage->next());
|
||||||
|
// reset
|
||||||
|
allocatePage->clear();
|
||||||
|
allocatePage->save();
|
||||||
|
page->save();
|
||||||
|
//printf("allocate: %d\n", index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// allocate block at the end
|
||||||
stream.seekp(0, std::ios::end);
|
stream.seekp(0, std::ios::end);
|
||||||
int index = stream.tellp() / 1024;
|
index = stream.tellp() / 1024;
|
||||||
setPage(index, StoragePage(index));
|
setPage(index, StoragePage(index));
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageManager::release(const int &index, const bool &next) {
|
void PageManager::release(const int &index, const bool &next) {
|
||||||
|
auto page = getPage(0);
|
||||||
|
int head = page->getIntStartFrom(0);
|
||||||
|
auto releasePage = getPage(index);
|
||||||
|
releasePage->setNext(head);
|
||||||
|
page->setIntStartFrom(0, releasePage->getAddress());
|
||||||
|
page->save();
|
||||||
|
releasePage->save();
|
||||||
|
//printf("release: %d\n", index);
|
||||||
|
|
||||||
return;
|
|
||||||
auto page = getPage(index);
|
|
||||||
freeList->insert(page.getAddress());
|
|
||||||
if(next) {
|
|
||||||
while(page.next()) {
|
|
||||||
freeList->insert(page.next());
|
|
||||||
page = getPage(page.next());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json PageManager::readJSONFromFile(const int &index) {
|
nlohmann::json PageManager::readJSONFromFile(const int &index) {
|
||||||
std::string content;
|
std::string content;
|
||||||
|
|
||||||
StoragePage page = getPage(index);
|
auto page = getPage(index);
|
||||||
while(true) {
|
while(true) {
|
||||||
for(int i=0; i<1016; i++) {
|
for(int i=0; i<1016; i++) {
|
||||||
if(page[i] == '\0') break;
|
if((*page)[i] == '\0') break;
|
||||||
content.push_back(page[i]);
|
content.push_back((*page)[i]);
|
||||||
}
|
}
|
||||||
if(page.next() == 0) break;
|
if(page->next() == 0) break;
|
||||||
page = getPage(page.next());
|
page = getPage(page->next());
|
||||||
}
|
}
|
||||||
|
|
||||||
return nlohmann::json::parse(content);
|
return nlohmann::json::parse(content);
|
||||||
@ -82,22 +98,22 @@ int PageManager::saveJSONToFile(const nlohmann::json& json) {
|
|||||||
std::string content = json.dump();
|
std::string content = json.dump();
|
||||||
int size = content.size();
|
int size = content.size();
|
||||||
|
|
||||||
StoragePage page = getPage(allocate());
|
auto page = getPage(allocate());
|
||||||
int res = page.getAddress();
|
int res = page->getAddress();
|
||||||
int p = 0;
|
int p = 0;
|
||||||
while(p < size) {
|
while(p < size) {
|
||||||
int len = std::min(size - p, 1016);
|
int len = std::min(size - p, 1016);
|
||||||
page.setStartFrom(0, &content.c_str()[p], len);
|
page->setStartFrom(0, &content.c_str()[p], len);
|
||||||
page.save();
|
page->save();
|
||||||
p += len;
|
p += len;
|
||||||
if(p < size) {
|
if(p < size) {
|
||||||
int newPage = allocate();
|
int newPage = allocate();
|
||||||
int lastPage = page.getAddress();
|
int lastPage = page->getAddress();
|
||||||
page.setNext(newPage);
|
page->setNext(newPage);
|
||||||
page.save();
|
page->save();
|
||||||
page = getPage(newPage);
|
page = getPage(newPage);
|
||||||
page.setLast(lastPage);
|
page->setLast(lastPage);
|
||||||
page.save();
|
page->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -23,19 +23,18 @@ public:
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
static int loadDatabase(const char *filename);
|
static int loadDatabase(const char *filename);
|
||||||
StoragePage getPage(const int &index);
|
std::shared_ptr<StoragePage> getPage(const int &index);
|
||||||
void setPage(const int &index, const StoragePage &page);
|
void setPage(const int &index, const StoragePage &page);
|
||||||
int allocate();
|
int allocate();
|
||||||
void release(const int &index, const bool &next = true);
|
void release(const int &index, const bool &next = true);
|
||||||
int saveJSONToFile(const nlohmann::json& json);
|
int saveJSONToFile(const nlohmann::json& json);
|
||||||
nlohmann::json readJSONFromFile(const int &index);
|
nlohmann::json readJSONFromFile(const int &index);
|
||||||
private:
|
private:
|
||||||
static List<int, 4> *freeList;
|
|
||||||
std::map<int, StoragePage> map;
|
std::map<int, StoragePage> map;
|
||||||
std::fstream stream;
|
std::fstream stream;
|
||||||
LRUCache<int, StoragePage> cache;
|
LRUCache<int, StoragePage> cache;
|
||||||
// 私有化实现单例
|
// 私有化实现单例
|
||||||
PageManager():cache(LRUCache<int, StoragePage>(1000)) {}
|
PageManager():cache(LRUCache<int, StoragePage>(100000)) {}
|
||||||
~PageManager() {}
|
~PageManager() {}
|
||||||
PageManager(const PageManager&);
|
PageManager(const PageManager&);
|
||||||
PageManager& operator=(const PageManager&);
|
PageManager& operator=(const PageManager&);
|
||||||
|
@ -73,4 +73,8 @@ void StoragePage::setStartFrom(const int &index, const void *content, int size)
|
|||||||
for(int i=0; i<size; i++) {
|
for(int i=0; i<size; i++) {
|
||||||
page[index+i] = ((const char *)content)[i];
|
page[index+i] = ((const char *)content)[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StoragePage::clear() {
|
||||||
|
memset(page, 0, sizeof(page));
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ public:
|
|||||||
int last();
|
int last();
|
||||||
void setLast(const int& lastPage);
|
void setLast(const int& lastPage);
|
||||||
void save();
|
void save();
|
||||||
|
void clear();
|
||||||
int getIntStartFrom(const int &index);
|
int getIntStartFrom(const int &index);
|
||||||
void setIntStartFrom(const int &index, const int &value);
|
void setIntStartFrom(const int &index, const int &value);
|
||||||
void setDoubleStartFrom(const int &index, const double &value);
|
void setDoubleStartFrom(const int &index, const double &value);
|
||||||
|
@ -13,7 +13,7 @@ int main() {
|
|||||||
//srand(t);
|
//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");
|
||||||
|
|
||||||
PageManager::loadDatabase("test.invodb");
|
PageManager::loadDatabase("test.invodb");
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ int main() {
|
|||||||
// col->insert(json);
|
// col->insert(json);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
col->test();
|
//col->test();
|
||||||
|
|
||||||
|
|
||||||
// nlohmann::json j = nlohmann::json::parse(R"(
|
// nlohmann::json j = nlohmann::json::parse(R"(
|
||||||
@ -57,10 +57,7 @@ int main() {
|
|||||||
//}
|
//}
|
||||||
// )");
|
// )");
|
||||||
|
|
||||||
|
testAndBenchmark(50000);
|
||||||
//testAndBenchmark(100000);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -78,6 +75,10 @@ void testAndBenchmark(int n) {
|
|||||||
for(int i=0; i<n; i++) {
|
for(int i=0; i<n; i++) {
|
||||||
int opt = rand() % 4;
|
int opt = rand() % 4;
|
||||||
|
|
||||||
|
if(i%(n/100) == 0) {
|
||||||
|
printf("[%d/%d] eeeeee\n", i, n);
|
||||||
|
}
|
||||||
|
|
||||||
// insert
|
// insert
|
||||||
if(opt <= 1) {
|
if(opt <= 1) {
|
||||||
std::string uuid = generateUUID();
|
std::string uuid = generateUUID();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user