예제 #1
0
// 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 );
}
예제 #3
0
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);
}
예제 #5
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;
}
예제 #6
0
파일: node.cpp 프로젝트: jameswei/cascadb
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);
}
예제 #7
0
// 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 ();
    }
  }
}
예제 #9
0
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;
		}
	}
}
예제 #10
0
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;
		}
	}
}
예제 #12
0
  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);
  }
예제 #13
0
  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);
  }
예제 #14
0
// 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;
}
예제 #15
0
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()
예제 #16
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);
}
예제 #17
0
  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;
    }
  }
예제 #18
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);
}
예제 #19
0
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;
}
예제 #21
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;
	}
}
예제 #22
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;
	}
}
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);
            }
        }
}
예제 #25
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()
예제 #26
0
파일: node.cpp 프로젝트: jameswei/cascadb
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);
}
예제 #27
0
 virtual void processNode(LeafNode &V) 
     {
         int id=V.getID();
         if(id>largestID) largestID=id;
         ++numNodes;
     }
예제 #28
0
 void processNode(LeafNode &v) {
   Taxon &taxon=*static_cast<Taxon*>(v.getDecoration());
   cout<<"  LLL "<<taxon.getName()<<"="<<taxon.getSeqLen()<<endl;
 }