Beispiel #1
0
static int RTreeInsertNode (node_t n, int level,
                            rect_t r, void *data,
                            node_t *new_node)
{
  int i;
  node_t n2;
  branch_t b;

  assert(n && new_node);
  assert(level >= 0 && level <= n->level);
  
  if (n->level > level)
    {
      i = RTreePickBranch(r,n);
      if (!RTreeInsertNode((node_t) n->branch[i].child, level,
                           r, data,&n2)) /* not split */
        {
          n->branch[i].mbr = RectCombine(r,n->branch[i].mbr);
          return FALSE;
        }
      else /* node split */
        {
           n->branch[i].mbr = RTreeNodeCover(n->branch[i].child);
           b.child = n2;
           b.mbr = RTreeNodeCover(n2);
           return RTreeAddBranch(n, b, new_node);
        }
    }
  else /*insert level*/
    {
      b.mbr = r;
      b.child = data;
      return RTreeAddBranch(n, b, new_node);
    }
}
Beispiel #2
0
/*
 * Inserts a new data rectangle into the index structure.
 * Recursively descends tree, propagates splits back up.
 * Returns 0 if node was not split.  Old node updated.
 * If node was split, returns 1 and sets the pointer pointed to by
 * new_node to point to the new node.  Old node updated to become one of two.
 * 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.
 */
static int RTreeInsertRect2(struct Rect *r,
                long tid, struct Node *n, struct Node **new_node, int level)
{
/*
        register struct Rect *r = R;
        register long tid = Tid;
        register struct Node *n = N, **new_node = New_node;
        register int level = Level;
*/

        register int i;
        struct Branch b;
        struct Node *n2;

        assert(r && n && new_node);
        assert(level >= 0 && level <= n->level);

        /* Still above level for insertion, go down tree recursively */
        if (n->level > level)
        {
                i = RTreePickBranch(r, n);
                if (!RTreeInsertRect2(r, tid, n->branch[i].child, &n2, level))
                {
                        /* child was not split */
                        n->branch[i].rect =
                                RTreeCombineRect(r,&(n->branch[i].rect));
                        return 0;
                }
                else    /* child was split */
                {
                        n->branch[i].rect = RTreeNodeCover(n->branch[i].child);
                        b.child = n2;
                        b.rect = RTreeNodeCover(n2);
                        return RTreeAddBranch(&b, n, new_node);
                }
        }

        /* Have reached level for insertion. Add rect, split if necessary */
        else if (n->level == level)
        {
                b.rect = *r;
                b.child = (struct Node *) (tid);
                /* child field of leaves contains tid of data record */
                return RTreeAddBranch(&b, n, new_node);
        }
        else
        {
                /* Not supposed to happen */
                assert (FALSE);
                return 0;
        }
}
Beispiel #3
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;
}
Beispiel #4
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;
    }
}
Beispiel #5
0
/*
 * Delete a rectangle from non-root part of an index structure.
 * Called by RTreeDeleteRect.  Descends tree recursively,
 * merges branches on the way back up.
 * Returns 1 if record not found, 0 if success.
 */
static int
RTreeDeleteRect2(struct Rect *R, long Tid, struct Node *N, struct ListNode **Ee)
{
        register struct Rect *r = R;
        register long tid = Tid;
        register struct Node *n = N;
        register struct ListNode **ee = Ee;
        register int i;

        assert(r && n && ee);
        assert(tid >= 0);
        assert(n->level >= 0);

        if (n->level > 0)  /* not a leaf node */
        {
            for (i = 0; i < NODECARD; i++)
            {
                if (n->branch[i].child && RTreeOverlap(r, &(n->branch[i].rect)))
                {
                        if (!RTreeDeleteRect2(r, tid, n->branch[i].child, ee))
                        {
                                if (n->branch[i].child->count >= MinNodeFill) {
                                        n->branch[i].rect = RTreeNodeCover(
                                                n->branch[i].child);
                                }
                                else
                                {
                                        /* not enough entries in child, eliminate child node */
                                        RTreeReInsert(n->branch[i].child, ee);
                                        RTreeDisconnectBranch(n, i);
                                }
                                return 0;
                        }
                }
            }
            return 1;
        }
        else  /* a leaf node */
        {
                for (i = 0; i < LEAFCARD; i++)
                {
                        if (n->branch[i].child &&
                            (struct Node *)(n->branch[i].child) == (struct Node *) tid)
                        {
                                RTreeDisconnectBranch(n, i);
                                return 0;
                        }
                }
                return 1;
        }
}
Beispiel #6
0
/*
 * Delete a rectangle from non-root part of an index structure.
 * Called by RTreeDeleteRect.  Descends tree non-recursively,
 * merges branches on the way back up.
 * Returns 1 if record not found, 0 if success.
 */
static int
RTreeDeleteRect2F(struct RTree_Rect *r, union RTree_Child child, struct RTree *t,
		 struct RTree_ListNode **ee)
{
    int i, notfound = 1, currlevel;
    struct RTree_Node *n;
    int top = 0, down = 0;
    int minfill;
    struct nstack *s = t->ns;

    struct RTree_Rect *nr = &(t->orect);

    /* add root node position to stack */
    currlevel = t->rootlevel;
    s[top].pos = t->rootpos;
    s[top].sn = RTreeGetNode(s[top].pos, currlevel, t);
    s[top].branch_id = 0;

    while (notfound && top >= 0) {
	/* go down to level 0, remember path */
	if (s[top].sn->level > 0) {
	    n = s[top].sn;
	    currlevel = s[top].sn->level - 1;
	    for (i = s[top].branch_id; i < t->nodecard; i++) {
		if (n->branch[i].child.pos > -1 &&
		    RTreeOverlap(r, &(n->branch[i].rect), t)) {
		    s[top++].branch_id = i + 1;
		    /* add next node to stack */
		    s[top].pos = n->branch[i].child.pos;
		    s[top].sn = RTreeGetNode(s[top].pos, currlevel, t);
		    s[top].branch_id = 0;

		    notfound = 0;
		    break;
		}
	    }
	    if (notfound) {
		/* nothing else found, go back up */
		s[top].branch_id = t->nodecard;
		top--;
	    }
	    else       /* found a way down but not yet the item */
		notfound = 1;
	}
	else {
	    for (i = 0; i < t->leafcard; i++) {
		if (s[top].sn->branch[i].child.id &&
		    s[top].sn->branch[i].child.id == child.id) { /* found item */
		    RTreeDisconnectBranch(s[top].sn, i, t);
		    RTreeNodeChanged(s[top].sn, s[top].pos, t);
		    t->n_leafs--;
		    notfound = 0;
		    break;
		}
	    }
	    if (notfound)    /* continue searching */
		top--;
	}
    }

    if (notfound) {
	return notfound;
    }

    /* go back up */
    while (top) {
	down = top;
	top--;
	i = s[top].branch_id - 1;

	minfill = (s[down].sn->level ? t->min_node_fill : t->min_leaf_fill);
	if (s[down].sn->count >= minfill) {
	    /* just update node cover */
	    RTreeNodeCover(s[down].sn, nr, t);
	    /* rewrite rect */
	    if (!RTreeCompareRect(nr, &(s[top].sn->branch[i].rect), t)) {
		RTreeCopyRect(&(s[top].sn->branch[i].rect), nr, t);
		RTreeNodeChanged(s[top].sn, s[top].pos, t);
	    }
	}
	else {
	    /* not enough entries in child, eliminate child node */
	    n = RTreeAllocNode(t, s[down].sn->level);
	    /* copy node */
	    RTreeCopyNode(n, s[down].sn, t);
	    RTreeAddNodePos(s[down].pos, s[down].sn->level, t);
	    RTreeReInsertNode(n, ee);
	    RTreeDisconnectBranch(s[top].sn, i, t);

	    RTreeNodeChanged(s[top].sn, s[top].pos, t);
	}
    }

    return notfound;
}
Beispiel #7
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 actual insertion.
 */
int RTreeInsertRectF(struct RTree_Rect *r, union RTree_Child child, int level,
                     struct RTree *t)
{
    struct RTree_ListBranch *reInsertList = NULL;
    struct RTree_ListBranch *e;
    int result;
    char overflow[MAXLEVEL];
    struct RTree_Branch *b = &(t->tmpb1);
    off_t newnode_pos = -1;

    struct RTree_Node *oldroot;
    static struct RTree_Node *newroot = NULL, *newnode = NULL;
    
    if (!newroot) {
	newroot = RTreeAllocNode(t, 1);
	newnode = RTreeAllocNode(t, 1);
    }

    /* R*-tree forced reinsertion: for each level only once */
    memset(overflow, t->overflow, MAXLEVEL);

    result = RTreeInsertRect2F(r, child, level, newnode, &newnode_pos,
			       t, &reInsertList, overflow);

    if (result == 1) {	/* root split */
	oldroot = RTreeGetNode(t->rootpos, t->rootlevel, t);
	/* grow a new root, & tree taller */
	t->rootlevel++;
	RTreeInitNode(t, newroot, NODETYPE(t->rootlevel, t->fd));
	newroot->level = t->rootlevel;
	/* branch for old root */
	RTreeNodeCover(oldroot, &(b->rect), t);
	b->child.pos = t->rootpos;
	RTreeAddBranch(b, newroot, NULL, NULL, NULL, NULL, t);
	/* branch for new node created by RTreeInsertRect2() */
	RTreeNodeCover(newnode, &(b->rect), t);
	b->child.pos = newnode_pos;  /* offset to new node as returned by RTreeInsertRect2F() */
	RTreeAddBranch(b, newroot, NULL, NULL, NULL, NULL, t);
	/* write new root node */
	t->rootpos = RTreeGetNodePos(t);
	RTreeWriteNode(newroot, t);
	t->n_nodes++;

	return result;
    }

    if (result == 2) {	/* branches were removed */
	while (reInsertList) {
	    /* get next branch in list */
	    RTreeCopyBranch(b, &(reInsertList->b), t);
	    level = reInsertList->level;
	    e = reInsertList;
	    reInsertList = reInsertList->next;
	    RTreeFreeListBranch(e);
	    /* reinsert branches */
	    result =
		RTreeInsertRect2F(&(b->rect), b->child, level, newnode, &newnode_pos, t,
				 &reInsertList, overflow);

	    if (result == 1) {	/* root split */
		oldroot = RTreeGetNode(t->rootpos, t->rootlevel, t);
		/* grow a new root, & tree taller */
		t->rootlevel++;
		RTreeInitNode(t, newroot, NODETYPE(t->rootlevel, t->fd));
		newroot->level = t->rootlevel;
		/* branch for old root */
		RTreeNodeCover(oldroot, &(b->rect), t);
		b->child.pos = t->rootpos;
		RTreeAddBranch(b, newroot, NULL, NULL, NULL, NULL, t);
		/* branch for new node created by RTreeInsertRect2() */
		RTreeNodeCover(newnode, &(b->rect), t);
		b->child.pos = newnode_pos; 
		RTreeAddBranch(b, newroot, NULL, NULL, NULL, NULL, t);
		/* write new root node */
		t->rootpos = RTreeGetNodePos(t);
		RTreeWriteNode(newroot, t);
		t->n_nodes++;
	    }
	}
    }

    return result;
}
Beispiel #8
0
/*
 * Inserts a new data rectangle into the index structure.
 * Non-recursively descends tree, propagates splits back up.
 * Returns 0 if node was not split.  Old node updated.
 * If node was split, returns 1 and sets the pointer pointed to by
 * new_node to point to the new node.  Old node updated to become one of two.
 * 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.
 */
static int RTreeInsertRect2F(struct RTree_Rect *r, union RTree_Child child, int level, 
			     struct RTree_Node *newnode, off_t *newnode_pos,
			     struct RTree *t,
			     struct RTree_ListBranch **ee, char *overflow)
{
    int i, currlevel;
    struct RTree_Node *n, *n2;
    struct RTree_Rect *cover;
    int top = 0, down = 0;
    int result;
    struct RTree_Branch *b = &(t->tmpb2);
    struct nstack *s = t->ns;

    struct RTree_Rect *nr = &(t->orect);

    n2 = newnode;

    /* add root node position to stack */
    currlevel = t->rootlevel;
    s[top].pos = t->rootpos;
    s[top].sn = RTreeGetNode(s[top].pos, currlevel, t);

    /* go down to level of insertion */
    while (s[top].sn->level > level) {
	n = s[top].sn;
	currlevel = s[top].sn->level - 1;
	i = RTreePickBranch(r, n, t);
	s[top++].branch_id = i;
	/* add next node to stack */
	s[top].pos = n->branch[i].child.pos;
	s[top].sn = RTreeGetNode(s[top].pos, currlevel, t);
    }

    /* Have reached level for insertion. Add rect, split if necessary */
    RTreeCopyRect(&(b->rect), r, t);
    /* child field of leaves contains tid of data record */
    b->child = child;
    /* add branch, may split node or remove branches */
    cover = NULL;
    if (top)
	cover = &(s[top - 1].sn->branch[s[top - 1].branch_id].rect);
    result = RTreeAddBranch(b, s[top].sn, &n2, ee, cover, overflow, t);
    /* update node */
    RTreeNodeChanged(s[top].sn, s[top].pos, t);
    /* write out new node if node was split */
    if (result == 1) {
	*newnode_pos = RTreeGetNodePos(t);
	RTreeWriteNode(n2, t);
	t->n_nodes++;
    }

    /* go back up */
    while (top) {
	down = top--;
	i = s[top].branch_id;
	if (result == 0) {        /* branch was added */
	    if (RTreeExpandRect(&(s[top].sn->branch[i].rect), r, t)) {
		RTreeNodeChanged(s[top].sn, s[top].pos, t);
	    }
	}
	else if (result == 2) {	/* branches were removed */
	    /* get node cover of previous node */
	    RTreeNodeCover(s[down].sn, nr, t);
	    /* rewrite rect */
	    if (!RTreeCompareRect(nr, &(s[top].sn->branch[i].rect), t)) {
		RTreeCopyRect(&(s[top].sn->branch[i].rect), nr, t);
		RTreeNodeChanged(s[top].sn, s[top].pos, t);
	    }
	}
	else if (result == 1) {                /* node was split */
	    /* get node cover of previous node */
	    RTreeNodeCover(s[down].sn, &(s[top].sn->branch[i].rect), t);
	    /* add new branch for new node previously added by RTreeAddBranch() */
	    b->child.pos = *newnode_pos;
	    RTreeNodeCover(n2, &(b->rect), t);

	    /* add branch, may split node or remove branches */
	    cover = NULL;
	    if (top)
		cover = &(s[top - 1].sn->branch[s[top - 1].branch_id].rect);
	    result =
		RTreeAddBranch(b, s[top].sn, &n2, ee, cover, overflow, t);

	    /* update node */
	    RTreeNodeChanged(s[top].sn, s[top].pos, t);

	    /* write out new node if node was split */
	    if (result == 1) {
		*newnode_pos = RTreeGetNodePos(t);
		RTreeWriteNode(n2, t);
	 	t->n_nodes++;
	    }
	}
    }

    return result;
}