// // Created by i on 2021/10/24. // #define UNLIMITED_MEMORY true #ifndef INVODB_NODE_H #define INVODB_NODE_H #include #include #include #include #include #include "file/page_manager.h" #include "invodb/models/cache.h" template class BTreeNode { public: static const int m = M_SIZE; static const int maxCount = m - 1; static const int minLeafCount = m / 2; static const int minLinkCount = (m - 1) / 2; static std::shared_ptr> getNode(const int &index); static BTreeNode* release(const int &index); BTreeNode(const int& address); int insert(KT const &key); int findPos(KT const &key); void update(); void release(); void clear(); int save(); bool enough(); bool full(); KT keySet[m + 1]; int linkSet[m + 1]; int parent; int left; int right; bool leaf; int size; int address; private: //static std::map>> cache; static LRUCache>> cache; }; //template //std::map>> BTreeNode::cache; template LRUCache>> BTreeNode::cache(100000); template BTreeNode::BTreeNode(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; if(std::is_same::value) { for(int i=0; ipush_back(c); } } } else { for(int i=0; i std::shared_ptr> BTreeNode::getNode(const int &index) { if(index == 0) { throw "invalid address!"; } // if(!cache.exist(index)) { // auto p = std::make_shared>(index); // cache.put(index, p); // return p; // } else { // auto p = cache.get(index); // cache.put(index, p); // return p; // } return std::make_shared>(index); // if(cache.count(index) == 0) { // cache[index] = std::make_shared>(index); // } } template BTreeNode *BTreeNode::release(const int &index) { //cache.remove(index); PageManager::Instance().release(index); return nullptr; } template int BTreeNode::insert(const KT &key) { int pos = 0; while(pos < size && key > keySet[pos]) pos++; linkSet[size + 1] = linkSet[size]; for(int i=size; i>pos; i--) { linkSet[i] = linkSet[i - 1]; keySet[i] = keySet[i - 1]; } keySet[pos] = key; size++; return pos; } template int BTreeNode::findPos(const KT &key) { int pos = std::lower_bound(keySet, keySet+size, key) - keySet; if(pos == size || keySet[pos] != key) return -1; return pos; } template void BTreeNode::release() { BTreeNode::release(this->address); } template void BTreeNode::clear() { for(int i=0; i<=m; i++) { if(std::is_same::value) { ((std::string *)&keySet[i])->clear(); } if(std::is_same::value) { *((double *)&keySet[i]) = 0; } if(std::is_same::value) { *((bool *)&keySet[i]) = 0; } if(std::is_same::value) { *((int *)&keySet[i]) = 0; } linkSet[i] = 0; } size = 0; leaf = true; parent = 0; left = 0; right = 0; } template int BTreeNode::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; if(std::is_same::value) { for(int i=0; ic_str(), str->size()); p += K_SIZE; } } else { for(int i=0; i 1024) { throw "too big page!"; } page.save(); return p; } template void BTreeNode::update() { if(leaf) return; for(int i=0; i<=size; i++) { auto node = getNode(linkSet[i]); node->parent = address; node->save(); } } template bool BTreeNode::enough() { if(leaf) return size >= minLeafCount; else return size >= minLinkCount; } template bool BTreeNode::full() { return size == maxCount; } #endif //INVODB_NODE_H