void MT::CollectStats () { GiSTpath path; path.MakeRoot (); GiSTnode *node = ReadNode (path); if (!node->IsLeaf()) { int maxLevel = node->Level(); double *radii = new double[maxLevel]; int *pages = new int[maxLevel]; for (int i=0; i<maxLevel; i++) { pages[i] = 0; radii[i] = 0; } TruePredicate truePredicate; GiSTlist<GiSTentry*> list = node->Search(truePredicate); // retrieve all the entries in this node double overlap = ((MTnode *)node)->Overlap(); double totalOverlap = overlap; delete node; while (!list.IsEmpty()) { GiSTentry *entry = list.RemoveFront (); path.MakeChild (entry->Ptr()); node = ReadNode (path); overlap = ((MTnode *)node)->Overlap(); totalOverlap += overlap; pages[node->Level()]++; radii[node->Level()] += ((MTkey *) entry->Key())->MaxRadius(); GiSTlist<GiSTentry*> newlist; if (!node->IsLeaf()) { newlist = node->Search(truePredicate); // recurse to next level } while (!newlist.IsEmpty()) { list.Append (newlist.RemoveFront ()); } path.MakeParent (); delete entry; delete node; } // output the results cout << "Level:\tPages:\tAverage_Radius:"<<endl; int totalPages = 1; // for the root for (int i=maxLevel-1; i>=0; i--) { totalPages += pages[i]; cout << i << ":\t" << pages[i] << "\t" << radii[i]/pages[i] << endl; } cout << "TotalPages:\t" << totalPages << endl; cout << "LeafPages:\t" << pages[0] << endl; cout << "TotalOverlap:\t" << (float)totalOverlap << endl; delete []radii; delete []pages; } else { delete node; } }
GiSTnode* GiST::ChooseSubtree(GiSTpage page, const GiSTentry &entry, int level) { GiSTnode *node; GiSTpath path; for(;;) { path.MakeChild(page); node=ReadNode(path); if(level==node->Level()||node->IsLeaf()) break; page=node->SearchMinPenalty(entry); delete node; } return node; }
void GiST::DumpNode (ostream& os, GiSTpath path) const { GiSTnode *node = ReadNode(path); node->Print(os); if (!node->IsLeaf()) { TruePredicate truePredicate; GiSTlist<GiSTentry*> list = node->Search(truePredicate); while (!list.IsEmpty()) { GiSTentry *e = list.RemoveFront(); path.MakeChild(e->Ptr()); DumpNode (os, path); path.MakeParent(); delete e; } } delete node; }
void GiST::ShortenTree () { GiSTpath path; // Shorten the tree if necessary (This should only be done if root actually changed!) path.MakeRoot (); GiSTnode *root = ReadNode(path); if (!root->IsLeaf() && root->NumEntries()==1) { path.MakeChild ((*root)[0]->Ptr()); GiSTnode *child = ReadNode (path); store->Deallocate(path.Page()); child->SetSibling(0); child->Path().MakeRoot(); WriteNode (child); delete child; } delete root; }