diff --git a/invodb/btree/btree.h b/invodb/btree/btree.h index 20eed9e..443d38f 100644 --- a/invodb/btree/btree.h +++ b/invodb/btree/btree.h @@ -15,6 +15,7 @@ public: void insert(const KT &key, const int &value); void update(const KT &key, const int &value); void remove(const KT &key); + bool exists(const KT &key); int getNodeSize(); int find(const KT &key); @@ -337,7 +338,7 @@ void BTree::split(const KT &key, int address, int parentAdd, int cur curRight->save(); } - cur->release(); + if(cur->address == root) { // auto newRoot = BTreeNode::getNode(PageManager::Instance().allocate()); @@ -370,6 +371,7 @@ void BTree::split(const KT &key, int address, int parentAdd, int cur lLeaf->save(); rLeaf->save(); insertInternal(rLeaf->keySet[0], cur->parent, lLeaf->address, rLeaf->address); + cur->release(); } } @@ -464,7 +466,7 @@ void BTree::insertInternal(const KT &key, int curAdd, int lLeafAdd, child->save(); } - cur->release(); + if(cur->address == root) { // auto newRoot = BTreeNode::getNode(PageManager::Instance().allocate()); @@ -499,6 +501,7 @@ void BTree::insertInternal(const KT &key, int curAdd, int lLeafAdd, newLChild->save(); newRChild->save(); insertInternal(cur->keySet[mid], cur->parent, newLChild->address, newRChild->address); + cur->release(); } } diff --git a/invodb/btree/node.h b/invodb/btree/node.h index c99c615..354d576 100644 --- a/invodb/btree/node.h +++ b/invodb/btree/node.h @@ -16,6 +16,7 @@ template class BTreeNode { public: + BTreeNode(const int& address); static std::shared_ptr> getNode(const int &index); static BTreeNode* release(const int &index); int insert(KT const &key); @@ -50,8 +51,6 @@ public: bool leaf; int size; int address; -private: - BTreeNode(const int& address); }; template @@ -95,17 +94,7 @@ std::shared_ptr> BTreeNode::ge if(index == 0) { throw "invalid address!"; } - return std::make_shared>( BTreeNode(index)); - static LRUCache> cache(1000000); - if(!cache.exist(index)) { - auto p = std::make_shared>( BTreeNode(index)); - cache.put(index, p); - return p; - } else { - auto p = cache.get(index); - cache.put(index, p); - return p; - } + return std::make_shared>(index); } template diff --git a/invodb/file/page_manager.cpp b/invodb/file/page_manager.cpp index 67349d8..1438625 100644 --- a/invodb/file/page_manager.cpp +++ b/invodb/file/page_manager.cpp @@ -5,7 +5,7 @@ #include "page_manager.h" #include "btree/list.h" -List* PageManager::freeList = new List(1); + int PageManager::loadDatabase(const char *filename) { Instance().stream.open(filename); @@ -19,60 +19,76 @@ int PageManager::loadDatabase(const char *filename) { return 0; } -StoragePage PageManager::getPage(const int &index) { +std::shared_ptr PageManager::getPage(const int &index) { - /* if(cache.exist(index)) { return cache.get(index); } - */ - StoragePage page(index); + auto page = std::make_shared(index); // 调整指针位置 stream.clear(); - stream.seekg(index * 1024); - stream.read(page, 1024); + stream.seekg((long long)index * 1024); + stream.read(*page, 1024); return page; } void PageManager::setPage(const int &index, const StoragePage &page) { - //cache.put(index, page); + cache.put(index, std::make_shared(page)); + stream.clear(); - stream.seekg(index * 1024); + stream.seekg((long long)index * 1024); stream.write(page, 1024); } 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); - int index = stream.tellp() / 1024; + index = stream.tellp() / 1024; setPage(index, StoragePage(index)); return index; } 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) { std::string content; - StoragePage page = getPage(index); + auto page = getPage(index); while(true) { for(int i=0; i<1016; i++) { - if(page[i] == '\0') break; - content.push_back(page[i]); + if((*page)[i] == '\0') break; + content.push_back((*page)[i]); } - if(page.next() == 0) break; - page = getPage(page.next()); + if(page->next() == 0) break; + page = getPage(page->next()); } return nlohmann::json::parse(content); @@ -82,22 +98,22 @@ int PageManager::saveJSONToFile(const nlohmann::json& json) { std::string content = json.dump(); int size = content.size(); - StoragePage page = getPage(allocate()); - int res = page.getAddress(); + auto page = getPage(allocate()); + int res = page->getAddress(); int p = 0; while(p < size) { int len = std::min(size - p, 1016); - page.setStartFrom(0, &content.c_str()[p], len); - page.save(); + page->setStartFrom(0, &content.c_str()[p], len); + page->save(); p += len; if(p < size) { int newPage = allocate(); - int lastPage = page.getAddress(); - page.setNext(newPage); - page.save(); + int lastPage = page->getAddress(); + page->setNext(newPage); + page->save(); page = getPage(newPage); - page.setLast(lastPage); - page.save(); + page->setLast(lastPage); + page->save(); } } return res; diff --git a/invodb/file/page_manager.h b/invodb/file/page_manager.h index d8f48f5..824ca49 100644 --- a/invodb/file/page_manager.h +++ b/invodb/file/page_manager.h @@ -23,19 +23,18 @@ public: return instance; } static int loadDatabase(const char *filename); - StoragePage getPage(const int &index); + std::shared_ptr getPage(const int &index); void setPage(const int &index, const StoragePage &page); int allocate(); void release(const int &index, const bool &next = true); int saveJSONToFile(const nlohmann::json& json); nlohmann::json readJSONFromFile(const int &index); private: - static List *freeList; std::map map; std::fstream stream; LRUCache cache; // 私有化实现单例 - PageManager():cache(LRUCache(1000)) {} + PageManager():cache(LRUCache(100000)) {} ~PageManager() {} PageManager(const PageManager&); PageManager& operator=(const PageManager&); diff --git a/invodb/file/storage_page.cpp b/invodb/file/storage_page.cpp index fc2d88f..fd9f85b 100644 --- a/invodb/file/storage_page.cpp +++ b/invodb/file/storage_page.cpp @@ -73,4 +73,8 @@ void StoragePage::setStartFrom(const int &index, const void *content, int size) for(int i=0; iinsert(json); // } - col->test(); + //col->test(); // nlohmann::json j = nlohmann::json::parse(R"( @@ -57,10 +57,7 @@ int main() { //} // )"); - - //testAndBenchmark(100000); - - + testAndBenchmark(50000); return 0; } @@ -78,6 +75,10 @@ void testAndBenchmark(int n) { for(int i=0; i