Example #1
0
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;
	}
}