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++; }
bool BPlusTree::recursiveInsert(Node* nodoCorriente, Key clave, ByteString dato, Key* clavePromocion, Node** nuevoNodo) { if (!nodoCorriente->isLeaf()) { InnerNode *nodoInteriorCorriente = static_cast<InnerNode*> (nodoCorriente); Key nuevaClave; Node* nuevoNodoHijo = NULL; int posicion = getPosition(nodoInteriorCorriente, clave); Node* nodoHijo = hidratateNode(nodoInteriorCorriente->sons[posicion]); bool resultado = recursiveInsert(nodoHijo, clave, dato, &nuevaClave, &nuevoNodoHijo); if (nuevoNodoHijo) { if (nodoInteriorCorriente->isOverflow(nuevaClave.getSize() + TreeConstraits::getControlSizeRecord() + keyTopSize)) { splitInnerNode(nodoInteriorCorriente, clavePromocion, nuevoNodo, posicion); if (posicion == nodoInteriorCorriente->keyMount + 1 && nodoInteriorCorriente->keyMount < (*nuevoNodo)->keyMount) { InnerNode *nuevoNodoInterior = static_cast<InnerNode*> (*nuevoNodo); nodoInteriorCorriente->keys[nodoInteriorCorriente->keyMount] = *clavePromocion; nodoInteriorCorriente->sons[nodoInteriorCorriente->keyMount + 1] = nuevoNodoInterior->sons[0]; nodoInteriorCorriente->keyMount++; nodoInteriorCorriente->occupiedSpace += (*clavePromocion).getSize() + TreeConstraits::getControlSizeRecord(); nuevoNodoInterior->sons[0] = nuevoNodoHijo->number; *clavePromocion = nuevaClave; persistNode(nuevoNodoHijo); freeNodeMemory(nuevoNodoHijo); persistNode(nodoHijo); freeNodeMemory(nodoHijo); return resultado; } else { if (posicion >= nodoInteriorCorriente->keyMount + 1) { posicion -= (nodoInteriorCorriente->keyMount + 1); nodoInteriorCorriente = static_cast<InnerNode*> (*nuevoNodo); } } } int i = nodoInteriorCorriente->keyMount; while (i > posicion) { nodoInteriorCorriente->keys[i] = nodoInteriorCorriente->keys[i - 1]; nodoInteriorCorriente->sons[i + 1] = nodoInteriorCorriente->sons[i]; i--; } nodoInteriorCorriente->keys[posicion] = nuevaClave; nodoInteriorCorriente->sons[posicion + 1] = nuevoNodoHijo->number; nodoInteriorCorriente->keyMount++; nodoInteriorCorriente->occupiedSpace += nuevaClave.getSize() + TreeConstraits::getControlSizeRecord(); persistNode(nuevoNodoHijo); freeNodeMemory(nuevoNodoHijo); } persistNode(nodoHijo); freeNodeMemory(nodoHijo); return resultado; } else { LeafNode *nodoHojaCorriente = static_cast<LeafNode*> (nodoCorriente); int posicion = getPosition(nodoHojaCorriente, clave); // chequea que no exista la clave if (posicion < nodoHojaCorriente->keyMount && equalKey(clave, nodoHojaCorriente->keys[posicion])) { return false; } int i = nodoHojaCorriente->keyMount - 1; while (i >= 0 && minorKey(clave, nodoHojaCorriente->keys[i])) { nodoHojaCorriente->keys[i + 1] = nodoHojaCorriente->keys[i]; nodoHojaCorriente->byteData[i + 1] = nodoHojaCorriente->byteData[i]; i--; } nodoHojaCorriente->keys[i + 1] = clave; nodoHojaCorriente->byteData[i + 1] = dato; nodoHojaCorriente->keyMount++; nodoHojaCorriente->occupiedSpace += dato.getSize() + clave.getSize() + TreeConstraits::getControlSizeRecord(); if (nodoHojaCorriente->isOverflow(keyTopSize)) { splitLeafNode(nodoHojaCorriente, clavePromocion, nuevoNodo); if (posicion >= nodoHojaCorriente->keyMount) { posicion -= nodoHojaCorriente->keyMount; nodoHojaCorriente = static_cast<LeafNode*> (*nuevoNodo); } } if (nuevoNodo && nodoHojaCorriente != *nuevoNodo && posicion == nodoHojaCorriente->keyMount - 1) { *clavePromocion = clave; } return true; } }