Esempio n. 1
0
/* This appends `this` to the node `node` */
NodePtr insert(NodePtr thIs, NodePtr node)
{
	int la = thIs->level; // node to be inserted
	int lb = node->level; // node where insertation
	assert(la < lb); // node to be inserted must have lower level then parent
	//if (thIs->parent) assert(find_in_tree1(thIs) == true);
	NodePtr q = NULL;
	NodePtr chd = NULL;
	node->move(thIs);
	if (la == lb - 1)
	{
    node->child.push_back(thIs);
		thIs->parent = node;
		if (node->child.size() > MAX_NODE_SZ &&  node->tree->canSplit() ) // with us as additional child `node` is now too large :(
			return (node->reinserted || node->parent == NULL) ? split(node) : reinsert(node);
	}
	else // la < lb - 1
	{
		chd = thIs->closest(node->child);
		q = insert(thIs, chd);
	}
	if ((node->updateCount + 1) % UPDATE_EVERY == 0)
		node->update();
	else
	{
		if (q) node->remove(q);
		node->inflate(chd);
	}

  return q;
}
Esempio n. 2
0
NodePtr split(NodePtr thIs)
{
	thIs->tree->increaseLevelSize(thIs->level);
	NodePtr p = new Node;
	NodePtr q = new Node;
	p->level = q->level = thIs->level;
	p->reinserted = q->reinserted = false;
	p->parent = q->parent = thIs->parent;
	p->tree = q->tree = thIs->tree;


	p->child.resize(MAX_NODE_SZ/2);
	q->child.resize(MAX_NODE_SZ/2 + 1);
	assert(thIs->child.size() == MAX_NODE_SZ+1);
	thIs->tree->ref = thIs->closest(thIs->child, FARTHEST); // farthest from centre
	std::sort(thIs->child.begin(), thIs->child.end(), compareDist);
	for (int i = 0; i < MAX_NODE_SZ+1; i++)
		assert(thIs->child[i]->parent == thIs);
	for (int i = 0; i < MAX_NODE_SZ/2 + 1; i++)
		q->child[i] = thIs->child[i];
	for (int i = MAX_NODE_SZ/2+1; i<MAX_NODE_SZ+1; i++)
		p->child[i-MAX_NODE_SZ/2-1] = thIs->child[i];
	for (int i = 0; i < MAX_NODE_SZ/2 + 1; i++)
		q->child[i]->parent = q;
	for (int i = MAX_NODE_SZ/2+1; i < MAX_NODE_SZ+1; i++)
		p->child[i-MAX_NODE_SZ/2-1]->parent = p;
	p->update();
	q->update();
   
	if (squaredist(thIs->centre, q->centre) < squaredist(thIs->centre, p->centre))
		swap(p, q);

	thIs->child = p->child; // now our children do not know we are their parents and believe p is their parent
	for (int i = 0; i < thIs->child.size(); i++)
		thIs->child[i]->parent = thIs;
	thIs->reinserted = p->reinserted;
	thIs->update();
	delete p;

	if (thIs == thIs->tree->root) // root split
	{
		// since we currently are root, make new root and make us and q its children
		thIs->tree->newRoot(thIs->level + 1);
		thIs->tree->root->child.push_back(thIs);  thIs->parent = thIs->tree->root;
		thIs->tree->root->child.push_back(q);     q->parent    = thIs->tree->root;
		thIs->tree->root->update();
	}
	else
	{
		thIs->tree->push_front(q);
	}  // push_front?

  	return q;
}
Esempio n. 3
0
// Each sample node has a rank randomly assigned to it, assign `node` from full tree
void Node::routeNode(NodePtr node, int level)
{
	NodePtr closest;

	double distMin2 = 0; // squared distance
	closest = NULL;
	if (tree->root == this)
		findClosest(level, node, distMin2, closest);

	if (closest != NULL && tree->root == this)
		/* When is this point reached?
		   if the preceeding findClosest was called and succesed to set closest
		   findClosest sets closest if we are `level` or src is in our circle (=> belongs to child of ours)
		   => reached if we are not `level` and node is not child of us
		*/
		node->route = closest->route;
	else  /* find closest was not successfull or we were not root */
	{
		if (this->level == level)
			node->route = this->route;
		else /* not yet right level => go down one more */
			node->closest(this->child)->routeNode(node, level);
	}
}