Tree-M
view release on metacpan or search on metacpan
GiST/GiST.cpp view on Meta::CPAN
// remove the "top" p entries from the node
deleted=RemoveTop(node);
WriteNode(node);
AdjustKeys(node, NULL);
// note that we've seen this level already
splitvec[node->Level()]=1;
// for each of the deleted entries, call InsertHelper at this level
while (!deleted.IsEmpty()) {
GiSTentry *tmpentry=deleted.RemoveFront();
InsertHelper(*tmpentry, node->Level(), splitvec);
delete tmpentry;
}
}
GiSTlist<GiSTentry*>
GiST::RemoveTop(GiSTnode *node)
{
GiSTlist<GiSTentry*> deleted;
int count=node->NumEntries();
// default: remove the first ones on the page
int num_rem=(int)((count+1)*RemoveRatio()+0.5);
for(int i=num_rem-1; i>=0; i--) {
deleted.Append((GiSTentry *)(*node)[i].Ptr()->Copy());
node->DeleteEntry(i);
}
return(deleted);
}
void
GiST::AdjustKeys(GiSTnode *node, GiSTnode **parent)
{
GiSTnode *P;
if(node->Path().IsRoot()) return;
// Read in node's parent
if(parent==NULL) {
GiSTpath parent_path=node->Path();
parent_path.MakeParent();
P=ReadNode(parent_path);
parent=&P;
}
else P=*parent;
// Get the old entry pointing to node
GiSTentry *entry=P->SearchPtr(node->Path().Page());
assert(entry!=NULL);
// Get union of node
GiSTentry *actual=node->Union();
actual->SetPtr(node->Path().Page());
if(!entry->IsEqual(*actual)) {
int pos=entry->Position();
P->DeleteEntry(pos);
P->InsertBefore(*actual, pos);
// A split may be necessary.
// XXX: should we do Forced Reinsert here too?
if(P->IsOverFull(*store)) {
Split(parent, *actual);
GiSTpage page=node->Path().Page();
node->Path()=P->Path();
node->Path().MakeChild(page);
}
else {
WriteNode(P);
AdjustKeys(P, NULL);
}
}
if(parent==&P) delete P;
delete actual;
delete entry;
}
void
GiST::Sync()
{
store->Sync();
}
void
GiST::Delete(const GiSTpredicate& pred)
{
GiSTcursor *c=Search(pred);
int condensed;
GiSTentry *e;
do {
if(c==NULL) return;
e=c->Next();
GiSTpath path=c->Path();
delete c;
if(e==NULL) return;
// Read in the node that this belongs to
GiSTnode *node=ReadNode(path);
node->DeleteEntry(e->Position());
WriteNode(node);
condensed=CondenseTree(node);
delete node;
if(condensed) {
ShortenTree();
// because the tree changed, we need to search all over again!
// XXX - this is inefficient! users may want to avoid condensing.
c=Search(pred);
}
} while(e!=NULL);
}
void
GiST::ShortenTree()
{
GiSTpath path;
( run in 0.378 second using v1.01-cache-2.11-cpan-5511b514fd6 )