示例#1
0
// split this M-tree into a list of trees having height level, which is used in the "splitting" phase of the BulkLoad algorithm
// nCreated is the number of created subtrees,
// level is the split level for the tree,
// children is the list of the parents of each subtree,
// name is the root for the subtrees names
// the return value is the list of splitted subtrees's names
GiSTlist<char *> *
MT::SplitTree (int *nCreated, int level, GiSTlist<MTentry *> *parentEntries, const char *name)
{
	GiSTlist<MTnode *> *oldList = new GiSTlist<MTnode *>;  // upper level nodes
	MTnode *node = new MTnode;  // this is because the first operation on node is a delete
	GiSTpath path;
	path.MakeRoot ();
	oldList->Append((MTnode *) ReadNode(path));  // insert the root
	do {  // build the roots list
		GiSTlist<MTnode *> *newList = new GiSTlist<MTnode *>;  // lower level nodes
		while (!oldList->IsEmpty()) {
			delete node;  // delete the old node created by ReadNode
			node = oldList->RemoveFront();  // retrieve next node to be examined
			path = node->Path();
			for (int i=0; i<node->NumEntries(); i++) {  // append all its children to the new list
				path.MakeChild ((*node)[i].Ptr()->Ptr());
				newList->Append((MTnode *)ReadNode(path));
				path.MakeParent ();
			}
		}
		delete oldList;
		oldList = newList;
	} while (node->Level() > level);  // stop if we're at the split level
	delete node;

	GiSTlist<char *> *newTreeNames = new GiSTlist<char *>;  // this is the results list
	while (!oldList->IsEmpty()) {  // now append each sub-tree to its root
		char newName[50];
		sprintf (newName, "%s.%i", name, ++(*nCreated));
		unlink (newName);  // if this M-tree already exists, delete it

		MT *newTree = new MT;
		newTree->Create(newName);  // create a new M-tree
		path.MakeRoot ();
		MTnode *rootNode = (MTnode *) newTree->ReadNode(path);  // read the root of the new tree

		node = oldList->RemoveFront();
		newTree->Append(rootNode, (MTnode *)node->Copy());  // append the current node to the root of new tree
		parentEntries->Append(node->ParentEntry());  // insert the original parent entry into the list
		newTreeNames->Append(strdup(newName));  // insert the new M-tree name into the list
		delete node;
		delete rootNode;
		delete newTree;
	}
	delete oldList;
	return newTreeNames;
}
示例#2
0
文件: MTnode.cpp 项目: jsc0218/MxTree
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;
}