Node2 &KRadix2::createNode(Node2& node, KStringUnicode key) { int curPos = 0; for(Node2& n : node.childNodes) { // Find matching node if(n.key[curPos] != key[curPos]) { continue; } for(int j = 1; ; j++){ if(key[j] == nullUnicode && n.key[j] == nullUnicode) { return n; // key already exists } if(key[j] == nullUnicode) { return splitNode(n, j); // key smaller than node, split node } if(n.key[j] == nullUnicode) { return createNode(n, key.mid(j)); // go to child nodes } if(key[j] != n.key[j]) { return addNode(splitNode(n, j), key.mid(j)); // key diverging from node, split node } } curPos++; } return addNode(node, std::move(key)); }
// recursively split BVH node void Bvh::splitNode( Bvh_Node* node , unsigned _start , unsigned _end , unsigned depth ) { m_totalNode ++; m_bvhDepth = max( depth , m_bvhDepth ); // generate the bounding box for the node for( unsigned i = _start ; i < _end ; i++ ) node->bbox.Union( m_bvhpri[i].GetBBox() ); unsigned tri_num = _end - _start; if( tri_num <= m_maxPriInLeaf ){ makeLeaf( node , _start , _end ); return; } // pick best split plane unsigned split_axis; float split_pos; float sah = pickBestSplit( split_axis , split_pos , node , _start , _end ); if( sah >= tri_num ){ makeLeaf( node , _start , _end ); return; } // partition the data auto compare = [split_pos,split_axis](const Bvh::Bvh_Primitive& pri){return pri.m_centroid[split_axis] < split_pos;}; const Bvh_Primitive* middle = partition( &m_bvhpri[_start] , &m_bvhpri[_end-1]+1 , compare ); unsigned mid = middle - m_bvhpri; node->left = new Bvh_Node(); splitNode( node->left , _start , mid , depth + 1 ); node->right = new Bvh_Node(); splitNode( node->right , mid , _end , depth + 1 ); }
void XMLParser::parseNode(IEntity *entity,QDomNode *node) { while(!node->isNull()) { QString namesp; QString name; IEntity *auxent = NULL; QDomElement child = node->toElement(); if(!child.isNull()) { #ifdef PARSER_DEBUG qDebug() << child.tagName(); #endif splitNode(child.tagName(),namesp,name); if(name.isEmpty()) throw new XMLParserException("Unable to parse node\n"); auxent = new IEntity(namesp,name); } if(node->hasAttributes()) { QDomNamedNodeMap attributes = node->attributes(); for(unsigned int i=0; i<=attributes.length(); i++) { QDomNode n = attributes.item(i); if(n.isAttr()) { #ifdef PARSER_DEBUG qDebug() << n.toAttr().name()<< "=" << n.toAttr().value(); #endif QString attnamesp; QString attname; splitNode(n.toAttr().name(),attnamesp,attname); //TODO: add attribute with namespace auxent->addAttribute(attname,n.toAttr().value()); } } } if(node->isText()) { #ifdef PARSER_DEBUG qDebug() << node->toText().data(); #endif entity->addValue(node->toText().data()); } else entity->addEntity(auxent); if (node->hasChildNodes()) parseNode(auxent,&node->firstChild()); node = &(node->nextSibling()); } }
IEntity* XMLParser::parse(QByteArray buff,int size) { IEntity *ent = NULL; if ((buff.isNull()) || (size == 0)) return ent; QDomDocument domDocument; if(domDocument.setContent(buff)) { QDomElement root = domDocument.documentElement(); QString namesp; QString name; splitNode(root.tagName(),namesp,name); if(!name.isEmpty()) ent = new IEntity(namesp,name); #ifdef PARSER_DEBUG qDebug() << root.tagName(); #endif QDomNode node = root.firstChild(); parseNode(ent,&node); } #ifdef QTREST_DEBUG if(ent!=NULL) qDebug() << ent->toString(); #endif return ent; }
/*------------------------------------------------------------------*/ bool AzRgforest::growForest() { clock_t b_time; time_begin(&b_time); /*--- find the best split ---*/ AzTrTsplit best_split; searchBestSplit(&best_split); if (shouldExit(&best_split)) { /* exit if no more split */ return true; /* exit */ } /*--- split the node ---*/ double w_inc; int leaf_nx[2] = {-1,-1}; const AzRgfTree *tree = splitNode(&best_split, &w_inc, leaf_nx); if (lmax_timer.reachedMax(l_num, "AzRgforest: #leaf", out)) { return true; /* #leaf reached max; exit */ } /*--- update target ---*/ updateTarget(tree, leaf_nx, w_inc); time_end(b_time, &search_time); return false; /* don't exit */ }
int setValueInNode(long long int val, long long int *pval, struct btreeNode *node, struct btreeNode **child) { int pos; if (!node) { *pval = val; *child = NULL; return 1; } if (val < node->val[1]) { pos = 0; } else { for (pos = node->count; (val < node->val[pos] && pos > 1); pos--); if (val == node->val[pos]) { //printf("Duplicates not allowed\n"); return 0; } } if (setValueInNode(val, pval, node->link[pos], child)) { if (node->count < MAX) { addValToNode(*pval, pos, node, *child); } else { splitNode(*pval, pval, pos, node, *child, child); return 1; } } return 0; }
void KDTree::createTree(const AxisAlignedBox& initialBounds, const KDTriList& sourceTri) { mNodes.clear(); mNodes.reserve(sourceTri.size() / MIN_KDTREE_TRIANGLES); mTriangles.clear(); mTriangles.reserve(sourceTri.size()); splitNode(createNode(initialBounds), sourceTri, 0); }
void Btree::insert(const string &key, long value) { shared_ptr<BtreeNode> node = findNode(key); Assert(node != NULL); bool rslt = node->insert(key, value); if (!rslt) { node = splitNode(node, key); Assert(node == NULL); rslt = node->insert(key, value); Assert(rslt); } }
// moreSeq -- check remaining sequence of node Node* moreSeq(Node* n, Node* par, int ch, int pos, int len) { int i; for (i = 1; i < n->end - n->st; i++) { // read is short if (pos + i == len) { return splitNode(n, par, ch, i); //return n; } // mismatch at position i if (line[pos + i] != n->seq[n->st + i]) { Node* m = splitNode(n, par, ch, i); return makeNode(m, 1, pos + i, len - pos - i); } } // recurse on child node return checkNode(n, pos + i, len); }
void KDTree::splitNode(int nodeIndex, const KDTriList& sourceTri, int level) { AxisAlignedBox triBox; KDTriList myTriangles; for(KDTriList::const_iterator iTriangle = sourceTri.begin(); iTriangle != sourceTri.end(); ++iTriangle) { KDTriangle triangle = *iTriangle; triBox.clear(); triBox.addPoint(triangle.vert0); triBox.addPoint(triangle.vert0 + triangle.edge1); triBox.addPoint(triangle.vert0 + triangle.edge2); if(mNodes[nodeIndex].mBounds.intersect(triBox)) myTriangles.push_back(triangle); } // Split ends here if(myTriangles.size() < MIN_KDTREE_TRIANGLES || level == MAX_KDTREE_LEVEL) { for(int iChild = 0; iChild < KDTREE_CHILDREN; ++iChild) mNodes[nodeIndex].mChildren[iChild] = 0; mNodes[nodeIndex].mTriStart = mTriangles.size(); mNodes[nodeIndex].mTriNum = myTriangles.size(); mTriangles.resize(mTriangles.size() + myTriangles.size()); mTriangles.insert(mTriangles.begin() + mNodes[nodeIndex].mTriStart, myTriangles.begin(), myTriangles.end()); } // No triangles stored, split children instead else { for(int iChild = 0; iChild < KDTREE_CHILDREN; ++iChild) { AxisAlignedBox childBounds; int splitDimension = level % 3; for(int iDimension = 0; iDimension < 3; ++iDimension) { if(iDimension == splitDimension) { if(iChild & 0x1) { childBounds.minPoint[iDimension] = mNodes[nodeIndex].mBounds.minPoint[iDimension]; childBounds.maxPoint[iDimension] = (mNodes[nodeIndex].mBounds.minPoint[iDimension] + mNodes[nodeIndex].mBounds.maxPoint[iDimension]) * 0.5f; } else { childBounds.minPoint[iDimension] = (mNodes[nodeIndex].mBounds.minPoint[iDimension] + mNodes[nodeIndex].mBounds.maxPoint[iDimension]) * 0.5f; childBounds.maxPoint[iDimension] = mNodes[nodeIndex].mBounds.maxPoint[iDimension]; } } else { childBounds.minPoint[iDimension] = mNodes[nodeIndex].mBounds.minPoint[iDimension]; childBounds.maxPoint[iDimension] = mNodes[nodeIndex].mBounds.maxPoint[iDimension]; } } mNodes[nodeIndex].mChildren[iChild] = createNode(childBounds); splitNode(mNodes[nodeIndex].mChildren[iChild], myTriangles, level + 1); } } }
// build the acceleration structure void Bvh::Build() { // malloc memory mallocMemory(); // build bounding box computeBBox(); // generate bvh primitives for( auto primitive : *m_primitives ) SORT_MALLOC_ID(Bvh_Primitive,BVH_LEAF_PRILIST_MEMID)(primitive); // recursively split node m_root = new Bvh_Node(); splitNode( m_root , 0 , m_primitives->size() , 0 ); }
static void splitNode(BSTree* tree, BSNode* node) { int m = (int)ceil((float)node->keyNum / 2); int mKey = node->keys[m]; void* mValue = node->values[m]; BSNode* nNode = _initNode(tree->mOrder); int j = 0, i = 0; for(i = m + 1; i <= node->keyNum; ++i) { ++j; nNode->keys[j] = node->keys[i]; nNode->values[j] = node->values[i]; nNode->children[j] = node->children[i]; if (node->children[i]) node->children[i]->parent = nNode; node->keys[i] = INT_MIN; node->values[i] = NULL; node->children[i] = NULL; } nNode->children[0] = node->children[m]; if (nNode->children[0]) nNode->children[0]->parent = nNode; nNode->keyNum = j; node->keys[m] = INT_MIN; node->children[m] = NULL; node->values[m] = NULL; node->keyNum = m - 1; BSNode* p = node->parent; if (p) { insertKey(p, mKey, mValue, nNode); nNode->parent = p; if (p->keyNum > tree->mOrder -1) splitNode(tree, p); } else { BSNode* nNode2 = initNode(tree->mOrder, mKey, mValue); nNode2->children[0] = node; nNode2->children[1] = nNode; node->parent = nNode2; nNode->parent = nNode2; tree->root = nNode2; } }
CNode* CTree::insert(CNode* node, int32_t start, int32_t len, int32_t pos, int8_t depth) { if(node == NULL) { nodeCnt++; return new CLeaf(start, len, pos); } int32_t mini = min<int32_t>(len, node->len); int32_t diff = diffIdx(txt + start, txt + node->id, mini, depth); if(diff == mini) { // total match if(!node->leaf) { // inner node CInnerNode* inner = (CInnerNode *) node; //int8_t idx = bioinf::baseToInt(txt[start + diff]); int8_t idx = txt[start + diff]; inner->children[idx] = insert(inner->children[idx], start + mini, len - mini, pos, depth + mini); return inner; } else { // kmer complete match - add pos CLeaf* leaf = (CLeaf*) node; leaf->pos.push_back(pos); return leaf; } } else { // split on inner nodeCnt += 2; // update old node CInnerNode* parent = splitNode(node, diff); // new leaf CLeaf* leaf = new CLeaf(start + diff, len - diff, pos); //int8_t idx = bioinf::baseToInt(txt[start + diff]); int8_t idx = txt[start + diff]; parent->children[idx] = leaf; return parent; } }
Action::ResultE SplitGraphOp::traverseLeave(NodePtr& node, Action::ResultE res) { std::vector<NodePtr>::iterator it = node->editMFChildren()->getValues().begin(); std::vector<NodePtr>::iterator en = node->editMFChildren()->getValues().end (); std::vector<NodePtr> toAdd; std::vector<NodePtr> toSub; for ( ; it != en; ++it ) { bool special=isInExcludeList(*it); bool leaf=isLeaf(*it); if (!special && leaf) { if (splitNode(*it, toAdd)) toSub.push_back(*it); } } it = toAdd.begin(); en = toAdd.end (); for ( ; it != en; ++it ) { beginEditCP(node, Node::ChildrenFieldMask); node->addChild(*it); endEditCP (node, Node::ChildrenFieldMask); } it = toSub.begin(); en = toSub.end (); for ( ; it != en; ++it ) { beginEditCP(node, Node::ChildrenFieldMask); addRefCP(*it); node->subChild(*it); endEditCP (node, Node::ChildrenFieldMask); } return res; }
//////////////////////////////////////////////////////////////////////////////// // buildTree void MaBSPTree::buildTree() { // Set root node. if( NodeList_.size() > 0 ) { // Put non coinciding node at the front. putNonCoincidingNodeAtTheFront( NodeList_ ); // Grab first for split. pRootNode_ = NodeList_[ 0 ]; // Put all items into root node for splitting. for( BcU32 i = 1; i < NodeList_.size(); ++i ) { pRootNode_->WorkingList_.push_back( NodeList_[ i ] ); } // Split. splitNode( pRootNode_ ); } }
Action::ResultE SplitGraphOp::traverseLeave(Node * const node, Action::ResultE res) { MFUnrecChildNodePtr::const_iterator mfit = node->getMFChildren()->begin(); MFUnrecChildNodePtr::const_iterator mfen = node->getMFChildren()->end (); std::vector<NodeUnrecPtr > toAdd; std::vector<Node *> toSub; for ( ; mfit != mfen; ++mfit ) { bool special=isInExcludeList(*mfit); bool leaf=isLeaf(*mfit); if (!special && leaf) { if (splitNode(*mfit, toAdd)) toSub.push_back(*mfit); } } std::vector<NodeUnrecPtr>::const_iterator vait = toAdd.begin(); std::vector<NodeUnrecPtr>::const_iterator vaen = toAdd.end (); for ( ; vait != vaen; ++vait ) { node->addChild(*vait); } std::vector<Node *>::const_iterator vsit = toSub.begin(); std::vector<Node *>::const_iterator vsen = toSub.end (); for ( ; vsit != vsen; ++vsit ) { node->subChild(*vsit); } return res; }
BVH::BVH( const std::vector< Primitive::PrimitiveUniquePtr > &primitives ) : primitives_( primitives ) { Timer t; t.start(); if ( primitives_.size() > 0 ) { std::deque< PrimitiveAABBArea > s( primitives_.size() ); primitive_id_.resize( primitives_.size() ); AABB root_aabb; for( std::size_t i = 0; i < primitives_.size(); i++ ) { AABB aabb = primitives_[i]->getAABB(); // compute the AABB area for the root node if ( !i ) root_aabb = aabb; else root_aabb = root_aabb + aabb; s[i].primitive_id_ = i; s[i].centroid_ = aabb.centroid_; s[i].aabb_ = aabb; } splitNode( &root_node_, s, 0, s.size() - 1, root_aabb.getArea() ); } //dump(); t.stop(); std::cout << " total BVH construction time ......: " << t.getElapsedSeconds() << " sec, " << t.getElapsedNanoSeconds() << " nsec."; }
void Tree::grow(std::vector<double>* variable_importance) { this->variable_importance = variable_importance; // Bootstrap, dependent if weighted or not and with or without replacement if (case_weights->empty()) { if (sample_with_replacement) { bootstrap(); } else { bootstrapWithoutReplacement(); } } else { if (sample_with_replacement) { bootstrapWeighted(); } else { bootstrapWithoutReplacementWeighted(); } } // While not all nodes terminal, split next node size_t num_open_nodes = 1; size_t i = 0; while (num_open_nodes > 0) { bool is_terminal_node = splitNode(i); if (is_terminal_node) { --num_open_nodes; } else { ++num_open_nodes; } ++i; } // Delete sampleID vector to save memory sampleIDs.clear(); cleanUpInternal(); }
/* BVH construction based on the algorithm presented in the paper: * * "Ray Tracing Deformable Scenes Using Dynamic Bounding Volume Hierarchies". * Ingo Wald, Solomon Boulos, and Peter Shirley * ACM Transactions on Graphics. * Volume 26 Issue 1, 2007. */ void BVH::splitNode( BVHNode **node, std::deque< PrimitiveAABBArea > &s, std::size_t first, std::size_t last, float s_area ) { (*node) = new BVHNode(); (*node)->first_ = first; (*node)->last_ = last; (*node)->left_ = nullptr; (*node)->right_ = nullptr; std::deque< PrimitiveAABBArea > s_aux; float best_cost = cost_intersec_tri_ * ( last + 1 - first ); int best_axis = -1; int best_event = -1; for ( int axis = 1; axis <= 3; axis++ ) { switch( axis ) { case 1: std::sort( s.begin() + first, s.begin() + last + 1, Comparator::sortInX ); break; case 2: std::sort( s.begin() + first, s.begin() + last + 1, Comparator::sortInY ); break; case 3: std::sort( s.begin() + first, s.begin() + last + 1, Comparator::sortInZ ); break; } s_aux = std::deque< PrimitiveAABBArea >( s.begin() + first, s.begin() + last + 1 ); for ( std::size_t i = first; i <= last; i++ ) { if ( i == first ) { s[i].left_area_ = std::numeric_limits< float >::infinity(); s_aux[0].left_aabb_ = s_aux[0].aabb_; } else { s[i].left_area_ = s_aux[ i - first - 1 ].left_aabb_.getArea(); s_aux[ i - first ].left_aabb_ = s_aux[ i - first ].aabb_ + s_aux[ i - first - 1 ].left_aabb_; } } for ( long int i = last; i >= static_cast< long int >( first ); i-- ) { if ( i == static_cast< long int >( last ) ) { s[i].right_area_ = std::numeric_limits< float >::infinity(); s_aux[ last - first ].right_aabb_ = s_aux[ last - first ].aabb_; } else { s[i].right_area_ = s_aux[ i - first + 1 ].right_aabb_.getArea(); s_aux[ i - first ].right_aabb_ = s_aux[ i - first ].aabb_ + s_aux[ i - first + 1 ].right_aabb_; } float this_cost = SAH( i - first + 1, s[i].left_area_, last - i, s[i].right_area_, s_area ); if ( this_cost < best_cost ) { best_cost = this_cost; best_event = i; best_axis = axis; } } } if ( best_axis == -1 ) // This is a leaf node { primitives_inserted_ += last - first + 1; std::stringstream progress_stream; progress_stream << "\r BVH building progress ............: " << std::fixed << std::setw( 6 ) << std::setprecision( 2 ) << 100.0f * static_cast< float >( primitives_inserted_ ) / primitives_.size() << "%"; std::clog << progress_stream.str(); //if ( last == first ) // std::clog << "One primitive node!\n"; for ( long unsigned int i = first; i <= last; i++ ) { primitive_id_[i] = s[i].primitive_id_; if ( i == first ) (*node)->aabb_ = s[i].aabb_; else (*node)->aabb_ = (*node)->aabb_ + s[i].aabb_; } } else // This is an inner node { // Make inner node with best_axis / best_event switch( best_axis ) { case 1: std::sort( s.begin() + first, s.begin() + last + 1, Comparator::sortInX ); break; case 2: std::sort( s.begin() + first, s.begin() + last + 1, Comparator::sortInY ); break; case 3: std::sort( s.begin() + first, s.begin() + last + 1, Comparator::sortInZ ); break; } splitNode( &(*node)->left_, s, first, best_event, s_area ); splitNode( &(*node)->right_, s, best_event + 1, last, s_area ); (*node)->aabb_ = (*node)->left_->aabb_ + (*node)->right_->aabb_; } }
void CompletionTrieBuilder::addString(std::string str, u_int32_t score, std::string additionalData) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); unsigned short numberOfCharsFound = 0; unsigned char charsRemainingForLastNode = 0; std::stack<BuilderNode*> locus = findLocus(str, numberOfCharsFound, charsRemainingForLastNode); BuilderNode* parent = locus.top(); /* * If the searched term is longer than the string defined by the current parent node */ if (parent != root && charsRemainingForLastNode > 0 && parent->suffix_.length() != 1 && charsRemainingForLastNode < parent->suffix_.length()) { if (numberOfCharsFound == str.length() && parent->suffix_.length() == static_cast<uint>(charsRemainingForLastNode + 1)) { /* * E.g. we've added XXXabc and than XXXa. In this case we should not split abc but * add a to abc's parent XXX */ numberOfCharsFound -= parent->suffix_.length() - charsRemainingForLastNode; locus.pop(); parent = locus.top(); } else { /* * Here we found more than one char but not all of parent are identical */ splitNode(parent, parent->suffix_.length() - charsRemainingForLastNode); } } /* * If the parent is already a leaf node */ if (parent->isLeafNode() && charsRemainingForLastNode == 0 && parent != root) { if (parent->suffix_.length() != 1) { splitNode(parent, parent->suffix_.length() - 1); numberOfCharsFound--; } else { /* * parent is a non splittable leaf node -> take its parent instead */ numberOfCharsFound -= parent->suffix_.length(); locus.pop(); parent = locus.top(); } } std::string prefix = str.substr(numberOfCharsFound); std::string nodePrefix; while ((nodePrefix = prefix.substr(0, MAXIMUM_PREFIX_SIZE)).length() != 0) { BuilderNode* child = createNode(parent, score, nodePrefix); parent->addChild(child); if (prefix.length() > MAXIMUM_PREFIX_SIZE) { parent = child; prefix = prefix.substr(MAXIMUM_PREFIX_SIZE); } else { child->setAdditionalData(additionalData); break; } } }
RC splitNode(BTreeHandle *tree, BT_KeyPosition *kp, Value *key, RID *rid) { BM_PageHandle *page = (BM_PageHandle *) malloc(sizeof(BM_PageHandle)); BM_PageHandle *newPage = (BM_PageHandle *) malloc(sizeof(BM_PageHandle)); RC rc; // currently the node has n keys and would be filled one more // split the node first - create a new node // get total node pages int totalNodePages; getTotalNodePages(tree, &totalNodePages); int newNode = totalNodePages; // get root page int rootPage; getRootPage(tree, &rootPage); // get n int n; getN(tree, &n); // pin the page rc = pinPage(BM, page, kp->nodePage); if (rc != RC_OK) { return rc; } int *ip = (int *) page->data; // get node state int nodeState = ip[0]; // get current keys int currentKeys = ip[1]; // get parent int parent = ip[2]; // get right sibling int rightSibling = ip[4 + n + 2 * n]; // THE NODE IS A LEAF if (nodeState == 2) { // copy the keys and key pointer into temp arrays int *keys = (int *) calloc(n + 1, sizeof(int)); // index is 0..n int *keyPointers = (int *) calloc(2 * (n + 2), sizeof(int)); // index is 0..2(n+1)+1 memcpy((char *) keys, page->data + 4 * sizeof(int), n * sizeof(int)); memcpy((char *) keyPointers, page->data + (4 + n) * sizeof(int), (2 * (n + 1)) * sizeof(int)); // if i comes to the end of the array, then insert the new key and key pointer into the end of the array if (kp->keyPos == n) { keys[n] = key->v.intV; keyPointers[2 * (n + 1)] = rid.page; keyPointers[2 * (n + 1) + 1] = rid.slot; } else if (key->v.intV < keys[kp->keyPos]) { int j; for (j = n; j > kp->keyPos; j--) { keys[j] = keys[j - 1]; keyPointers[2 * (j + 1)] = keyPointers[2 * j]; keyPointers[2 * (j + 1) + 1] = keyPointers[2 * j + 1]; } // after the for loop, the j comes to i (j = i) // insert the new key and key pointer into the j spot keys[j] = key->v.intV; keyPointers[2 * (j + 1)] = rid->page; keyPointers[2 * (j + 1) + 1] = rid->slot; } // get the new number of keys in the split node int newCurrentKeys = (int) ceil((double) n / 2.0f); // copy the first half into the original node memcpy(page->data + 4 * sizeof(int), (char *) keys, newCurrentKeys * sizeof(int)); memcpy(page->data + (4 + n) * sizeof(int), (char *) keyPointers, (2 * newCurrentKeys) * sizeof(int)); // unset the rest keys and key pointers memset(page->data + (4 + newCurrentKeys) * sizeof(int), 0, (n - newCurrentKeys) * sizeof(int)); memset(page->data + (4 + n + 2 * (newCurrentKeys)) * sizeof(int), 0, 2 * (n + 1 - newCurrentKeys) * sizeof(int)); // set right sibling to the new node page ip[4 + n + 2 * n] = newNode; // create the new node, the new node page number is totalNodePages createNodePage(tree, newNode, nodeState, parent, kp->nodePage, rightSibling); // init the new node page // pin the page rc = pinPage(BM, newPage, newNode); if (rc != RC_OK) { return rc; } int *nip = newPage->data; nip[1] = newCurrentKeys; memcpy(newPage->data + 4 * sizeof(int), (char *) keys, newCurrentKeys * sizeof(int)); memcpy(newPage->data + (4 + n) * sizeof(int), (char *) keyPointers, (2 * newCurrentKeys) * sizeof(int)); // unpin the page rc = -99; rc = unpinPage(BM, newPage); if (rc != RC_OK) { return rc; } int pCurrentKeys; getCurrentKeys(tree, parent, &pCurrentKeys); // insert the smallest key in the right node into the parent if (pCurrentKeys < n) { // case 1 - parent is not full insertInternalNode(); } else if (pCurrentKeys == n) { BT_KeyPosition *newKp; newKp->nodePage = parent; newKp->keyPos = -1; RID *newRid; newRid->page = newNode; newRid->slot = -1; Value *newKey; newKey->dt = DT_INT; newKey->v->intV = keys[newCurrentKeys]; splitNode(tree, newKp, newKey, newRid); } } else if (kp->nodePage != rootPage) { // case 2 - parent is full, parent is not root } else if (kp->nodePage == rootPage) { // case 3 - parent is full, parent is root } // unpin the page rc = -99; rc = unpinPage(BM, page); if (rc != RC_OK) { return rc; } free(page); return RC_OK; }
/*! \internal */ QPoint QGeneralAreaAllocator::allocateFromNode(const QSize &size, Node *node) { // Find the best node to insert into, which should be // a node with the least amount of unused space that is // big enough to contain the requested size. while (node != 0) { // Go down a level and determine if the left or right // sub-tree contains the best chance of allocation. Node *left = node->left; Node *right = node->right; if (left && fitsWithin(size, left->largestFree)) { if (right && fitsWithin(size, right->largestFree)) { if (left->largestFree.width() < right->largestFree.width() || left->largestFree.height() < right->largestFree.height()) { // The largestFree values may be a little oversized, // so try the left sub-tree and then the right sub-tree. QPoint point = allocateFromNode(size, left); if (point.x() >= 0) return point; else return allocateFromNode(size, right); } else { node = right; } } else { node = left; } } else if (right && fitsWithin(size, right->largestFree)) { node = right; } else if (left || right) { // Neither sub-node has enough space to allocate from. return QPoint(-1, -1); } else if (fitsWithin(size, node->largestFree)) { // Do we need to split this node into smaller pieces? Split split; if (fitsWithin(QSize(size.width() * 2, size.height() * 2), node->largestFree)) { // Split in either direction: choose the inverse of // the parent node's split direction to try to balance // out the wasted space as further subdivisions happen. if (node->parent && node->parent->left->rect.x() == node->parent->right->rect.x()) split = SplitOnX; else if (node->parent) split = SplitOnY; else if (node->rect.width() >= node->rect.height()) split = SplitOnX; else split = SplitOnY; } else if (fitsWithin(QSize(size.width() * 2, size.height()), node->largestFree)) { // Split along the X direction. split = SplitOnX; } else if (fitsWithin(QSize(size.width(), size.height() * 2), node->largestFree)) { // Split along the Y direction. split = SplitOnY; } else { // Cannot split further - allocate this node. node->largestFree = QSize(0, 0); updateLargestFree(node); return node->rect.topLeft(); } // Split the node, then go around again using the left sub-tree. node = splitNode(node, split); } else { // Cannot possibly fit into this node. break; } } return QPoint(-1, -1); }
//////////////////////////////////////////////////////////////////////////////// // splitNode void MaBSPTree::splitNode( MaBSPNode* pNode ) { MaBSPNode* pSwappedNode = NULL; BcBSPNodeList FList_; // Front list. BcBSPNodeList BList_; // Back list. // Move non coinciding node to the front. putNonCoincidingNodeAtTheFront( pNode->WorkingList_ ); // Split up this nodes list into a front and back list. for( BcBSPNodeList::iterator It( pNode->WorkingList_.begin() ); It != pNode->WorkingList_.end(); ) { MaPlane::eClassify Classify = classifyNode( (*It), pNode->Plane_ ); // If it's coinciding use normal to determine facing. if( Classify == MaPlane::bcPC_COINCIDING ) { /* if( pNode->Plane_.normal().dot( (*It)->Plane_.normal() ) < 0.0f ) { Classify = MaPlane::bcPC_FRONT; } else { Classify = MaPlane::bcPC_FRONT; } */ // HACK, seems to work...just: Classify = MaPlane::bcPC_FRONT; } // Classify the node. switch( Classify ) { case MaPlane::bcPC_FRONT: { // Node is entirely infront. pSwappedNode = (*It); It = pNode->WorkingList_.erase( It ); FList_.push_back( pSwappedNode ); BcAssert( pSwappedNode->Vertices_.size() >= 2 ); } break; case MaPlane::bcPC_BACK: { // Node is entirely behind. pSwappedNode = (*It); It = pNode->WorkingList_.erase( It ); BList_.push_back( pSwappedNode ); BcAssert( pSwappedNode->Vertices_.size() >= 2 ); } break; case MaPlane::bcPC_SPANNING: { // Node spans the plane. Must be clipped. MaBSPNode* pFront = clipNode( (*It), MaPlane( pNode->Plane_.normal().x(), pNode->Plane_.normal().y(), pNode->Plane_.normal().z(), pNode->Plane_.d() ) ); MaBSPNode* pBack = clipNode( (*It), MaPlane( -pNode->Plane_.normal().x(), -pNode->Plane_.normal().y(), -pNode->Plane_.normal().z(), -pNode->Plane_.d() ) ); // Original node can be dropped. pSwappedNode = (*It); It = pNode->WorkingList_.erase( It ); // Add new nodes to lists. FList_.push_back( pFront ); BcAssert( pFront->Vertices_.size() >= 2 ); BList_.push_back( pBack ); BcAssert( pBack->Vertices_.size() >= 2 ); } break; default: //Bc_AssertFailMsg( "Duplicate plane in tree." ); BcBreakpoint; break; } } // Select a front and back node for each list. if( FList_.size() > 0 ) { pNode->pFront_ = (*FList_.begin()); FList_.erase( FList_.begin() ); MaBSPNode* pSwappedNode = NULL; for( BcBSPNodeList::iterator It( FList_.begin() ); It != FList_.end(); ) { pSwappedNode = (*It); It = FList_.erase( It ); pNode->pFront_->WorkingList_.push_back( pSwappedNode ); BcAssert( pSwappedNode->Vertices_.size() >= 2 ); } splitNode( pNode->pFront_ ); } if( BList_.size() > 0 ) { pNode->pBack_ = (*BList_.begin()); BList_.erase( BList_.begin() ); MaBSPNode* pSwappedNode = NULL; for( BcBSPNodeList::iterator It( BList_.begin() ); It != BList_.end(); ) { pSwappedNode = (*It); It = BList_.erase( It ); pNode->pBack_->WorkingList_.push_back( pSwappedNode ); BcAssert( pSwappedNode->Vertices_.size() >= 2 ); } splitNode( pNode->pBack_ ); } }
RC insertKey(BTreeHandle *tree, Value *key, RID rid) { RC rc; // get root page PageNumber rootPage; rc = -99; rc = getRootPage(tree, &rootPage); if (rc != RC_OK) { return rc; } RID result; BT_KeyPosition *kp; rc = -99; rc = searchKeyFromRoot(tree, key, &result, kp); // if return RC_OK, then the to-be inserted key is found, return RC_IM_KEY_ALREADY_EXISTS // else if return RC_IM_KEY_NOT_FOUND, then the to-be inserted key is not in the tree, insert it // else, some error happens, return rc if (rc == RC_OK) { return RC_IM_KEY_ALREADY_EXISTS; } else if (rc == RC_IM_KEY_NOT_FOUND) { // start to insert // get N int n; rc = -99; rc = getN(tree, &n); if (rc != RC_OK) { return rc; } // get current keys int currentKeys; rc = -99; rc = getCurrentKeys(tree, kp->nodePage, ¤tKeys); if (rc != RC_OK) { return rc; } // if current node is full, split it into two nodes if (currentKeys == n) { // split splitNode(); } else { rc = -99; rc = insertLeafNode(tree, kp, key, &rid); if (rc != RC_OK) { return rc; } } // increment # of entries by 1 int numEntries; rc = -99; rc = getNumEntries(tree, kp->nodePage, &numEntries); if (rc != RC_OK) { return rc; } rc = -99; rc = setNumEntries(tree, kp->nodePage, ++numEntries); if (rc != RC_OK) { return rc; } } else { return rc; } return RC_OK; }
/** * brief @ To split the node that had more than 2 parents. * Example: * TREE A: TREE B: * (A) (A) * / \ / \ * (B) (C) => (B) (C) * / \ | => / \ \ * (D) (E) | => (D) (E) | * \ | / \ | | * split Node>> (F) (F)<-+---- * C is pointing to F while E is pointing to (newNode) * \ | * (newNode) << Expression of F passed to newNode * * brief @ The expression block in NodeF will be moved to newNode * brief @ The expression block in NodeF become empty then * * param @ Node* node - The tree that is going to use this function to find all the domFrontiers of it. * * retval@ LinkedList* - The union of domFrontiers of the input argument, 'Node** root' is going to return. **/ void splitNode(Node** rootNode){ LinkedList* splitList = createLinkedList(); LinkedList* nodeList = assembleList(rootNode); ListElement* checkListHead = NULL; ListElement* tempNode = NULL; int i, count, rank, positionOfSplitNode; /* build a list for the children those have more than 1 parent */ ListElement* tempHead = nodeList->head; while(tempHead){ for(i = 0; i < ((Node*)tempHead->node)->numOfChild; i++){ if(((Node*) tempHead->node)->children[i]->parent != tempHead->node && \ ((Node*) tempHead->node)->children[i]->imdDom != tempHead->node) addListLast(splitList, ((Node*) tempHead->node)->children[i]); } tempHead = tempHead->next; } tempHead = splitList->head; /* check each element inside the split list, if one of the elements appear twice, that means it had more than 2 parents. */ while(tempHead){ count = 0; checkListHead = tempHead; tempNode = tempHead->node; // store the current pointing node while(checkListHead){ if(checkListHead->node == tempNode) count++; //more than 2 parent for (checkListHead->node), so need to separate the parents out if(count == 2) break; checkListHead = checkListHead->next; } if(count == 2) break; tempHead = tempHead->next; } if(!tempHead) return; /* compare the rank of both of the nodes that is going to be the parents of newNode */ if(((Node*)checkListHead->node)->rank > ((Node*)checkListHead->node)->parent->rank) rank = ((Node*)checkListHead->node)->parent->rank + 1; else rank = ((Node*)checkListHead->node)->rank + 1; Node* newNode = createNode(rank); positionOfSplitNode = 0; /* find the place of the Node(that is more than 2 parent & going to be splitted) in its parent its parent may own more than 1 child */ while(positionOfSplitNode < ((Node*)checkListHead->node)->parent->numOfChild && \ ((Node*)checkListHead->node)->parent->children[positionOfSplitNode] != ((Node*)checkListHead->node)) positionOfSplitNode++; if(!((Node*)checkListHead->node)->parent->children[positionOfSplitNode]) ThrowError(ERR_UNHANDLE_ERROR, "There was a unhandled exception error"); /* in case the splitNode(had >2 parent at the first) had any children link the newNode with the children of splitNode */ for(i = 0; i < ((Node*)checkListHead->node)->numOfChild; i++) addChild(&newNode, &((Node*)checkListHead->node)->children[i]); /* break the children of the splitNode */ if(((Node*)checkListHead->node)->numOfChild){ ((Node*)checkListHead->node)->numOfChild = 0; ((Node*)checkListHead->node)->children = NULL; } /* link the splitNode to the newNode */ addChild(((Node**)&checkListHead->node), &newNode); /* pass the expression block of splitNode to newNode */ newNode->block = ((Node*)checkListHead->node)->block; ((Node*)checkListHead->node)->block = NULL; /* add the newNode created in the children list of the splitNode(had >2 parent at the first) and its parent */ ((Node*)checkListHead->node)->parent->children[positionOfSplitNode] = newNode; /* re-assign parent */ nodeList = assembleList(rootNode); tempHead = nodeList->head; while(tempHead){ for(i = 0; i < ((Node*)tempHead->node)->numOfChild; i++){ if(((Node*)tempHead->node)->children[i]->parent != tempHead->node) ((Node*)tempHead->node)->children[i]->parent = tempHead->node; } tempHead = tempHead->next; } //check is any node's parent >2 nodeList = assembleList(rootNode); tempHead = nodeList->head; while(tempHead){ for(i = 0; i < ((Node*)tempHead->node)->numOfChild; i++){ if(((Node*) tempHead->node)->children[i]->parent != tempHead->node && \ ((Node*) tempHead->node)->children[i]->imdDom != tempHead->node) addListLast(splitList, ((Node*) tempHead->node)->children[i]); } tempHead = tempHead->next; } tempHead = splitList->head; while(tempHead){ count = 0; checkListHead = tempHead; tempNode = tempHead->node; // store the current pointing node while(checkListHead){ if(checkListHead->node == tempNode) count++; //more than 2 parent for (checkListHead->node), so need to separate the parents out if(count == 2) break; checkListHead = checkListHead->next; } if(count == 2) break; tempHead = tempHead->next; } if(!tempHead) return; //recursive splitNode(rootNode); }
static void _updateNode(BSTree* tree, BSNode* node, int key, void* value) { insertKey(node, key, value, NULL); if (node->keyNum > tree->mOrder - 1 ) splitNode(tree, node); }
// delete the specified key from the Btree RC deleteKey(BTreeHandle *tree, Value *key) { Btree* leaf = NULL; // get the desired leaf leaf = find_leaf(tree, key); // get the left node Btree* childLeft = NULL; childLeft = leaf->prev; // get the tree stastistics data Btree_stat *info = NULL; info = tree->mgmtData; if (leaf != NULL) { if (childLeft == NULL) { // no child // delete the entry and adjust the tree if needed delete_entry(tree, leaf, key); // done return RC_OK; } if (key->v.intV == leaf->keys[0]) { // the key exists in this leaf node // delete it delete_entry(tree, leaf, key); // check if there is underflow in the node capacity if (leaf->num_keys == 0) { // merge with the left sibling childLeft->next = leaf->next; // check if we need to propagate this change up the tree delete_parent_nodes_inital(info, leaf, key); // done return RC_OK; } // update the prent node updateFirst(leaf, key); return RC_OK; } else { delete_entry(tree, leaf, key); if (leaf) { // see of there is underflow if (checkUnderflow(info, leaf)) { // if yes, merge with left sibling if (childLeft) { // check the number of keys even after splitting if (childLeft->num_keys > splitNode(info->order) && childLeft->num_keys != info->order) { // we need to redistribute the keys // to balance out redistribute(info, childLeft, leaf); } else { // just merge merge_nodes(info, childLeft, leaf); } } } } return RC_OK; } } // all ok return RC_OK; }