void GiST::InsertHelper(const GiSTentry &entry, int level, // level of tree at which to insert int *splitvec) // a vector to trigger Split instead of forced reinsert { GiSTnode *leaf; int overflow=0; leaf=ChooseSubtree(GiSTRootPage, entry, level); leaf->Insert(entry); if (leaf->IsOverFull(*store)) { if(ForcedReinsert()&&!leaf->Path().IsRoot()&&(!splitvec||!splitvec[level])) { int split[GIST_MAX_LEVELS]; // R*-tree-style forced reinsert for(int i=0; i<GIST_MAX_LEVELS; i++) split[i]=0; OverflowTreatment(leaf, entry, split); overflow=1; } else Split(&leaf, entry); if(leaf->IsOverFull(*store)) { // we only should get here if we reinserted, and the node re-filled assert(overflow); leaf->DeleteEntry(entry.Position()); Split(&leaf, entry); } } else WriteNode(leaf); if(!overflow) AdjustKeys(leaf, NULL); delete leaf; }
static void GetInstChain(RSTREE R, typrect newrect, int depth) { int i; refcount c; i= 1; while (i < depth) { if ((*R).NInst[i+1] != NULL) { /* already in path */ (*R).E[i]= (*R).EInst[i]; (*R).EInst[i]= -1; i++; if ((*R).N[i] != (*R).NInst[i]) { (*R).P[i]= (*(*R).N[i-1]).DIR.entries[(*R).E[i-1]].ptrtosub; free((*R).N[i]); (*R).N[i]= NULL; (*R).N[i]= (*R).NInst[i]; } (*R).NInst[i]= NULL; } else if ((*R).EInst[i] != -1) { /* known ... */ (*R).E[i]= (*R).EInst[i]; (*R).EInst[i]= -1; i++; if ((*(*R).N[i-1]).DIR.entries[(*R).E[i-1]].ptrtosub != (*R).P[i]) { /* but not in path */ NewNode(R,i); } } else { /* not known */ ChooseSubtree(R,newrect,i,&(*(*R).N[i]).DIR,&(*R).E[i]); i++; if ((*(*R).N[i-1]).DIR.entries[(*R).E[i-1]].ptrtosub != (*R).P[i]) { /* and not in path */ NewNode(R,i); } } } c= &(*R).count; if ((*c).countflag) { if (depth == (*R).parameters._.height) { (*c).dirvisitcount+= depth - 1; (*c).datavisitcount++; } else { (*c).dirvisitcount+= depth; } } }