Esempio n. 1
0
int findElementHash(Key *key, Hash *hash)
{
  int index;
  Node *h;

  index = hashIndex(key, hash->size);

  h = hash->table[index];

  while( h!=NULL && !equalKey(&h->key,key) )
    h = h->next;

  if( h==NULL )
    return 0;

  return h->count;
}
Esempio n. 2
0
int setElementHash(Key *key, Hash *hash, int count)
{
  int index;
  Node *h,*p=NULL;

  index = hashIndex(key, hash->size);

  if( hash->table[index]==NULL )
    {
      if( (h = (Node*) mymalloc(sizeof(Node)))==NULL )
	{ fprintf(stderr, "Cannot allocate memory for new entry in hash table"); exit(2); }

      hash->table[index] = h;
      hash->total++;
      keyCopy(&(h->key),key);
      h->count = count;
      h->next = NULL;
      return count;
    }    

  h = hash->table[index];
  //assert(h);
  while( h!=NULL && !equalKey(&h->key, key))
    {
      p = h;
      h = h->next;
    }
  if(h == NULL)
    {
      if( (h = (Node*) mymalloc(sizeof(Node)))==NULL )
	{ fprintf(stderr, "Cannot allocate memory for new entry in hash table"); exit(2); }
      hash->total++;
      //assert(p);
      p->next = h;
      keyCopy(&(h->key),key);
      h->count = count;
      h->next = NULL;
      return count;
    }

  h->count = count;
  return h->count;
}
Esempio n. 3
0
pair<Record*, BPlusTreeIterator*> BPlusTree::search(Key k) {
	Node *aNode = root;
	if (!aNode)
		return pair<Record*, BPlusTreeIterator*> (NULL, NULL);

	while (!aNode->isLeaf()) {
		InnerNode *innerNode = static_cast<InnerNode*> (aNode);
		int position = getPosition(innerNode, k);
		aNode = hidratateNode(innerNode->sons[position]);
		if (innerNode != root)
			freeNodeMemory(innerNode);
	}
	LeafNode *leafNode = static_cast<LeafNode*> (aNode);
	Record* record = NULL;
	BPlusTreeIterator* iterator = NULL;
	int pos = getPosition(leafNode, k);
	if (pos < leafNode->keyMount && equalKey(k, leafNode->keys[pos])) {
		record = new Record(leafNode->keys[pos].Clone(), new ByteString(leafNode->byteData[pos]));
		iterator = new BPlusTreeIterator(leafNode->clone(), pos, fileBlockManager);
	}
	if (leafNode != root)
		freeNodeMemory(leafNode);
	return pair<Record*, BPlusTreeIterator*> (record, iterator);
}
Esempio n. 4
0
Result BPlusTree::recursiveRemove(Key clave, Node *nodoCorriente, Node *nodoIzquierda, Node *nodoDerecha,
		InnerNode *nodoPadreIzquierda, InnerNode *nodoPadreDerecha, InnerNode *nodoPadre, int posicionPadre) {

	if (nodoCorriente->isLeaf()) {

		LeafNode *nodoHojaCorriente = static_cast<LeafNode*> (nodoCorriente);
		LeafNode *nodoHojaIzquierda = static_cast<LeafNode*> (nodoIzquierda);
		LeafNode *nodoHojaDerecha = static_cast<LeafNode*> (nodoDerecha);
		int posicion = getPosition(nodoHojaCorriente, clave);
		if (posicion >= nodoHojaCorriente->keyMount || !equalKey(clave, nodoHojaCorriente->keys[posicion])) {
			return Result::NO_ENCONTRADO;
		}

		nodoHojaCorriente->occupiedSpace -= (nodoHojaCorriente->byteData[posicion].getSize() + nodoHojaCorriente->keys[posicion].getSize() + TreeConstraits::getControlSizeRecord());
		nodoHojaCorriente->keyMount--;
		for (int i = posicion; i < nodoHojaCorriente->keyMount; i++) {
			nodoHojaCorriente->keys[i] = nodoHojaCorriente->keys[i + 1];
			nodoHojaCorriente->byteData[i] = nodoHojaCorriente->byteData[i + 1];
		}

		Result resultado = Result::OK;

		// si se borro el elemento de la ultima posicion y no es la raiz
		if (posicion == nodoHojaCorriente->keyMount && nodoPadre) {
			if (posicionPadre < nodoPadre->keyMount) {
				if (nodoHojaCorriente->keyMount >= 1) {
					nodoPadre->occupiedSpace -= nodoPadre->keys[posicionPadre].getSize();
					nodoPadre->occupiedSpace += nodoHojaCorriente->keys[nodoHojaCorriente->keyMount - 1].getSize();
					nodoPadre->keys[posicionPadre] = nodoHojaCorriente->keys[nodoHojaCorriente->keyMount - 1];
				}
			} else {
				if (nodoHojaCorriente->keyMount >= 1) {
					resultado |= Result (Result::ACTUALIZAR_ULTIMA_CLAVE, nodoHojaCorriente->keys[nodoHojaCorriente->keyMount - 1]);
				} else {
					resultado |= Result (Result::ACTUALIZAR_ULTIMA_CLAVE, nodoHojaIzquierda->keys[nodoHojaIzquierda->keyMount - 1]);
				}
			}
		}

		if (nodoHojaCorriente->isUnderflow() && !(nodoHojaCorriente == root && nodoHojaCorriente->keyMount >= 1)) {

			if (nodoHojaIzquierda == NULL && nodoHojaDerecha == NULL) {
				persistNode(root);
				if (root)
					freeNodeMemory(root);
				root = nodoHojaCorriente = NULL;
				firstLeaf = 0;
				string archivoConfiguracion = fileBlockManager->getPath() + ".cnf";
				remove(archivoConfiguracion.c_str());
				return Result::OK;
			// @fusion
			} else if (( (nodoHojaIzquierda == NULL || !nodoHojaIzquierda->elementsCanTransfer())
						&& (nodoHojaDerecha == NULL	|| !nodoHojaDerecha->elementsCanTransfer()))
						|| nodoHojaCorriente->keyMount == 0) {

					if (nodoPadreIzquierda == nodoPadre) { //  cte e izq son hermanos.
						resultado |= leafNodeFusion(nodoHojaIzquierda, nodoHojaCorriente);
					}else {
						resultado |= leafNodeFusion(nodoHojaCorriente, nodoHojaDerecha);
					}
			// si la derecha mas cargada redistribuyo
			} else if ((nodoHojaIzquierda != NULL && !nodoHojaIzquierda->elementsCanTransfer())
						&& (nodoHojaDerecha != NULL	&& nodoHojaDerecha->elementsCanTransfer())) {

					if (nodoPadreDerecha == nodoPadre) {
						resultado |= redistributeLeftLeaf(nodoHojaCorriente, nodoHojaDerecha, nodoPadreDerecha, posicionPadre);
					} else {
						resultado |= leafNodeFusion(nodoHojaIzquierda, nodoHojaCorriente);
					}
			// si la izquierda mas cargada  redistribuyo
			} else	if ((nodoHojaIzquierda != NULL && nodoHojaIzquierda->elementsCanTransfer())
						&& (nodoHojaDerecha != NULL && !nodoHojaDerecha->elementsCanTransfer())) {

					if (nodoPadreIzquierda == nodoPadre) {
						redistributeRightLeaf(nodoHojaIzquierda, nodoHojaCorriente,	nodoPadreIzquierda, posicionPadre - 1);
					} else {
						resultado |= leafNodeFusion(nodoHojaCorriente, nodoHojaDerecha);
					}
			// izq cte y der son todos hermanos, me fijo cual tiene mas carga y redistribuyo
			} else	if (nodoPadreIzquierda == nodoPadreDerecha) {
					if (nodoHojaIzquierda->occupiedSpace <= nodoHojaDerecha->occupiedSpace) {
						resultado |= redistributeLeftLeaf(nodoHojaCorriente, nodoHojaDerecha, nodoPadreDerecha, posicionPadre);
					} else {
						redistributeRightLeaf(nodoHojaIzquierda, nodoHojaCorriente, nodoPadreIzquierda, posicionPadre - 1);
					}

			} else {
				if (nodoPadreIzquierda == nodoPadre) {
					redistributeRightLeaf(nodoHojaIzquierda, nodoHojaCorriente,	nodoPadreIzquierda, posicionPadre - 1);
				} else {
					resultado |= redistributeLeftLeaf(nodoHojaCorriente, nodoHojaDerecha, nodoPadreDerecha, posicionPadre);
				}
			}
		} else {
			persistNode(nodoHojaCorriente);
		}
		return resultado;

	} else {

		InnerNode *nodoInteriorCorriente = static_cast<InnerNode*> (nodoCorriente);
		InnerNode *nodoInteriorIzquierda = static_cast<InnerNode*> (nodoIzquierda);
		InnerNode *nodoInteriorDerecha = static_cast<InnerNode*> (nodoDerecha);
		Node *auxNodoIzquierda, *auxNodoDerecha;
		InnerNode *auxPadreIzquierda, *auxPadreDerecha;

		int posicion = getPosition(nodoInteriorCorriente, clave);
		if (posicion == 0) {
			auxNodoIzquierda = (nodoIzquierda == NULL) ? NULL : hidratateNode((static_cast<InnerNode*> (nodoIzquierda))->sons[nodoIzquierda->keyMount]);
			auxPadreIzquierda = nodoPadreIzquierda;
		} else {
			auxNodoIzquierda = hidratateNode(nodoInteriorCorriente->sons[posicion - 1]);
			auxPadreIzquierda = nodoInteriorCorriente;
		}

		if (posicion == nodoInteriorCorriente->keyMount) {
			auxNodoDerecha = (nodoDerecha == NULL) ? NULL : hidratateNode((static_cast<InnerNode*> (nodoDerecha))->sons[0]);
			auxPadreDerecha = nodoPadreDerecha;
		} else {
			auxNodoDerecha = hidratateNode(nodoInteriorCorriente->sons[posicion + 1]);
			auxPadreDerecha = nodoInteriorCorriente;
		}
//		if(clave.getKey().compare("438") == 0)
//			std::cout << "llamada recursiva: nodointeriorcorriente: " << nodoInteriorCorriente->number << "posicion: " << posicion << endl;
		Node* auxNodoCorriente = hidratateNode(nodoInteriorCorriente->sons[posicion]);
		Result resultadoParcial = recursiveRemove(clave, auxNodoCorriente, auxNodoIzquierda, auxNodoDerecha, auxPadreIzquierda, auxPadreDerecha, nodoInteriorCorriente, posicion);
		Result resultado = Result::OK;

		if (auxNodoIzquierda)
			freeNodeMemory(auxNodoIzquierda);
		if (auxNodoDerecha)
			freeNodeMemory(auxNodoDerecha);
		if (auxNodoCorriente)
			freeNodeMemory(auxNodoCorriente);

		if (resultadoParcial.contains(Result::NO_ENCONTRADO)) {
			return resultadoParcial;
		}

		if (resultadoParcial.contains(Result::ACTUALIZAR_ULTIMA_CLAVE)) {
			if (nodoPadre && posicionPadre < nodoPadre->keyMount) {
				nodoPadre->occupiedSpace -= nodoPadre->keys[posicionPadre].getSize();
				nodoPadre->occupiedSpace += resultadoParcial.ultimaClave.getSize();
				nodoPadre->keys[posicionPadre] = resultadoParcial.ultimaClave;
			} else {
				resultado |= Result(Result::ACTUALIZAR_ULTIMA_CLAVE, resultadoParcial.ultimaClave);
			}
		}

		if (resultadoParcial.contains(Result::FUSION_NODOS)) {
			Node* nodoHijo = hidratateNode(nodoInteriorCorriente->sons[posicion]);
			if (nodoHijo->keyMount != 0)
				posicion++;

			Key claveInteriorBorrada = nodoInteriorCorriente->keys[posicion - 1];
			for (int i = posicion; i < nodoInteriorCorriente->keyMount; i++) {
				nodoInteriorCorriente->keys[i - 1] = nodoInteriorCorriente->keys[i];
				nodoInteriorCorriente->sons[i] = nodoInteriorCorriente->sons[i + 1];
			}
			nodoInteriorCorriente->keyMount--;
			nodoInteriorCorriente->occupiedSpace -= (claveInteriorBorrada.getSize() + TreeConstraits::getControlSizeRecord());
			nodoInteriorCorriente->occupiedSpace -= nodoInteriorCorriente->keys[nodoInteriorCorriente->keyMount].getSize();

			if (nodoHijo)
				freeNodeMemory(nodoHijo);
			if (nodoInteriorCorriente->level == 1) {
				posicion--;
				nodoHijo = hidratateNode(nodoInteriorCorriente->sons[posicion]);
				nodoInteriorCorriente->occupiedSpace -= nodoInteriorCorriente->keys[posicion].getSize();
				nodoInteriorCorriente->occupiedSpace += nodoHijo->keys[nodoHijo->keyMount - 1].getSize();
				nodoInteriorCorriente->keys[posicion] = nodoHijo->keys[nodoHijo->keyMount - 1];
				if (nodoHijo)
					freeNodeMemory(nodoHijo);
			}
		}

		if (resultadoParcial.contains(Result::FUSION_NODOS)
				&& nodoInteriorCorriente->isUnderflow()
				&& !(nodoInteriorCorriente == root && nodoInteriorCorriente->keyMount >= 1)) {

			if (nodoInteriorIzquierda == NULL && nodoInteriorDerecha == NULL) {
				root = hidratateNode(nodoInteriorCorriente->sons[0]);
				root->number = 0;
				persistNode(root);
				freeNodes.push_back(nodoInteriorCorriente->sons[0]);
				serializeDataConfig();
				return Result::OK;

			} else if ((nodoInteriorIzquierda == NULL || !nodoInteriorIzquierda->elementsCanTransfer())
					&& (nodoInteriorDerecha == NULL || !nodoInteriorDerecha->elementsCanTransfer())) {

				if (nodoPadreIzquierda == nodoPadre) {
					resultado |= innerNodeFusion(nodoInteriorIzquierda, nodoInteriorCorriente, nodoPadreIzquierda, posicionPadre - 1);
				} else {
					resultado |= innerNodeFusion(nodoInteriorCorriente, nodoInteriorDerecha, nodoPadreDerecha, posicionPadre);
				}

			} else if ((nodoInteriorIzquierda != NULL && !nodoInteriorIzquierda->elementsCanTransfer())
					&& (nodoInteriorDerecha != NULL && nodoInteriorDerecha->elementsCanTransfer())) {

				if (nodoPadreDerecha == nodoPadre) {
					redistributeLeftInner(nodoInteriorCorriente, nodoInteriorDerecha, nodoPadreDerecha, posicionPadre);
				} else {
					resultado |= innerNodeFusion(nodoInteriorIzquierda, nodoInteriorCorriente, nodoPadreIzquierda, posicionPadre - 1);
				}

			} else if ((nodoInteriorIzquierda != NULL && nodoInteriorIzquierda->elementsCanTransfer())
					&& (nodoInteriorDerecha != NULL && !nodoInteriorDerecha->elementsCanTransfer())) {

				if (nodoPadreIzquierda == nodoPadre) {
					redistributeRightInner(nodoInteriorIzquierda, nodoInteriorCorriente, nodoPadreIzquierda, posicionPadre - 1);
				} else {
					resultado |= innerNodeFusion(nodoInteriorCorriente, nodoInteriorDerecha, nodoPadreDerecha, posicionPadre);
				}

			} else if (nodoPadreIzquierda == nodoPadreDerecha) {

				if (nodoInteriorIzquierda->keyMount <= nodoInteriorDerecha->keyMount) {
					redistributeLeftInner(nodoInteriorCorriente, nodoInteriorDerecha, nodoPadreDerecha, posicionPadre);
				} else {
					redistributeRightInner(nodoInteriorIzquierda, nodoInteriorCorriente, nodoPadreIzquierda, posicionPadre - 1);
				}

			} else {

				if (nodoPadreIzquierda == nodoPadre) {
					redistributeRightInner(nodoInteriorIzquierda, nodoInteriorCorriente, nodoPadreIzquierda, posicionPadre - 1);
				} else {
					redistributeLeftInner(nodoInteriorCorriente, nodoInteriorDerecha, nodoPadreDerecha, posicionPadre);
				}
			}

		} else {
			persistNode(nodoInteriorCorriente);
		}

		return resultado;
	}
}
Esempio n. 5
0
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;
	}
}