Exemplo n.º 1
0
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;
	}
}
Exemplo n.º 2
0
GiSTentry* 
GiSTnode::SearchPtr(GiSTpage ptr) const
{
    for (int i=0; i<numEntries; i++) {
	GiSTentry *e = (*this)[i];
	if (e->Ptr() == ptr)
	    return (GiSTentry*) e->Copy();
    }
    return NULL;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
// SearchMinPenalty returns where a new entry should be inserted.
GiSTpage 
GiSTnode::SearchMinPenalty(const GiSTentry &newEntry) const
{
    GiSTentry *minEntry = NULL;
    GiSTpenalty *minPenalty = NULL;

    for (int i=0; i<numEntries; i++) {
	GiSTentry *e = (*this)[i];
	assert(e->Node() == this);
	GiSTpenalty *penalty = e->Penalty(newEntry);
	if (minEntry == NULL || (*penalty) < (*minPenalty)) {
	    minEntry = e;
	    if (minPenalty) delete minPenalty;
	    minPenalty = penalty;
	}
	else 
	  delete penalty;
    }
    delete minPenalty;
    return minEntry->Ptr();
}
Exemplo n.º 6
0
void CommandSelect(const char *table,
		   const GiSTpredicate& pred)
{
    int i;

    i = GetTable(table);
    if (i == NOT_FOUND) {
	cerr << "Table is not open!\n";
	return;
    }

    GiST *gist = tables[i].gist;

    GiSTcursor *c = gist->Search(pred);
    GiSTentry *e;
    while ((e = c->Next()) != NULL) {
	Record* rec = (Record*)e->Ptr();
	cout << rec->value << "\n";
	delete e;
    }
    delete c;
}
Exemplo n.º 7
0
void 
GiST::Split(GiSTnode **node, const GiSTentry& entry)
{
	int went_left=0, new_root=0;

	if((*node)->Path().IsRoot()) {
		new_root=1;
		(*node)->Path().MakeChild(store->Allocate());
	}

	GiSTnode *node2=(*node)->PickSplit();
	node2->Path().MakeSibling(store->Allocate());
	GiSTentry *e=(*node)->SearchPtr(entry.Ptr());

	if(e!=NULL) {
		went_left=1;
		delete e;
	}
	node2->SetSibling((*node)->Sibling());
	(*node)->SetSibling(node2->Path().Page());
	WriteNode(*node);
	WriteNode(node2);

	GiSTentry *e1=(*node)->Union();
	GiSTentry *e2=node2->Union();

	e1->SetPtr((*node)->Path().Page());
	e2->SetPtr(node2->Path().Page());
	// Create new root if root is being split
	if (new_root) {
		GiSTnode *root=NewNode(this);

		root->SetLevel((*node)->Level()+1);
		root->InsertBefore(*e1, 0);
		root->InsertBefore(*e2, 1);
		root->Path().MakeRoot();
		WriteNode(root);
		delete root;
	}
	else {
		// Insert entry for N' in parent
		GiSTpath parent_path=(*node)->Path();
		parent_path.MakeParent();
		GiSTnode *parent=ReadNode(parent_path);
		// Find the entry for N in parent
		GiSTentry *e=parent->SearchPtr((*node)->Path().Page());
		assert(e!=NULL);
		// Insert the new entry right after it
		int pos=e->Position();

		parent->DeleteEntry(pos);
		parent->InsertBefore(*e1, pos);
		parent->InsertBefore(*e2, pos+1);
		delete e;
		if(!parent->IsOverFull(*store)) WriteNode(parent);
		else {
			Split(&parent, went_left? *e1: *e2);
			GiSTpage page=(*node)->Path().Page();

			(*node)->Path()=parent->Path();
			(*node)->Path().MakeChild(page);
			page=node2->Path().Page();
			node2->Path()=(*node)->Path();
			node2->Path().MakeSibling(page);
		}
		delete parent;
	}
	if(!went_left) {
		delete *node;
		*node=node2;
	}
	else delete node2;
	delete e1;
	delete e2;
}
Exemplo n.º 8
0
void MXTree::Split(GiSTnode **node, const GiSTentry& entry)
{
	double radii[2], dist, *dists = new double[(*node)->NumEntries()*2];
	int pageNums[2], cands[2];
	vector<vector<int>> vec(2);
	((MXTnode *)(*node))->TestPromotion(radii, &dist, pageNums, cands, dists, vec);
	if (Trade((*node)->Path().IsRoot(), radii, dist, pageNums, ((MXTnode *)(*node))->GetPageNum()+1, (*node)->NumEntries())) {
		// don't split now
		delete[] dists;
		GiSTpath oldPath = (*node)->Path();

		int startPage = ((*node)->Path().IsRoot() ? rootPage : (*node)->Path().Page());
		int pageNum = ((MXTnode *)(*node))->GetPageNum();
		((MXTfile *)store)->Deallocate(startPage, pageNum);
		startPage = ((MXTfile *)store)->Allocate(++pageNum);
		(*node)->Path().MakeSibling(startPage);
		rootPage = ((*node)->Path().IsRoot() ? startPage : rootPage);
		((MXTnode *)(*node))->SetPageNum(pageNum);
		WriteNode(*node);

		if (!(*node)->Path().IsRoot() && startPage != oldPath.Page()) {
			GiSTpath parentPath = oldPath;
			parentPath.MakeParent();
			GiSTnode *parentNode = ReadNode(parentPath);
			GiSTentry *e = parentNode->SearchPtr(oldPath.Page());
			assert(e != NULL);
			int pos = e->Position();
			e->SetPtr(startPage);
			parentNode->DeleteEntry(pos);
			parentNode->InsertBefore(*e, pos);
			WriteNode(parentNode);
			delete parentNode;
			delete e;
		}
	} else {
		// split now
		bool bLeft = false, bNewRoot = false;

		if ((*node)->Path().IsRoot()) {
			bNewRoot = true;
			(*node)->Path().MakeChild(rootPage);
			rootPage = store->Allocate();
		}

		int oldPageNum = ((MXTnode *)(*node))->GetPageNum();
		GiSTnode *node2 = ((MXTnode *)(*node))->PickSplit(cands, dists, vec);
		delete[] dists;
		int curPageNum = ((MXTnode *)(*node))->GetPageNum();
		assert(oldPageNum >= curPageNum);
		if (oldPageNum > curPageNum) {
			((MXTfile *)store)->Deallocate((*node)->Path().Page()+curPageNum, oldPageNum-curPageNum);
		}
		node2->Path().MakeSibling(((MXTfile *)store)->Allocate(((MXTnode *)node2)->GetPageNum()));

		WriteNode(*node);
		WriteNode(node2);
	
		GiSTentry *e = (*node)->SearchPtr(entry.Ptr());
		if (e != NULL) {
			bLeft = true;
			delete e;
		}
	
		GiSTentry *e1 = (*node)->Union();
		GiSTentry *e2 = node2->Union();
	
		e1->SetPtr((*node)->Path().Page());
		e2->SetPtr(node2->Path().Page());
		// Create new root if root is being split
		if (bNewRoot) {
			GiSTnode *root = NewNode(this);
			root->SetLevel((*node)->Level() + 1);
			root->InsertBefore(*e1, 0);
			root->InsertBefore(*e2, 1);
			root->Path().MakeRoot();
			WriteNode(root);
			delete root;
		} else {
			// Insert entry for N' in parent
			GiSTpath parentPath = (*node)->Path();
			parentPath.MakeParent();
			GiSTnode *parent = ReadNode(parentPath);
			// Find the entry for N in parent
			GiSTentry *e = parent->SearchPtr((*node)->Path().Page());
			assert(e != NULL);
			// Insert the new entry right after it
			int pos = e->Position();
			parent->DeleteEntry(pos);
			parent->InsertBefore(*e1, pos);
			parent->InsertBefore(*e2, pos+1);
			delete e;
			if (!parent->IsOverFull(*store)) {
				WriteNode(parent);
			} else {
				Split(&parent, bLeft? *e1: *e2);  // parent is the node which contains the entry inserted
				GiSTpage page = (*node)->Path().Page();
				(*node)->Path() = parent->Path();  // parent's path may change
				(*node)->Path().MakeChild(page);
				page = node2->Path().Page();
				node2->Path() = (*node)->Path();
				node2->Path().MakeSibling(page);
			}
			delete parent;
		}
		if (!bLeft) {
			delete *node;
			*node = node2;  // return it
		} else {
			delete node2;
		}
		delete e1;
		delete e2;
	}
}
Exemplo n.º 9
0
int PtrPredicate::Consistent (const GiSTentry& entry) const
{
	return !entry.IsLeaf() || entry.Ptr()==page;
}