// GoToNext status_t ItemIterator::GoToNext(Item *item) { //PRINT(("ItemIterator::GoToNext()\n")); LeafNode *node = NULL; status_t error = _GetLeafNode(&node); if (error == B_OK) { //PRINT((" leaf node: %Ld\n", node->GetNumber())); // get the leaf node on which the next item resides int32 newIndex = fIndex + 1; while (error == B_OK && newIndex >= node->CountItems()) { error = fTreeIterator.GoToNextLeaf(&node); newIndex = 0; } // got the node, get the item if (error == B_OK) { //PRINT((" leaf node now: %Ld\n", node->GetNumber())); fIndex = newIndex; //PRINT((" index now: %ld\n", fIndex)); if (item) error = item->SetTo(node, fIndex); } } //PRINT(("ItemIterator::GoToNext() done: %s\n", strerror(error))); return error; }
void InnerNode::add( Sortable *obj, int index ) { // this is called only from Btree::add() PRECONDITION( index >= 1 ); LeafNode* ln = getTree(index-1)->lastLeafNode(); ln->add( obj, ln->last+1 ); }
void Snapshoot::Build(const Database& db, const std::string& dir) { const std::vector<Node*>& nodes = db.GetNodes(); for (int i = 0, n = nodes.size(); i < n; ++i) { Node* node = nodes[i]; if (node->Type() != NODE_LEAF) { continue; } LeafNode* leaf = static_cast<LeafNode*>(node); const std::string& path = leaf->GetPath(); std::string out_path = dir + "\\" + path; out_path = out_path.substr(0, out_path.find_last_of(".")); out_path += "_ss.png"; std::string dir = gum::FilepathHelper::Dir(out_path); if (!wxDir::Exists(dir)) { wxFileName::Mkdir(dir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL); } s2::DrawRT rt; std::string ori_path = db.GetDirPath() + "\\" + path; auto sym = ee::SymbolMgr::Instance()->FetchSymbol(ori_path); rt.Draw(*sym); sm::vec2 sz = sym->GetBounding().Size(); rt.StoreToFile(out_path, sz.x, sz.y); } }
void InnerNode::remove( int index ) { PRECONDITION( index >= 1 && index <= last ); LeafNode* lf = getTree(index)->firstLeafNode(); setKey( index, lf->item[0] ); lf->removeItem(0); }
BPlusTreeIterator* BPlusTree::begin() { BPlusTreeIterator* iterator = NULL; LeafNode* leaf = static_cast <LeafNode*> (hidratateNode(firstLeaf)); if (leaf) { iterator = new BPlusTreeIterator(leaf->clone(), 0, fileBlockManager); freeNodeMemory(leaf); } return iterator; }
void LeafNode::merge(Slice anchor) { if (balancing_) { unlock(); return; } balancing_ = true; assert(records_.size() == 0); // release the write lock unlock(); // acquire write locks from root to leaf vector<DataNode*> path; tree_->lock_path(anchor, path); assert(path.back() == this); // may have insertions during this period if (records_.size() > 0) { while (path.size()) { path.back()->unlock(); path.back()->dec_ref(); path.pop_back(); } return; } if (left_sibling_ >= NID_LEAF_START) { LeafNode *ll = (LeafNode*)tree_->load_node(left_sibling_, false); assert(ll); ll->write_lock(); ll->right_sibling_ = right_sibling_; ll->set_dirty(true); ll->unlock(); ll->dec_ref(); } if (right_sibling_ >= NID_LEAF_START) { LeafNode *rl = (LeafNode*)tree_->load_node(right_sibling_, false); assert(rl); rl->write_lock(); rl->left_sibling_ = left_sibling_; rl->set_dirty(true); rl->unlock(); rl->dec_ref(); } dead_ = true; balancing_ = false; path.pop_back(); unlock(); dec_ref(); // propagation InnerNode *parent = (InnerNode*) path.back(); assert(parent); parent->rm_pivot(nid_, path); }
// GetCurrent status_t ItemIterator::GetCurrent(Item *item) { LeafNode *node = NULL; status_t error = (item ? _GetLeafNode(&node) : B_BAD_VALUE); if (error == B_OK) { if (fIndex >= 0 && fIndex < node->CountItems()) error = item->SetTo(node, fIndex); else error = B_ENTRY_NOT_FOUND; } return error; }
template<typename PointT, typename LeafContainerT, typename BranchContainerT> void pcl::octree::OctreePointCloudVoxelCentroid<PointT, LeafContainerT, BranchContainerT>::getVoxelCentroidsRecursive ( const BranchNode* branch_arg, OctreeKey& key_arg, typename OctreePointCloud<PointT, LeafContainerT, BranchContainerT>::AlignedPointTVector &voxel_centroid_list_arg) const { // child iterator unsigned char child_idx; // iterate over all children for (child_idx = 0; child_idx < 8; child_idx++) { // if child exist if (branch_arg->hasChild (child_idx)) { // add current branch voxel to key key_arg.pushBranch (child_idx); OctreeNode *child_node = branch_arg->getChildPtr (child_idx); switch (child_node->getNodeType ()) { case BRANCH_NODE: { // recursively proceed with indexed child branch getVoxelCentroidsRecursive (static_cast<const BranchNode*> (child_node), key_arg, voxel_centroid_list_arg); break; } case LEAF_NODE: { PointT new_centroid; LeafNode* container = static_cast<LeafNode*> (child_node); container->getContainer().getCentroid (new_centroid); voxel_centroid_list_arg.push_back (new_centroid); break; } default: break; } // pop current branch voxel from key key_arg.popBranch (); } } }
Node* BPlusTree::hidratateNode(int numeroDeNodo) { ByteString byteStr = this->fileBlockManager->readBlock(numeroDeNodo); if (byteStr.isEmpty()) { return NULL; } else { int nivel = byteStr.readAsInt(0); if (nivel == 0) { LeafNode *nuevoNodoHoja = createLeafNode(); nuevoNodoHoja->Hidratate(byteStr); nuevoNodoHoja->number = numeroDeNodo; return nuevoNodoHoja; } else { InnerNode *nuevoNodoInterior = createInnerNode(nivel); nuevoNodoInterior->Hidratate(byteStr); nuevoNodoInterior->number = numeroDeNodo; return nuevoNodoInterior; } } }
const char* BomKeyNode::printRef(MapNode *pNode) { BomItem *tmp; LeafNode *lf; tmp = mHead; while(tmp != NULL) { if(AcontainsB(tmp->node, pNode) == 1) { //printf("REF: %c%d%02d\n", tmp->refChar, mMajor, tmp->idNum); if(pNode->nodeType() == 1) { lf = (LeafNode*)pNode; sprintf(mTmpRef,"%c%d%02d-%s ", tmp->refChar, mMajor, tmp->idNum,lf->value()); } else { sprintf(mTmpRef, "%c%d%02d-? ", tmp->refChar, mMajor, tmp->idNum); } return mTmpRef; } tmp = tmp->next; } strcpy(mTmpRef, "NODE_NOT_FOUND"); return mTmpRef; }
Node* ClassifBPlusTree::hidratateNode(int nodeNumber) { int block = fileBlockNodeMapper->getBlock(nodeNumber); ByteString byteStr = this->fileBlockManager->readBlock(block); if (byteStr.isEmpty()) { return NULL; } else { int nivel = byteStr.readAsInt(0); if (nivel == 0) { LeafNode *nuevoNodoHoja = createLeafNode(); nuevoNodoHoja->Hidratate(byteStr); nuevoNodoHoja->number = nodeNumber; return nuevoNodoHoja; } else { InnerNode *nuevoNodoInterior = createInnerNode(nivel); nuevoNodoInterior->Hidratate(byteStr); nuevoNodoInterior->number = nodeNumber; return nuevoNodoInterior; } } }
virtual void processNode(LeafNode &u) // DO NOT CHANGE THIS FUNCTION { int id=u.getID(); Symbol a=A.getIthTrack(id)[column]; Array2D<double>::RowIn2DArray<double> row=L[id]; if(gapSymbols.isMember(a)) for(Symbol i=0 ; i<numAlpha; ++i) row[i]=0; //=log(1); missing data -- same as Seipel & Haussler else for(Symbol i=0 ; i<numAlpha; ++i) row[i]=(i==a ? 0 : NEGATIVE_INFINITY); }
virtual void processNode(LeafNode &u) { int id=u.getID(); Symbol a=alphabetMap(A.getIthTrack(id)[column]); Array2D<double>::RowIn2DArray<double> row=L[id]; if(a==gap) for(Symbol i=0 ; i<numAlpha; ++i) row[i]=log1;// missing data -- same as Seipel & Haussler else for(Symbol i=0 ; i<numAlpha; ++i) row[i]=(i==a ? log1 : log0); }
// GoToPrevious status_t ItemIterator::GoToPrevious(Item *item) { LeafNode *node = NULL; status_t error = _GetLeafNode(&node); if (error == B_OK) { // get the leaf node on which the next item resides int32 newIndex = fIndex - 1; while (error == B_OK && (newIndex < 0 || newIndex >= node->CountItems())) { error = fTreeIterator.GoToPreviousLeaf(&node); if (error == B_OK) newIndex = node->CountItems() - 1; } // got the node, get the item if (error == B_OK) { fIndex = newIndex; if (item) error = item->SetTo(node, fIndex); } } return error; }
LeafNode* LeafNode::split(int value) { int last, i; if (value > values[count - 1]) last = value; else { last = values[count - 1]; for (i = count - 2; i >= 0 && values[i] > value; i--) values[i + 1] = values[i]; values[i + 1] = value; } LeafNode *newNode = new LeafNode(leafSize, parent, this, rightSibling); if(rightSibling) rightSibling->setLeftSibling(newNode); rightSibling = newNode; for (i = (leafSize + 1) / 2; i < leafSize; i++) newNode->insert(values[i]); count = (leafSize + 1 ) / 2; newNode->insert(last); return newNode; } // split()
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); }
virtual void processNode(LeafNode &u) { int id=u.getID(); Array2D<double>::RowIn2DArray<double> row=L[id]; Sequence &track=A.getIthTrack(id).getSeq(); Sequence leafNmer, nmer; track.getSubsequence(firstCol,numCols,leafNmer); if(MultSeqAlignment::rightmostGapPos(leafNmer,gapSymbols)>=0) for(int i=0 ; i<numNmers ; ++i) { nmer.fromInt(i,numCols,alphabetMap); row[i]= degenerateDnaMatch(nmer,leafNmer,gapSymbols) ? 0 : NEGATIVE_INFINITY; } else { row.setAllTo(NEGATIVE_INFINITY); int index=leafNmer.asInt(alphabetMap); row[index]=0; } }
void LeafNode::splitNode(FatherNode* parentNode, int childIndex) { LeafNode* newNode = new LeafNode(); setKeyNum(MIN_LEAF); newNode->setKeyNum(MIN_LEAF + 1); newNode->setRightSibling(getRightSibling()); setRightSibling(newNode); newNode->setLeftSibling(this); int i; for (i = 0; i < MIN_LEAF + 1; ++i) { newNode->setKeyValue(i, m_KeyValues[i + MIN_LEAF]); } for (i = 0; i < MIN_LEAF + 1; ++i) { newNode->setData(i, m_Datas[i + MIN_LEAF]); } ((InternalNode*)parentNode)->insert(childIndex, childIndex + 1, m_KeyValues[MIN_LEAF], newNode); }
LeafNode* LeafNode::remove(int value) { int pos = 0; // int q; for(pos = 0; pos < count; pos++) { if(values[pos] == value) { for(int i = pos; i < count; i++) { values[i] = values[i + 1]; } count--; break; } if(values[pos] > value) break; } if(count < ((leafSize+1)/2)) { int transfer; // BTreeNode *ptr2; LeafNode *ptr; int check = 0; int siblingCount, i; //int count1; //Checks left sibling // if(count == 0) // return this; if(leftSibling != NULL) { //cout << "left pass \n"; if((siblingCount = leftSibling->getCount()) > ((leafSize+1)/ 2)) { //borrow from left //cout << "problem left 1\n"; ptr = static_cast<LeafNode*>(leftSibling); transfer = ptr->borrowLeft(); this->insert(transfer); } else {//merge with left //cout << "problem left 2 \n"; ptr = static_cast<LeafNode*>(leftSibling); //cout << "ptr pass \n"; if(ptr->getLeftSibling() != NULL) { this->setLeftSibling(ptr->getLeftSibling());//Set new Sibling leftSibling->setRightSibling(this); } else { this->setLeftSibling(NULL); } ptr->setRightSibling(NULL); ptr->setLeftSibling(NULL); for(i = 0; i < count; i++) { //cout << "seg1\n"; values[i + ptr->getCount()] = values[i]; } for(i = ptr->getCount() - 1; i > -1; i--) { //cout << "seg2\n"; values[i] = ptr->values[i]; count++; } return ptr; } check = 1; }//Left Sibling if((check == 0) && (rightSibling != NULL)) {//borrow from right if(rightSibling->getCount() > ((leafSize+1)/ 2)) { ptr = static_cast<LeafNode*>(rightSibling);//borrow transfer = ptr->borrowRight(); values[count] = transfer; count++; } else { ptr = static_cast<LeafNode*>(rightSibling);//merge with right if(ptr->getRightSibling() != NULL) { this->setRightSibling(ptr->getRightSibling()); rightSibling->setLeftSibling(this); } else { this->setRightSibling(NULL); } ptr->setLeftSibling(NULL); ptr->setRightSibling(NULL); for(i = 0; i < ptr->getCount(); i++) { values[count] = ptr->values[i]; count++; } return ptr;//returns merged } check = 1; //cout << "right\n\n"; }//Right Sibling //cout << "seg\n"; }//If not in size reqs //cout << "no action\n"; if((count == 0) && (parent == NULL)) return NULL; if(count == 0) return this; return NULL; // filler for stub } // LeafNode::remove()
LeafNode* LeafNode::split(int value){ //print old node //cout << "PRINTING OLD NODE" << endl; //cout << "COUNT: " << count << endl; //for(int i = 0; i < count; i++){ // cout << values[i] << " "; //} //cout << endl; //cout << "LeafNode:split" << endl; //creat a new leafNode to the right, will automatically attach as sibling LeafNode* newNode = new LeafNode(leafSize, parent, this, NULL); //need to insert this new node between this node and potential rightSibling BTreeNode* oldRightNode = getRightSibling(); if(oldRightNode){ // if there is a right sibling prior to split //cout << "Leafnode:split: there is a right sibling prior to split" << endl; //cout << "oldRight has min: " << oldRightNode->getMinimum() << endl; //cout << "newNodes left has min: " << getMinimum() << endl; oldRightNode->setLeftSibling(newNode); //set the right sibling to this new node in middle newNode->setRightSibling(oldRightNode); //set new nodes right to the right sibling of this newNode->setLeftSibling(this); // maybe not needed since constructor has this } //cout << "leafSize % 2 = " << leafSize % 2 << endl; //cout << "Value: " << value << " values[" << leafSize/2 << "]: " << values[leafSize/2] << endl; //simpler insert, if breaks, use doomsday comment below to fix for(int i = ((leafSize+1) / 2); i < leafSize; i++){ //cout << "Leaf Split: inserting (top half)" << values[i] << " into newNode" << endl; newNode->insert(values[i]); } count = count - newNode->getCount(); if(values[0] > value){ //cout << "first if" << endl; newNode->insert(values[0]); values[0] = value; } else if(values[(((leafSize+1)/2)-1)] > value){ //cout << " else if " << endl; newNode->insert(values[(((leafSize+1)/2)-1)]); values[(((leafSize+1)/2)-1)] = value; sort(); parent->updateMinimums(); parent->sort(); } else{ //cout << "Leaf Split: inserting (else)" << value << " into newNode" << endl; if(newNode->parent){ newNode->parent->updateMinimums(); newNode->parent->sort(); //cout << "Has parent with min: " << newNode->parent->getMinimum() << endl; } newNode->insert(value); } setRightSibling(newNode); //newNode->values[newNode->count++] = last; //if(value == values[0] && parent) // parent->updateMinimums(); return newNode; // FOLLOWING COMMENT MIGHT BREAK EVERYTHING /* //if leaf is odd, and new value will be inserted into old, and mid to last will go into new if((leafSize % 2 == 1) && value < values[(leafSize-1)]){ //cout << "odd: New value inserted into old" << endl; for(int i = count/2; i < leafSize; i++){ newNode->insert(values[i]); } count = count - newNode->getCount(); insert(value); //rightSibling = newNode; setRightSibling(newNode); } //if leaf is odd, and new value will be inserted into new if((leafSize % 2 == 1) && value > values[leafSize-1]){ //cout << "odd: New value inserted into new" << endl; for(int i = (count/2)+1; i < leafSize; i++){ //cout << "Inserting " << values[i] << " into new" << endl; newNode->insert(values[i]); } count = count - newNode->getCount(); newNode->insert(value); //rightSibling = newNode; setRightSibling(newNode); } //if leaf is even, and new value will be insterted into old, and mid to last will go into new if((leafSize%2 == 0) && value < values[leafSize-1]){ cout << "even: New value " << value << " inserted into old" << endl; //cout << value << " < " << values[leafSize/2] << endl; //cout << "Count/2: " << count/2 << endl; for(int i = count/2; i < leafSize; i++){ //cout << "Insering " << values[i] << " into new" << endl; newNode->insert(values[i]); } //if leaf is size 2, has 2 in it, and insert value is less than mid, then all transfer [0] and [1] over if(leafSize == 2){ //cout << "Inserting " << values[0] << " into new as well" << endl; newNode->insert(values[0]); } count = count - newNode->getCount(); insert(value); rightSibling = newNode; setRightSibling(newNode); } //if leaf is even, and new value will be insterted into new if((leafSize%2 == 0) && value > values[leafSize-1]){ //cout << "even: New value inserted into new" << endl; //cout << value << " < " << values[leafSize/2] << endl; if(leafSize!=2){ for(int i = (count/2); i < leafSize; i++){ // cout << "Inserting " << values[i] << " into new" << endl; newNode->insert(values[i]); } } else{ //leafSize is equal to 2, so insert value + element[1] into new //cout << "LeafNode:split: Inserting " << values[1] << " into new" << endl; newNode->insert(values[1]); values[1] = 0; //newNode->insert(value; } //cout << "Inserted " << newNode->getCount() << " into new, so subtracting from count" << endl; count = count - newNode->getCount(); newNode->insert(value); //rightSibling = newNode; setRightSibling(newNode); } */ //ABOVE IS DOOMSDAY COMMENT THAT MIGHT BREAK EVERYTHING //print old node //cout << "PRINTING OLD NODE" << endl; //cout << "OLD NODE HAS COUNT: " << count << endl; //for(int i = 0; i < count; i++){ // cout << values[i] << " "; // } //cout << endl; //print new node //cout << "PRINTING NEW NODE" << endl; //cout << "NEW NODE HAS COUNT: " << newNode->getCount() << endl; //for(int i = 0; i < newNode->getCount(); i++){ // cout << newNode->values[i] << " "; //} //cout << endl; return newNode; }
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; } }
void InnerNode::isFull(Node *that) { // the child node THAT is full. We will either redistribute elements // or create a new node and then redistribute. // In an attempt to minimize the number of splits, we adopt the following // strategy: // * redistribute if possible // * if not possible, then split with a sibling if( that->isLeaf ) { LeafNode *leaf = (LeafNode *)that; LeafNode *left, *right; // split LEAF only if both sibling nodes are full. int leafidx = indexOf(leaf); int hasRightSib = (leafidx < last) && ((right=(LeafNode*)getTree(leafidx+1)) != 0); int hasLeftSib = (leafidx > 0) && ((left=(LeafNode*)getTree(leafidx-1)) != 0); int rightSibFull = (hasRightSib && right->isAlmostFull()); int leftSibFull = (hasLeftSib && left->isAlmostFull()); if( rightSibFull ) { if( leftSibFull ) { // both full, so pick one to split with left->splitWith( leaf, leafidx ); } else if( hasLeftSib ) { // left sib not full, so balance with it leaf->balanceWithLeft( left, leafidx ); } else { // there is no left sibling, so split with right leaf->splitWith( right, leafidx+1 ); } } else if( hasRightSib ) { // right sib not full, so balance with it leaf->balanceWithRight( right, leafidx+1 ); } else if( leftSibFull ) { // no right sib, and left sib is full, so split with it left->splitWith( leaf, leafidx ); } else if( hasLeftSib ) { // left sib not full so balance with it leaf->balanceWithLeft( left, leafidx ); } else { // neither a left or right sib; should never happen CHECK(0); } } else { InnerNode *inner = (InnerNode *)that; // split INNER only if both sibling nodes are full. int inneridx = indexOf(inner); InnerNode *left, *right; int hasRightSib = (inneridx < last) && ((right=(InnerNode*)getTree(inneridx+1)) != 0); int hasLeftSib = (inneridx > 0) && ((left=(InnerNode*)getTree(inneridx-1)) != 0); int rightSibFull = (hasRightSib && right->isAlmostFull()); int leftSibFull = (hasLeftSib && left->isAlmostFull()); if( rightSibFull ) { if( leftSibFull ) { left->splitWith( inner, inneridx ); } else if( hasLeftSib ) { inner->balanceWithLeft( left, inneridx ); } else { // there is no left sibling inner->splitWith(right, inneridx+1); } } else if( hasRightSib ) { inner->balanceWithRight( right, inneridx+1 ); } else if( leftSibFull ) { left->splitWith( inner, inneridx ); } else if( hasLeftSib ) { inner->balanceWithLeft( left, inneridx ); } else { CHECK(0); } } }
void InnerNode::isLow( Node *that ) { // the child node THAT is <= half full. We will either redistribute // elements between children, or THAT will be merged with another child. // In an attempt to minimize the number of mergers, we adopt the following // strategy: // * redistribute if possible // * if not possible, then merge with a sibling if( that->isLeaf ) { LeafNode *leaf = (LeafNode *)that; LeafNode *left, *right; // split LEAF only if both sibling nodes are full. int leafidx = indexOf(leaf); int hasRightSib = (leafidx < last) && ((right=(LeafNode*)getTree(leafidx+1)) != 0); int hasLeftSib = (leafidx > 0) && ((left=(LeafNode*)getTree(leafidx-1)) != 0); if( hasRightSib && (leaf->Psize() + right->Vsize()) >= leaf->maxPsize()) { // then cannot merge, // and balancing this and rightsib will leave them both // more than half full leaf->balanceWith( right, leafidx+1 ); } else if( hasLeftSib && (leaf->Vsize() + left->Psize()) >= leaf->maxPsize()) { // ditto left->balanceWith( leaf, leafidx ); } else if( hasLeftSib ) { // then they should be merged left->mergeWithRight( leaf, leafidx ); } else if( hasRightSib ) { leaf->mergeWithRight( right, leafidx+1 ); } else { CHECK(0); // should never happen } } else { InnerNode *inner = (InnerNode *)that; // int inneridx = indexOf(inner); InnerNode *left, *right; int hasRightSib = (inneridx < last) && ((right=(InnerNode*)getTree(inneridx+1)) != 0); int hasLeftSib = (inneridx > 0) && ((left=(InnerNode*)getTree(inneridx-1)) != 0); if( hasRightSib && (inner->Psize() + right->Vsize()) >= inner->maxPsize()) { // cannot merge inner->balanceWith( right, inneridx+1 ); } else if( hasLeftSib && (inner->Vsize() + left->Psize()) >= inner->maxPsize()) { // cannot merge left->balanceWith( inner, inneridx ); } else if( hasLeftSib ) { left->mergeWithRight( inner, inneridx ); } else if( hasRightSib ) { inner->mergeWithRight( right, inneridx+1 ); } else { CHECK(0); } } }
LeafNode* LeafNode::insert(int value) { //Returns null unless action is required on the part of the parent, in which case it returns the new node which needs a home #ifdef DEBUG cout << "Inserting " << value << " into leaf @ " << this << ": "; #endif //Insert into this node if (count < leafSize) { #ifdef DEBUG cout << "Have found room in this node, inserting into values[]:\n"; #endif insertValue(value); if (parent) { parent->updateMinimums(); } return NULL; } //Insert into sibling node else if ( ((rightSibling) && (rightSibling->getCount() < leafSize)) || ((leftSibling) && (leftSibling->getCount() < leafSize)) ) { //Check right sibling then left sibling //so the end result here is that value now contains the value to be sent to the new node. if ((leftSibling) && (leftSibling->getCount() < leafSize)) { #ifdef DEBUG cout << " Going left "; #endif //decide which value is getting kicked out value = arrangeLarger(value, false); leftSibling->insert(value); } //kick it out else { // ((rightSibling) && (rightSibling->getCount() < leafSize)) { #ifdef DEBUG cout << " Going right "; #endif //decide which value is getting kicked out value = arrangeLarger(value, true); rightSibling->insert(value); } if (parent) { parent->updateMinimums(); } return NULL; } //Insert into else { //We cannot find space and must split #ifdef DEBUG cout << "Need to make a new leaf node: "; #endif //Decide which to kick out and rearrange data array value = arrangeLarger(value, true); //Create new node LeafNode* newnode = new LeafNode(leafSize, parent, this, rightSibling); //Make new node, considerations at ¹. Has only changed parameters of newnode. #ifdef FINALDEBUG cout << "New child LeafNode: " << newnode << endl; #endif if (rightSibling) { //If we have a right sibling rightSibling->setLeftSibling(newnode); //Set the left sibling of our soon-to-be-former right sibling to the new node } this->rightSibling = newnode; //Copy stuff to new node newnode->insert(value); //rightSibling.insert(value) should be an equivalent call for (int pos=leafSize-1; pos>((leafSize/2)-1+(leafSize%2)); --pos) { #ifdef DEBUG cout << "Inserting " << values[pos] << endl; #endif newnode->insert(values[pos]); values[pos] = 0; //² --count; } if (parent) { parent->updateMinimums(); } return newnode; } } // LeafNode::insert()
void LeafNode::split(Slice anchor) { if (balancing_) { unlock(); return; } balancing_ = true; assert(records_.size() > 1); // release the write lock unlock(); // need to search from root to leaf again // since the path may be modified vector<DataNode*> path; tree_->lock_path(anchor, path); assert(path.back() == this); // may have deletions during this period if (records_.size() <= 1 || (records_.size() <= (tree_->options_.leaf_node_record_count / 2) && size() <= (tree_->options_.leaf_node_page_size / 2) )) { while (path.size()) { path.back()->unlock(); path.back()->dec_ref(); path.pop_back(); } return; } // create new leaf LeafNode *nl = tree_->new_leaf_node(); assert(nl); // set siblings nl->left_sibling_ = nid_; nl->right_sibling_ = right_sibling_; if(right_sibling_ >= NID_LEAF_START) { LeafNode *rl = (LeafNode*)tree_->load_node(right_sibling_, false); assert(rl); rl->write_lock(); rl->left_sibling_ = nl->nid_; rl->set_dirty(true); rl->unlock(); rl->dec_ref(); } right_sibling_ = nl->nid_; Slice k = records_.split(nl->records_); refresh_buckets_info(); nl->refresh_buckets_info(); set_dirty(true); nl->set_dirty(true); nl->dec_ref(); balancing_ = false; path.pop_back(); unlock(); dec_ref(); // propagation InnerNode *parent = (InnerNode*) path.back(); assert(parent); parent->add_pivot(k, nl->nid_, path); }
virtual void processNode(LeafNode &V) { int id=V.getID(); if(id>largestID) largestID=id; ++numNodes; }
void processNode(LeafNode &v) { Taxon &taxon=*static_cast<Taxon*>(v.getDecoration()); cout<<" LLL "<<taxon.getName()<<"="<<taxon.getSeqLen()<<endl; }