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; }
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; }
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); }
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; } }
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; } }