inline void BTree<KeyType, KeyComparator>::insert(KeyType key, TID tid) { size_t currHeight = 0; uint64_t currPageId = rootPageId; BufferFrame *parentFrame = nullptr; BufferFrame *currFrame = nullptr; InnerNode<KeyType, KeyComparator> *parentNode = nullptr; InnerNode<KeyType, KeyComparator> *currNode = nullptr; while (!isLeafHeight(currHeight)) { if (parentFrame != nullptr) { bufferManager.unfixPage(*parentFrame, true); } parentFrame = currFrame; parentNode = currNode; currFrame = &bufferManager.fixPage(this->segmentId, currPageId, true); currNode = reinterpret_cast<InnerNode<KeyType, KeyComparator> *>(currFrame->getData()); if (!currNode->hasSpaceForOneMoreEntry()) { if (parentNode == nullptr) { auto newNode = createEmptyNode(currPageId); parentFrame = newNode.first; parentNode = newNode.second; currHeight++; } auto splitResult = splitInnerNode(currNode, currFrame, currPageId, parentNode, key); currFrame = splitResult.first; currNode = splitResult.second; } currPageId = currNode->getNextNode(key, this->smallerComparator); currHeight++; } // we are now at leaf height - the currPageId points to a leaf if (parentFrame != nullptr) { bufferManager.unfixPage(*parentFrame, true); } parentFrame = currFrame; parentNode = currNode; currNode = nullptr; currFrame = &bufferManager.fixPage(this->segmentId, currPageId, true); auto leaf = reinterpret_cast<Leaf<KeyType, KeyComparator> *>(currFrame->getData()); if (!leaf->hasSpaceForOneMoreEntry()) { if (parentNode == nullptr) { auto newNode = createEmptyNode(currPageId); parentFrame = newNode.first; parentNode = newNode.second; } auto splitResult = splitLeaf(leaf, currFrame, currPageId, parentNode, key); currFrame = splitResult.first; leaf = splitResult.second; } if (parentFrame != nullptr) { bufferManager.unfixPage(*parentFrame, true); } leaf->insertDefiniteFit(key, tid, smallerComparator); bufferManager.unfixPage(*currFrame, true); treeSize++; }
inline bool BTree<KeyType, KeyComparator>::searchForKey( KeyType key, TID &tid, uint64_t pageId, size_t currentHeight) { BufferFrame *currentFrame = &bufferManager.fixPage(this->segmentId, pageId, false); bool result; if (isLeafHeight(currentHeight)) { Leaf<KeyType, KeyComparator> *leaf = reinterpret_cast<Leaf<KeyType, KeyComparator> *>( currentFrame->getData()); result = leaf->lookup(key, smallerComparator, &tid); } else { //we haven't reached the leaves yet InnerNode<KeyType, KeyComparator> *currNode = reinterpret_cast<InnerNode<KeyType, KeyComparator> *> ( currentFrame->getData()); pageId = currNode->getNextNode(key, smallerComparator); result = searchForKey(key, tid, pageId, currentHeight + 1); } //return page as result was received and page is no longer required bufferManager.unfixPage(*currentFrame, false); return result; }
BufferFrame *BTree<KeyType, KeyComparator>::findFrameForKey(KeyType key, bool exclusive) { BufferFrame *currentFrame = &bufferManager.fixPage(this->segmentId, rootPageId, exclusive); int currentDepth = 0; BufferFrame *parentFrame = nullptr; while (!isLeafHeight(currentDepth)) { InnerNode<KeyType, KeyComparator> *curNode = reinterpret_cast<InnerNode<KeyType, KeyComparator> *> (currentFrame->getData()); if (parentFrame != nullptr) { bufferManager.unfixPage(*parentFrame, false); } int nextPageId = curNode->getNextNode(key, smallerComparator); parentFrame = currentFrame; currentFrame = &bufferManager.fixPage(this->segmentId, nextPageId, exclusive); currentDepth++; } if (parentFrame != nullptr) { bufferManager.unfixPage(*parentFrame, false); } //frame is fixed and has to be unfixed by the caller!! return currentFrame; }