Пример #1
0
/* Make a new index, empty.  Consists of a single node. */
struct Node * RTreeNewIndex(void)
{
        struct Node *x;

        nodeCount = 0;
        maxLevel  = 0;
        rootID    = 0;

        /* The tree traversal logic fails if there is    */
        /* "pointer" to node 0.  For real memory this    */
        /* cannot happen but for our memory mapped files */
        /* it can and does.  To avoid this, we will      */
        /* allocate a dummy node which will never be     */
        /* used as part of the tree.  A bit of a kludge  */
        /* but better than mucking around with index     */
        /* offsets all over the place.                   */

        x = RTreeNewNode();


        /* This is the real "first" node */

        x = RTreeNewNode();
        x->level = 0; /* leaf */
        return x;
}
Пример #2
0
rtree_t RTreeNew (void)
{
  rtree_t t;
  t = RTreeNewNode();
  t->level = 0; /*leaf*/
  return t;
}
Пример #3
0
static void RTreeSplitNode (node_t n, branch_t b, node_t *new_node)
{
  partition_t p;
  int level;
  int i;

  assert(n);
  assert(new_node);

  p = PartitionNew();

  for (i = 0; i < MAXCARD; i ++)
    PartitionPush(p,n->branch[i]);
  PartitionPush(p,b);

  level = n->level;
  RTreeNodeInit(n);
  n->level = level;
  *new_node = RTreeNewNode();
  (*new_node)->level = level;

  RTreePickSeeds(p, n, *new_node);

  while (p->n)
    if (n->count + p->n <= MINCARD)
      /* first group (n) needs all entries */
      RTreeNodeAddBranch(&(p->cover[0]), n, PartitionPop(p));
    else if ((*new_node)->count + p->n <= MINCARD)
      /* second group (new_node) needs all entries */
      RTreeNodeAddBranch(&(p->cover[1]), *new_node, PartitionPop(p));
    else
      RTreePickNext(p, n, *new_node);
}
Пример #4
0
/*-----------------------------------------------------------------------------
| Split a node.
| Divides the nodes branches and the extra one between two nodes.
| Old node is one of the new ones, and one really new one is created.
| Tries more than one method for choosing a partition, uses best result.
-----------------------------------------------------------------------------*/
extern void RTreeSplitNode(struct Node *n, struct Branch *b, struct Node **nn)
{
	register struct PartitionVars *p;
	register int level;

	assert(n);
	assert(b);

	/* load all the branches into a buffer, initialize old node */
	level = n->level;
	RTreeGetBranches(n, b);

	/* find partition */
	p = &Partitions[0];
	/* Note: can't use MINFILL(n) below since n was cleared by GetBranches() */
	RTreeMethodZero(p, level>0 ? MinNodeFill : MinLeafFill);

	/*
	 * put branches from buffer into 2 nodes
	 * according to chosen partition
	 */
	*nn = RTreeNewNode();
	(*nn)->level = n->level = level;
	RTreeLoadNodes(n, *nn, p);
	assert(n->count+(*nn)->count == p->total);
}
Пример #5
0
/* Make a new index, empty.  Consists of a single node. */
Node_t *RTreeNewIndex(RTree_t * rtp)
{
    Node_t *x;
    x = RTreeNewNode(rtp);
    x->level = 0;		/* leaf */
    rtp->LeafCount++;
    return x;
}
Пример #6
0
int
RTreeInsert(RTree_t * rtp, Rect_t * r, void *data, Node_t ** n, int level)
{
    /* RTreeInsert(RTree_t*rtp, Rect_t*r, int data, Node_t**n, int level) { */
    register int i;
    register Node_t *newroot;
    Node_t *newnode=0;
    Branch_t b;
    int result = 0;


    assert(r && n);
    assert(level >= 0 && level <= (*n)->level);
    for (i = 0; i < NUMDIMS; i++)
	assert(r->boundary[i] <= r->boundary[NUMDIMS + i]);

#	ifdef RTDEBUG
    fprintf(stderr, "RTreeInsert  level=%d\n", level);
#	endif

    if (rtp->StatFlag) {
	if (rtp->Deleting)
	    rtp->ReInsertCount++;
	else
	    rtp->InsertCount++;
    }
    if (!rtp->Deleting)
	rtp->RectCount++;

    if (RTreeInsert2(rtp, r, data, *n, &newnode, level)) {	/* root was split */
	if (rtp->StatFlag) {
	    if (rtp->Deleting)
		rtp->DeTouchCount++;
	    else
		rtp->InTouchCount++;
	}

	newroot = RTreeNewNode(rtp);	/* grow a new root, make tree taller */
	rtp->NonLeafCount++;
	newroot->level = (*n)->level + 1;
	b.rect = NodeCover(*n);
	b.child = *n;
	AddBranch(rtp, &b, newroot, NULL);
	b.rect = NodeCover(newnode);
	b.child = newnode;
	AddBranch(rtp, &b, newroot, NULL);
	*n = newroot;
	// rtp->root = newroot;
	rtp->EntryCount += 2;
	result = 1;
    }

    return result;
}
Пример #7
0
/*
 * Add a branch to a node.  Split the node if necessary.
 * Returns 0 if node not split.  Old node updated.
 * Returns 1 if node split, sets *new_node to address of new node.
 * Old node updated, becomes one of two.
 * Returns 2 if branches were removed for forced reinsertion
 */
int RTreeAddBranch(struct RTree_Branch *b, struct RTree_Node *n,
		   struct RTree_Node **newnode, struct RTree_ListBranch **ee,
		   struct RTree_Rect *cover, int *overflow, struct RTree *t)
{
    int i, maxkids;

    maxkids = MAXKIDS((n)->level, t);

    if (n->count < maxkids) {	/* split won't be necessary */
	if ((n)->level > 0) {   /* internal node */
	    for (i = 0; i < maxkids; i++) {	/* find empty branch */
		if (!t->valid_child(&(n->branch[i].child))) {
		    n->branch[i] = *b;
		    n->count++;
		    break;
		}
	    }
	    return 0;
	}
	else if ((n)->level == 0) {   /* leaf */
	    for (i = 0; i < maxkids; i++) {	/* find empty branch */
		if (n->branch[i].child.id == 0) {
		    n->branch[i] = *b;
		    n->count++;
		    break;
		}
	    }
	    return 0;
	}
    }
    else {
	if (n->level < t->rootlevel && overflow[n->level]) {
	    /* R*-tree forced reinsert */
	    RTreeRemoveBranches(n, b, ee, cover, t);
	    overflow[n->level] = 0;
	    return 2;
	}
	else {
	    if (t->fd > -1)
		RTreeInitNode(*newnode, NODETYPE(n->level, t->fd));
	    else
		*newnode = RTreeNewNode(t, (n)->level);
	    RTreeSplitNode(n, b, *newnode, t);
	    return 1;
	}
    }

    /* should not be reached */
    assert(0);
    return -1;
}
Пример #8
0
/* 
 * Insert a data rectangle into an index structure.
 * RTreeInsertRect provides for splitting the root;
 * returns 1 if root was split, 0 if it was not.
 * The level argument specifies the number of steps up from the leaf
 * level to insert; e.g. a data rectangle goes in at level = 0.
 * RTreeInsertRect2 does the recursion.
 */
int RTreeInsertRect(struct Rect *R, long Tid, struct Node **Root, int Level)
{
        register struct Rect *r = R;
        register long tid = Tid;
        register struct Node **root = Root;
        register int level = Level;
        register int i;
        register struct Node *newroot;
        struct Node *newnode;
        struct Branch b;
        int result;

        assert(r && root);
        assert(level >= 0 && level <= (*root)->level);
        for (i=0; i<NUMDIMS; i++) {
                assert(r->boundary[i] <= r->boundary[NUMDIMS+i]);
        }

        if (RTreeInsertRect2(r, tid, *root, &newnode, level))  /* root split */
        {
                newroot = RTreeNewNode();  /* grow a new root, & tree taller */
                newroot->level = (*root)->level + 1;

                rootID = newroot->id;

                if(newroot->level > maxLevel)
                   maxLevel = newroot->level;

                b.rect = RTreeNodeCover(*root);
                b.child = *root;
                RTreeAddBranch(&b, newroot, NULL);
                b.rect = RTreeNodeCover(newnode);
                b.child = newnode;
                RTreeAddBranch(&b, newroot, NULL);
                *root = newroot;
                result = 1;
        }
        else
                result = 0;

        return result;
}
Пример #9
0
void RTreeInsert (rtree_t *t, rect_t r, void *data)
{
  node_t n2;
  node_t new_root;
  branch_t b;
  assert(t && *t);

  if (RTreeInsertNode(*t, 0, r, data, &n2))
    /* deal with root split */
    {
      new_root = RTreeNewNode();
      new_root->level = (*t)->level + 1;
      b.mbr = RTreeNodeCover(*t);
      b.child = (void *) *t;
      RTreeAddBranch(new_root, b, NULL);
      b.mbr = RTreeNodeCover(n2);
      b.child = (void *) n2;
      RTreeAddBranch(new_root, b, NULL);
      *t = new_root;
    }
}