void MTnode::InvalidateEntry (BOOL bNew) { GiSTpath path = Path (); if (path.Level() > 1) { // len>=3 MTnode *parentNode = ((MT *)Tree())->ParentNode((MTnode *)this); for (int i=0; i<parentNode->NumEntries(); i++) { // search the entry in the parent's node MTentry *entry = (MTentry *) (*parentNode)[i].Ptr(); if (entry->Ptr() == path.Page()) { if (bNew) { entry->Key()->distance = -MaxDist(); } entry->Key()->splitted = TRUE; break; } } path.MakeParent (); MTnode *grandNode = ((MT *)Tree())->ParentNode(parentNode); for (int i=0; i<grandNode->NumEntries(); i++) { // search the entry in the grandparent's node MTentry *entry = (MTentry *) (*grandNode)[i].Ptr(); if (entry->Ptr() == path.Page()) { entry->SetMaxRadius(-1); break; } } ((MT *)Tree())->WriteNode(parentNode); // write parent node (in inconsistent state) ((MT *)Tree())->WriteNode(grandNode); // write grandparent node (to invalidate the parent's entry) delete parentNode; delete grandNode; } }
GiSTentry * MTnode::Union () const { Object *objTemp = NULL; if (!obj) { // retrieve the node's parent object MTentry *parentEntry = ParentEntry (); ((MTnode *)this)->obj = (objTemp = new Object(parentEntry->object())); delete parentEntry; } GiSTpath path = ((MTnode *)this)->Path(); MTentry *unionEntry = new MTentry; unionEntry->InitKey(); if (path.Level() > 1) { // len>=3 MTentry *parentEntry = ParentEntry (); if (parentEntry) { // copy the entry unionEntry->Key()->distance = parentEntry->Key()->distance; if (parentEntry->Key()->splitted) { unionEntry->Key()->splitted = TRUE; } delete parentEntry; } if (unionEntry->Key()->distance == -MaxDist()) { // compute the distance from the parent MTnode *parentNode = ((MT *)Tree())->ParentNode((MTnode *)this); MTentry *grandEntry = parentNode->ParentEntry(); unionEntry->Key()->distance = obj->distance(grandEntry->object()); unionEntry->Key()->splitted = TRUE; delete grandEntry; delete parentNode; } } unionEntry->SetObject(*obj); unionEntry->SetMaxRadius(0); unionEntry->SetMinRadius(MAXDOUBLE); mMRadius (unionEntry); // compute the radii if (objTemp) { delete objTemp; } ((MTnode *)this)->obj = NULL; return unionEntry; }