示例#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);
    }
}
示例#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;
        }
}
示例#3
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;
}