diff --git a/.gitignore b/.gitignore index 0d28bdd..13b5060 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -test.invodb \ No newline at end of file +test.invodb +/cmake-build-debug/ +.idea \ No newline at end of file diff --git a/invodb/btree/btree.h b/invodb/btree/btree.h index 78a2fd0..1a90982 100644 --- a/invodb/btree/btree.h +++ b/invodb/btree/btree.h @@ -18,11 +18,12 @@ public: bool exists(const KT &key); int getNodeSize(); int find(const KT &key); + int findNode(const KT &key); + int firstNode(); std::vector keySet(); std::vector> all(); int size(); private: - int findNode(const KT &key); void removeEntry(int curAdd, const KT& key, const int& pointer); bool canCoalesce(int curAdd, int sibAdd); void coalesce(int curAdd, int sibAdd); @@ -473,5 +474,14 @@ std::vector> BTree::all() { return v; } +template +int BTree::firstNode() { + auto p = BTreeNode::getNode(root); + while(!p->leaf) { + p = BTreeNode::getNode(p->linkSet[0]); + } + return p.address; +} + #endif //INVODB_BTREE_H diff --git a/invodb/btree/node.h b/invodb/btree/node.h index 9b8f056..da496c1 100644 --- a/invodb/btree/node.h +++ b/invodb/btree/node.h @@ -83,7 +83,7 @@ BTreeNode::BTreeNode(const int& address): address(address) { template BTreeNode *BTreeNode::getNode(const int &index) { - if(index < 4) { + if(index == 0) { throw "invalid address!"; } static std::map*> map; @@ -96,6 +96,7 @@ BTreeNode *BTreeNode::getNode(const int template BTreeNode *BTreeNode::release(const int &index) { + PageManager::Instance().release(index); return nullptr; } diff --git a/invodb/file/page_manager.cpp b/invodb/file/page_manager.cpp index f4c911e..5c86110 100644 --- a/invodb/file/page_manager.cpp +++ b/invodb/file/page_manager.cpp @@ -3,17 +3,25 @@ // #include "page_manager.h" +#include "btree/list.h" + +List* PageManager::freeList = new List(1); int PageManager::loadDatabase(const char *filename) { Instance().stream.open(filename); + Instance().stream.seekp(0, std::ios::end); + int index = Instance().stream.tellp() / 1024; + if(index == 0) { + StoragePage(0).save(); + StoragePage(1).save(); + StoragePage(2).save(); + } return 0; } StoragePage PageManager::getPage(const int &index) { if(cache.exist(index)) { - static int cnt = 0; - printf("%d\n", ++cnt); return cache.get(index); } @@ -26,9 +34,7 @@ StoragePage PageManager::getPage(const int &index) { } void PageManager::setPage(const int &index, const StoragePage &page) { - cache.put(index, page); - stream.clear(); stream.seekg(index * 1024); stream.write(page, 1024); @@ -41,8 +47,15 @@ int PageManager::allocate() { return index; } -void PageManager::release(const int &index) { - +void PageManager::release(const int &index, const bool &next) { + 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) { @@ -83,9 +96,6 @@ int PageManager::saveJSONToFile(const nlohmann::json& json) { page.save(); } } - - - return res; } diff --git a/invodb/file/page_manager.h b/invodb/file/page_manager.h index 0382015..d8f48f5 100644 --- a/invodb/file/page_manager.h +++ b/invodb/file/page_manager.h @@ -13,6 +13,9 @@ #include "json/json.hpp" #include "models/cache.h" +template +class List; + class PageManager { public: static PageManager& Instance() { @@ -23,15 +26,16 @@ public: StoragePage getPage(const int &index); void setPage(const int &index, const StoragePage &page); int allocate(); - void release(const int &index); + 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(50000)) {} + PageManager():cache(LRUCache(1000)) {} ~PageManager() {} PageManager(const PageManager&); PageManager& operator=(const PageManager&); diff --git a/invodb/models/collection.cpp b/invodb/models/collection.cpp index 9b0cafe..5e0d87a 100644 --- a/invodb/models/collection.cpp +++ b/invodb/models/collection.cpp @@ -4,57 +4,26 @@ #include "collection.h" +BTree Collection::colList(2); std::map Collection::map; -std::set Collection::free; void Collection::loadCollections() { - // 前四页为集合信息页 - for (int id = 0; id < 4; id++) { - StoragePage page = PageManager::Instance().getPage(id); - PageManager::Instance().setPage(id, page); - for (int i = 0; i < 32; i++) { - int p = i * 32; - int len = strlen(&page[p]); - std::string name(&page[p], len > 28 ? 28 : len); - int firstPage = page.getIntStartFrom(p + 28); - // if free - if (firstPage == 0) free.insert(id * 32 + i); - // not free - else map.insert(make_pair(name, new Collection(name, firstPage))); - } + int cnt = 0; + for(auto& key : colList.keySet()) { + map.insert(std::make_pair(key, new Collection(key, colList.find(key)))); + cnt++; } - Logger::info("Successfully load Collections: ", 128 - free.size()); + Logger::info("Successfully load Collections: ", cnt); } Collection& Collection::createCollection(const std::string &name) { // exist if(map.count(name) != 0) { - throw "collection has already exist"; + return *map[name]; } - // no free line - if(free.size() == 0) { - throw "you are reach the max limit count of collections"; - } - int id = *free.begin(); - free.erase(free.begin()); - - StoragePage page = PageManager::Instance().getPage(id / 32); - id %= 32; - - StoragePage collectionPage = PageManager::Instance().getPage(PageManager::Instance().allocate()); - - if(name.size() > 28) { - throw "too long name of collection"; - } - - page.setStringStartFrom(id*32, name.c_str()); - page.setIntStartFrom(id*32+28, collectionPage.getAddress()); - page.save(); - - Collection *col = new Collection(name, collectionPage.getAddress()); - + colList.insert(name, PageManager::Instance().allocate()); + Collection *col = new Collection(name, colList.find(name)); map.insert(make_pair(name, col)); - return *col; } @@ -68,8 +37,6 @@ Collection &Collection::getCollection(const std::string &name) { Collection::Collection(const std::string &name, const int &firstPage) { Logger::info("load Collection: ", name); index = new BTree(firstPage); - - if(!index->exists("__INVO_ID__")) { index->insert("__INVO_ID__", PageManager::Instance().allocate()); } diff --git a/invodb/models/collection.h b/invodb/models/collection.h index 7f11968..d98d75a 100644 --- a/invodb/models/collection.h +++ b/invodb/models/collection.h @@ -36,7 +36,7 @@ private: void removeIndex(const std::string indexName, bool indexValue, const int& address); static std::map map; - static std::set free; + static BTree colList; BTree *uuid; BTree *index;