// adjust the keys of node, which is used during the final phase of the BulkLoad algorithm void MT::AdjKeys (GiSTnode *node) { if (node->Path().IsRoot()) { return; } GiSTpath parentPath = node->Path(); parentPath.MakeParent (); GiSTnode *parentNode = ReadNode (parentPath); GiSTentry *parentEntry = parentNode->SearchPtr(node->Path().Page()); // parent entry assert (parentEntry != NULL); GiSTentry *unionEntry = node->Union(); unionEntry->SetPtr(node->Path().Page()); ((MTkey *) unionEntry->Key())->distance = ((MTkey *) parentEntry->Key())->distance; // necessary to keep track of the distance from the parent if (!parentEntry->IsEqual(*unionEntry)) { // replace this entry parentNode->DeleteEntry(parentEntry->Position()); parentNode->Insert(*unionEntry); WriteNode (parentNode); AdjKeys (parentNode); } delete unionEntry; delete parentEntry; delete parentNode; }
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; } }