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; } }
// return root level+1 (the height of the tree) // this is used in the "splitting" phase of the BulkLoad algorithm int MT::TreeHeight () const { GiSTpath path; path.MakeRoot (); GiSTnode *root = ReadNode (path); int i = root->Level(); delete root; return (i+1); }
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; }
GiSTentry* GiSTcursor::Next() { GiSTpage page; while (first || !stack.IsEmpty()) { if (first) { page = GiSTRootPage; first = 0; } else { assert(lastlevel >= 0); GiSTentry *entry = stack.RemoveFront(); if (entry->IsLeaf()) return entry; // Pop off the stack for (int i=0; i < entry->Level() - lastlevel; i++) path.MakeParent(); page = entry->Ptr(); delete entry; } // Entry was a pointer to another node path.MakeChild(page); GiSTnode *node = gist.ReadNode(path); lastlevel = node->Level(); GiSTlist<GiSTentry*> list = node->Search(*query); while (!list.IsEmpty()) { GiSTentry *entry = list.RemoveRear(); stack.Prepend(entry); } delete node; } // The search is over... return NULL; }