瀏覽代碼

huhabla: rtree dynamic memory allocation

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@54107 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 12 年之前
父節點
當前提交
71a0372692

+ 31 - 29
lib/vector/diglib/spindex_rw.c

@@ -615,12 +615,10 @@ static int rtree_dump_branch_file(FILE * fp, struct RTree_Branch *b, int with_z,
 int rtree_dump_node_file(FILE * fp, off_t pos, int with_z, struct RTree *t)
 {
     int i;
-    static struct RTree_Node n;
-    static int node_init = 0;
+    static struct RTree_Node *n = NULL;
     
-    if (!node_init) {
-	for (i = 0; i < MAXCARD; i++)
-	    n.branch[i].rect.boundary = RTreeAllocBoundary(t);
+    if (!n) {
+	n = RTreeAllocNode(t, 1);
     }
 
     /* recursive nearly-but-a-bit-messy depth-first pre-order traversal
@@ -628,21 +626,21 @@ int rtree_dump_node_file(FILE * fp, off_t pos, int with_z, struct RTree *t)
     /* TODO: change to non-recursive depth-first post-order traversal */
     /* left for comparison with GRASS6.x */
 
-    RTreeReadNode(&n, pos, t);
-    fprintf(fp, "Node level=%d  count=%d\n", n.level, n.count);
+    RTreeReadNode(n, pos, t);
+    fprintf(fp, "Node level=%d  count=%d\n", n->level, n->count);
 
-    if (n.level > 0)
+    if (n->level > 0)
 	for (i = 0; i < NODECARD; i++) {
-	    if (n.branch[i].child.pos >= 0) {
+	    if (n->branch[i].child.pos >= 0) {
 		fprintf(fp, "  Branch %d", i);
-		rtree_dump_branch_file(fp, &n.branch[i], with_z, n.level, t);
+		rtree_dump_branch_file(fp, &(n->branch[i]), with_z, n->level, t);
 	    }
 	}
     else
 	for (i = 0; i < LEAFCARD; i++) {
-	    if (n.branch[i].child.id) {
+	    if (n->branch[i].child.id) {
 		fprintf(fp, "  Branch %d", i);
-		rtree_dump_branch_file(fp, &n.branch[i], with_z, n.level, t);
+		rtree_dump_branch_file(fp, &(n->branch[i]), with_z, n->level, t);
 	    }
 	}
 
@@ -691,7 +689,7 @@ static off_t rtree_write_from_memory(struct gvfile *fp, off_t startpos,
     int sidx_nodesize, sidx_leafsize;
     struct RTree_Node *n;
     int i, j, writeout, maxcard;
-    struct spidxpstack s[MAXLEVEL];
+    struct spidxpstack *s = G_malloc(MAXLEVEL * sizeof(struct spidxstack));
     int top = 0;
 
     /* should be foolproof */
@@ -768,6 +766,8 @@ static off_t rtree_write_from_memory(struct gvfile *fp, off_t startpos,
 	    }
 	}
     }
+    
+    G_free(s);
 
     return nextfreepos;
 }
@@ -793,21 +793,19 @@ static off_t rtree_write_from_file(struct gvfile *fp, off_t startpos,
     int sidx_nodesize, sidx_leafsize;
     struct RTree_Node *n;
     int i, j, writeout, maxcard;
-    static struct spidxstack s[MAXLEVEL];
-    static int stack_init = 0;
+    static struct spidxstack *s = NULL;
     int top = 0;
     
-    if (!stack_init) {
+    if (!s) {
+	s = G_malloc(MAXLEVEL * sizeof(struct spidxstack));
 	for (i = 0; i < MAXLEVEL; i++) {
+	    s[i].sn.branch = G_malloc(MAXCARD * sizeof(struct RTree_Branch));
 	    for (j = 0; j < MAXCARD; j++) {
 		s[i].sn.branch[j].rect.boundary = G_malloc(6 * sizeof(RectReal));
 	    }
 	}
-	stack_init = 1;
     }
 
-
-
     /* write pending changes to file */
     RTreeFlushBuffer(t);
 
@@ -915,17 +913,17 @@ static void rtree_load_to_memory(struct gvfile *fp, off_t rootpos,
     struct RTree_Node *newnode = NULL;
     int i, j, loadnode, maxcard;
     struct spidxstack *last;
-    static struct spidxstack s[MAXLEVEL];
-    static int stack_init = 0;
+    static struct spidxstack *s = NULL;
     int top = 0;
 
-    if (!stack_init) {
+    if (!s) {
+	s = G_malloc(MAXLEVEL * sizeof(struct spidxstack));
 	for (i = 0; i < MAXLEVEL; i++) {
+	    s[i].sn.branch = G_malloc(MAXCARD * sizeof(struct RTree_Branch));
 	    for (j = 0; j < MAXCARD; j++) {
 		s[i].sn.branch[j].rect.boundary = G_malloc(6 * sizeof(RectReal));
 	    }
 	}
-	stack_init = 1;
     }
 
     /* stack size of t->rootlevel + 1 would be enough because of
@@ -1041,17 +1039,17 @@ static void rtree_load_to_file(struct gvfile *fp, off_t rootpos,
     off_t newnode_pos = -1;
     int i, j, loadnode, maxcard;
     struct spidxstack *last;
-    static struct spidxstack s[MAXLEVEL];
-    static int stack_init = 0;
+    static struct spidxstack *s = NULL;
     int top = 0;
 
-    if (!stack_init) {
+    if (!s) {
+	s = G_malloc(MAXLEVEL * sizeof(struct spidxstack));
 	for (i = 0; i < MAXLEVEL; i++) {
+	    s[i].sn.branch = G_malloc(MAXCARD * sizeof(struct RTree_Branch));
 	    for (j = 0; j < MAXCARD; j++) {
 		s[i].sn.branch[j].rect.boundary = G_malloc(6 * sizeof(RectReal));
 	    }
 	}
-	stack_init = 1;
     }
 	
     /* stack size of t->rootlevel + 1 would be enough because of
@@ -1343,10 +1341,12 @@ static struct RTree_Node *rtree_get_node(off_t nodepos, int level,
     int which, i = 0;
 
     /* check mru first */
+    /* t->used[level][i] */
     while (t->nb[level][t->used[level][i]].pos != nodepos &&
-           t->nb[level][t->used[level][i]].pos >= 0 &&
-	   i < NODE_BUFFER_SIZE - 1)
+	   t->nb[level][t->used[level][i]].pos >= 0 &&
+	   i < NODE_BUFFER_SIZE - 1) {
 	i++;
+    }
 
     which = t->used[level][i];
 
@@ -1355,6 +1355,8 @@ static struct RTree_Node *rtree_get_node(off_t nodepos, int level,
 	t->nb[level][which].pos = nodepos;
     }
     assert(t->nb[level][which].n.level == level);
+
+
     /* make it mru */
     if (i) { /* t->used[level][0] != which */
 #if 0

+ 15 - 6
lib/vector/rtree/index.c

@@ -110,19 +110,19 @@ struct RTree *RTreeCreateTree(int fd, off_t rootpos, int ndims)
 	    new_rtree->nb[i] = new_rtree->nb[i - 1] + NODE_BUFFER_SIZE;
 	}
 
+	new_rtree->used = malloc(MAXLEVEL * sizeof(int *));
+	new_rtree->used[0] = malloc(MAXLEVEL * NODE_BUFFER_SIZE * sizeof(int));
 	for (i = 0; i < MAXLEVEL; i++) {
-
-	    /*
-	    for (j = 0; j < MAXCARD; j++) {
-		new_rtree->fs[i].sn.branch[j].rect.boundary = RTreeAllocBoundary(new_rtree);
-	    }
-	    */
+	    if (i)
+		new_rtree->used[i] = new_rtree->used[i - 1] + NODE_BUFFER_SIZE;
 	    for (j = 0; j < NODE_BUFFER_SIZE; j++) {
 		new_rtree->nb[i][j].dirty = 0;
 		new_rtree->nb[i][j].pos = -1;
 		/* usage order */
 		new_rtree->used[i][j] = j;
 
+		new_rtree->nb[i][j].n.branch = malloc(MAXCARD * sizeof(struct RTree_Branch));
+
 		/* alloc memory for rectangles */
 		for (k = 0; k < MAXCARD; k++) {
 		    new_rtree->nb[i][j].n.branch[k].rect.boundary = RTreeAllocBoundary(new_rtree);
@@ -166,12 +166,16 @@ struct RTree *RTreeCreateTree(int fd, off_t rootpos, int ndims)
     new_rtree->n_leafs = 0;
 
     /* initialize temp variables */
+    new_rtree->ns = malloc(MAXLEVEL * sizeof(struct nstack));
+    
     new_rtree->p.cover[0].boundary = RTreeAllocBoundary(new_rtree);
     new_rtree->p.cover[1].boundary = RTreeAllocBoundary(new_rtree);
     
     new_rtree->tmpb1.rect.boundary = RTreeAllocBoundary(new_rtree);
     new_rtree->tmpb2.rect.boundary = RTreeAllocBoundary(new_rtree);
     new_rtree->c.rect.boundary = RTreeAllocBoundary(new_rtree);
+
+    new_rtree->BranchBuf = malloc((MAXCARD + 1) * sizeof(struct RTree_Branch));
     for (i = 0; i <= MAXCARD; i++) {
 	new_rtree->BranchBuf[i].rect.boundary = RTreeAllocBoundary(new_rtree);
     }
@@ -226,11 +230,15 @@ void RTreeDestroyTree(struct RTree *t)
 	    free(t->free_nodes.pos);
 	free(t->nb[0]);
 	free(t->nb);
+	free(t->used[0]);
+	free(t->used);
     }
     else if (t->root)
 	RTreeDestroyNode(t->root, t->root->level ? t->nodecard : t->leafcard);
 
     /* free temp variables */
+    free(t->ns);
+    
     RTreeFreeBoundary(&(t->p.cover[0]));
     RTreeFreeBoundary(&(t->p.cover[1]));
     
@@ -240,6 +248,7 @@ void RTreeDestroyTree(struct RTree *t)
     for (i = 0; i <= MAXCARD; i++) {
         RTreeFreeBoundary(&(t->BranchBuf[i].rect));
     }
+    free(t->BranchBuf);
     RTreeFreeBoundary(&(t->rect_0));
     RTreeFreeBoundary(&(t->rect_1));
     RTreeFreeBoundary(&(t->upperrect));

+ 0 - 2
lib/vector/rtree/index.h

@@ -111,9 +111,7 @@ int RTreeGetLeafMax(struct RTree *);
 /* io.c */
 struct RTree_Node *RTreeGetNode(off_t, int, struct RTree *);
 void RTreeNodeChanged(struct RTree_Node *, off_t , struct RTree *);
-void RTreePutNode(struct RTree_Node *, off_t, struct RTree *);
 size_t RTreeRewriteNode(struct RTree_Node *, off_t, struct RTree *);
-void RTreeUpdateRect(struct RTree_Rect *, struct RTree_Node *, off_t, int, struct RTree *);
 void RTreeAddNodePos(off_t, int, struct RTree *);
 
 #endif /* _INDEX_ */

+ 31 - 97
lib/vector/rtree/indexf.c

@@ -42,7 +42,7 @@ int RTreeSearchF(struct RTree *t, struct RTree_Rect *r,
     int hitCount = 0, notfound, currlevel;
     int i;
     int top = 0;
-    struct fstack *s = t->fs;
+    struct nstack *s = t->ns;
 
     /* stack size of t->rootlevel + 1 is enough because of depth first search */
     /* only one node per level on stack at any given time */
@@ -51,7 +51,6 @@ int RTreeSearchF(struct RTree *t, struct RTree_Rect *r,
     currlevel = t->rootlevel;
     s[top].pos = t->rootpos;
     s[top].sn = RTreeGetNode(s[top].pos, currlevel, t);
-    /* RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t); */
     s[top].branch_id = i = 0;
     
     while (top >= 0) {
@@ -66,7 +65,6 @@ int RTreeSearchF(struct RTree *t, struct RTree_Rect *r,
 		    /* add next node to stack */
 		    s[top].pos = n->branch[i].child.pos;
 		    s[top].sn = RTreeGetNode(s[top].pos, currlevel, t);
-		    /* RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t); */
 		    s[top].branch_id = 0;
 		    notfound = 0;
 		    break;
@@ -119,28 +117,16 @@ static int RTreeInsertRect2F(struct RTree_Rect *r, union RTree_Child child, int
     int top = 0, down = 0;
     int result;
     struct RTree_Branch *b = &(t->tmpb2);
-    struct fstack *s = t->fs;
+    struct nstack *s = t->ns;
 
-    static struct RTree_Node nn;
-    static struct RTree_Rect nr;
-    static int rect_init = 0;
-    
-    if (!rect_init) {
-	for (i = 0; i < MAXCARD; i++) {
-	    nn.branch[i].rect.boundary = RTreeAllocBoundary(t);
-	}
-	nr.boundary = RTreeAllocBoundary(t);
-	rect_init = t->ndims_alloc;
-    }
+    struct RTree_Rect *nr = &(t->orect);
 
-    n2 = &nn;
-    /* n2 = newnode; */
+    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);
-    /* RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t); */
 
     /* go down to level of insertion */
     while (s[top].sn->level > level) {
@@ -151,10 +137,7 @@ static int RTreeInsertRect2F(struct RTree_Rect *r, union RTree_Child child, int
 	/* add next node to stack */
 	s[top].pos = n->branch[i].child.pos;
 	s[top].sn = RTreeGetNode(s[top].pos, currlevel, t);
-	/* RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t); */
-	assert(s[top].sn->level == currlevel);
     }
-    assert(s[top].sn->level == level);
 
     /* Have reached level for insertion. Add rect, split if necessary */
     RTreeCopyRect(&(b->rect), r, t);
@@ -166,7 +149,6 @@ static int RTreeInsertRect2F(struct RTree_Rect *r, union RTree_Child child, int
 	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 */
-    /* RTreePutNode(&(s[top].sn), s[top].pos, t); */
     RTreeNodeChanged(s[top].sn, s[top].pos, t);
     /* write out new node if node was split */
     if (result == 1) {
@@ -180,24 +162,16 @@ static int RTreeInsertRect2F(struct RTree_Rect *r, union RTree_Child child, int
 	down = top--;
 	i = s[top].branch_id;
 	if (result == 0) {        /* branch was added */
-	    RTreeCombineRect(&(s[top].sn->branch[i].rect), r, &nr, t);
-	    /* rewrite rect */
-	    /*
-	    if (!RTreeCompareRect(&nr, &(s[top].sn.branch[i].rect), t)) {
-		RTreeUpdateRect(&nr, &(s[top].sn), s[top].pos, i, t);
-	    }
-	    */
 	    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);
+	    RTreeNodeCover(s[down].sn, nr, t);
 	    /* rewrite rect */
-	    if (!RTreeCompareRect(&nr, &(s[top].sn->branch[i].rect), t)) {
-		/* RTreeUpdateRect(&nr, &(s[top].sn), s[top].pos, i, t); */
-		RTreeCopyRect(&(s[top].sn->branch[i].rect), &nr, t);
+	    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);
 	    }
 	}
@@ -216,7 +190,6 @@ static int RTreeInsertRect2F(struct RTree_Rect *r, union RTree_Child child, int
 		RTreeAddBranch(b, s[top].sn, &n2, ee, cover, overflow, t);
 
 	    /* update node */
-	    /* RTreePutNode(&(s[top].sn), s[top].pos, t); */
 	    RTreeNodeChanged(s[top].sn, s[top].pos, t);
 
 	    /* write out new node if node was split */
@@ -228,9 +201,6 @@ static int RTreeInsertRect2F(struct RTree_Rect *r, union RTree_Child child, int
 	}
     }
 
-    /* copy node */
-    RTreeCopyNode(newnode, n2, t);
-
     return result;
 }
 
@@ -247,48 +217,42 @@ int RTreeInsertRectF(struct RTree_Rect *r, union RTree_Child child, int level,
 {
     struct RTree_ListBranch *reInsertList = NULL;
     struct RTree_ListBranch *e;
-    int i, result;
+    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, newnode;
-    static int rect_init = 0;
+    static struct RTree_Node *newroot = NULL, *newnode = NULL;
     
-    if (!rect_init) {
-	for (i = 0; i < MAXCARD; i++) {
-	    /* oldroot.branch[i].rect.boundary = RTreeAllocBoundary(t); */
-	    newroot.branch[i].rect.boundary = RTreeAllocBoundary(t);
-	    newnode.branch[i].rect.boundary = RTreeAllocBoundary(t);
-	}
-	rect_init = t->ndims_alloc;
+    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,
+    result = RTreeInsertRect2F(r, child, level, newnode, &newnode_pos,
 			       t, &reInsertList, overflow);
 
     if (result == 1) {	/* root split */
 	oldroot = RTreeGetNode(t->rootpos, t->rootlevel, t);
-	/* RTreeGetNode(&oldroot, 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;
+	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);
+	RTreeAddBranch(b, newroot, NULL, NULL, NULL, NULL, t);
 	/* branch for new node created by RTreeInsertRect2() */
-	RTreeNodeCover(&newnode, &(b->rect), t);
+	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);
+	RTreeAddBranch(b, newroot, NULL, NULL, NULL, NULL, t);
 	/* write new root node */
 	t->rootpos = RTreeGetNodePos(t);
-	RTreeWriteNode(&newroot, t);
+	RTreeWriteNode(newroot, t);
 	t->n_nodes++;
 
 	return result;
@@ -304,27 +268,26 @@ int RTreeInsertRectF(struct RTree_Rect *r, union RTree_Child child, int level,
 	    RTreeFreeListBranch(e);
 	    /* reinsert branches */
 	    result =
-		RTreeInsertRect2F(&(b->rect), b->child, level, &newnode, &newnode_pos, t,
+		RTreeInsertRect2F(&(b->rect), b->child, level, newnode, &newnode_pos, t,
 				 &reInsertList, overflow);
 
 	    if (result == 1) {	/* root split */
 		oldroot = RTreeGetNode(t->rootpos, t->rootlevel, t);
-		/* RTreeGetNode(&oldroot, 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;
+		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);
+		RTreeAddBranch(b, newroot, NULL, NULL, NULL, NULL, t);
 		/* branch for new node created by RTreeInsertRect2() */
-		RTreeNodeCover(&newnode, &(b->rect), t);
+		RTreeNodeCover(newnode, &(b->rect), t);
 		b->child.pos = newnode_pos; 
-		RTreeAddBranch(b, &newroot, NULL, NULL, NULL, NULL, t);
+		RTreeAddBranch(b, newroot, NULL, NULL, NULL, NULL, t);
 		/* write new root node */
 		t->rootpos = RTreeGetNodePos(t);
-		RTreeWriteNode(&newroot, t);
+		RTreeWriteNode(newroot, t);
 		t->n_nodes++;
 	    }
 	}
@@ -347,23 +310,14 @@ RTreeDeleteRect2F(struct RTree_Rect *r, union RTree_Child child, struct RTree *t
     struct RTree_Node *n;
     int top = 0, down = 0;
     int minfill;
-    struct fstack *s = t->fs;
+    struct nstack *s = t->ns;
 
-    static struct RTree_Rect nr;
-    static int rect_init = 0;
-    
-    assert(ee);
-    
-    if (!rect_init) {
-	nr.boundary = RTreeAllocBoundary(t);
-	rect_init = 1;
-    }
+    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);
-    /* RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t); */
     s[top].branch_id = 0;
 
     while (notfound && top >= 0) {
@@ -378,7 +332,6 @@ RTreeDeleteRect2F(struct RTree_Rect *r, union RTree_Child child, struct RTree *t
 		    /* add next node to stack */
 		    s[top].pos = n->branch[i].child.pos;
 		    s[top].sn = RTreeGetNode(s[top].pos, currlevel, t);
-		    /* RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t); */
 		    s[top].branch_id = 0;
 
 		    notfound = 0;
@@ -398,7 +351,6 @@ RTreeDeleteRect2F(struct RTree_Rect *r, union RTree_Child child, struct RTree *t
 		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);
-		    /* RTreePutNode(&(s[top].sn), s[top].pos, t); */
 		    RTreeNodeChanged(s[top].sn, s[top].pos, t);
 		    t->n_leafs--;
 		    notfound = 0;
@@ -419,22 +371,19 @@ RTreeDeleteRect2F(struct RTree_Rect *r, union RTree_Child child, struct RTree *t
 	down = top;
 	top--;
 	i = s[top].branch_id - 1;
-	assert(s[down].sn->level == s[top].sn->level - 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);
+	    RTreeNodeCover(s[down].sn, nr, t);
 	    /* rewrite rect */
-	    if (!RTreeCompareRect(&nr, &(s[top].sn->branch[i].rect), t)) {
-		/* RTreeUpdateRect(&nr, &(s[top].sn), s[top].pos, i, t); */
-		RTreeCopyRect(&(s[top].sn->branch[i].rect), &nr, t);
+	    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 */
-	    assert(s[top].sn->branch[i].child.pos == s[down].pos);
 	    n = RTreeAllocNode(t, s[down].sn->level);
 	    /* copy node */
 	    RTreeCopyNode(n, s[down].sn, t);
@@ -442,7 +391,6 @@ RTreeDeleteRect2F(struct RTree_Rect *r, union RTree_Child child, struct RTree *t
 	    RTreeReInsertNode(n, ee);
 	    RTreeDisconnectBranch(s[top].sn, i, t);
 
-	    /* RTreePutNode(&(s[top].sn), s[top].pos, t); */
 	    RTreeNodeChanged(s[top].sn, s[top].pos, t);
 	}
     }
@@ -464,16 +412,6 @@ int RTreeDeleteRectF(struct RTree_Rect *r, union RTree_Child child, struct RTree
     struct RTree_Node *n;
     struct RTree_ListNode *e, *reInsertList = NULL;
 
-    static struct RTree_Node rn;
-    static int rect_init = 0;
-    
-    if (!rect_init) {
-	for (i = 0; i < MAXCARD; i++) {
-	    rn.branch[i].rect.boundary = RTreeAllocBoundary(t);
-	}
-	rect_init = 1;
-    }
-
     if (!RTreeDeleteRect2F(r, child, t, &reInsertList)) {
 	/* found and deleted a data item */
 
@@ -505,10 +443,6 @@ int RTreeDeleteRectF(struct RTree_Rect *r, union RTree_Child child, struct RTree
 
 	/* check for redundant root (not leaf, 1 child) and eliminate */
 	n = RTreeGetNode(t->rootpos, t->rootlevel, t);
-	/*
-	RTreeGetNode(&rn, t->rootpos, t->rootlevel, t);
-	n = &rn;
-	*/
 	
 	if (n->count == 1 && n->level > 0) {
 	    for (i = 0; i < t->nodecard; i++) {

+ 3 - 3
lib/vector/rtree/indexm.c

@@ -39,7 +39,7 @@ int RTreeSearchM(struct RTree *t, struct RTree_Rect *r,
     int hitCount = 0, notfound;
     int i;
     int top = 0;
-    struct mstack *s = t->ms;
+    struct nstack *s = t->ns;
 
     /* stack size of t->rootlevel + 1 is enough because of depth first search */
     /* only one node per level on stack at any given time */
@@ -111,7 +111,7 @@ static int RTreeInsertRect2M(struct RTree_Rect *r, union RTree_Child child, int
     int top = 0, down = 0;
     int result;
     struct RTree_Branch *b = &(t->tmpb2);
-    struct mstack *s = t->ms;
+    struct nstack *s = t->ns;
 
     /* add root node to stack */
     s[top].sn = t->root;
@@ -270,7 +270,7 @@ RTreeDeleteRect2M(struct RTree_Rect *r, union RTree_Child child, struct RTree *t
     struct RTree_Node *n;
     int top = 0, down = 0;
     int minfill;
-    struct mstack *s = t->ms;
+    struct nstack *s = t->ns;
 
     assert(ee);
 

+ 1 - 84
lib/vector/rtree/io.c

@@ -24,7 +24,7 @@
 #include <grass/config.h>
 #include "index.h"
 
-#define USAGE_SWAP
+/* #define USAGE_SWAP */
 
 /* add new free node position for recycling */
 void RTreeAddNodePos(off_t pos, int level, struct RTree *t)
@@ -50,7 +50,6 @@ void RTreeAddNodePos(off_t pos, int level, struct RTree *t)
     /* is it possible that this node is not in the buffer? */
     assert(i < NODE_BUFFER_SIZE);
     which = t->used[level][i];
-    assert(t->nb[level][which].n.level == level);
     t->nb[level][which].pos = -1;
     t->nb[level][which].dirty = 0;
     
@@ -123,8 +122,6 @@ struct RTree_Node *RTreeGetNode(off_t nodepos, int level, struct RTree *t)
     if (t->nb[level][which].pos != nodepos) {
 	/* rewrite node in buffer */
 	if (t->nb[level][which].dirty) {
-	    assert(t->nb[level][which].pos >= 0);
-	    assert(t->nb[level][which].n.level == level);
 	    RTreeRewriteNode(&(t->nb[level][which].n),
 	                     t->nb[level][which].pos, t);
 	    t->nb[level][which].dirty = 0;
@@ -132,7 +129,6 @@ struct RTree_Node *RTreeGetNode(off_t nodepos, int level, struct RTree *t)
 	RTreeReadNode(&(t->nb[level][which].n), nodepos, t);
 	t->nb[level][which].pos = nodepos;
     }
-    assert(t->nb[level][which].n.level == level);
     /* make it mru */
     if (i) { /* t->used[level][0] != which */
 #ifdef USAGE_SWAP
@@ -202,85 +198,6 @@ void RTreeNodeChanged(struct RTree_Node *n, off_t nodepos, struct RTree *t)
     /* as it is used, it should always be mru */
     assert(i == 0);
     which = t->used[n->level][i];
-    assert(t->nb[n->level][which].n.level == n->level);
-
-    t->nb[n->level][which].dirty = 1;
-
-    /* make it mru */
-    if (i) { /* t->used[level][0] != which */
-#ifdef USAGE_SWAP
-	t->used[n->level][i] = t->used[n->level][0];
-	t->used[n->level][0] = which;
-#else
-	while (i) {
-	    t->used[n->level][i] = t->used[n->level][i - 1];
-	    i--;
-	}
-	t->used[n->level][0] = which;
-#endif
-    }
-}
-
-/* update node in buffer */
-void RTreePutNode(struct RTree_Node *n, off_t nodepos, struct RTree *t)
-{
-    int which, i = 0;
-
-    /* check mru first */
-    while (t->nb[n->level][t->used[n->level][i]].pos != nodepos &&
-           i < NODE_BUFFER_SIZE)
-	i++;
-
-    assert(i < NODE_BUFFER_SIZE);
-    /* as it is used, it should always be mru */
-    assert(i == 0);
-    which = t->used[n->level][i];
-
-    assert(t->nb[n->level][which].n.level == n->level);
-    /* copy node */
-    RTreeCopyNode(&(t->nb[n->level][which].n), n, t);
-    t->nb[n->level][which].dirty = 1;
-
-    /* make it mru */
-    if (i) { /* t->used[level][0] != which */
-#ifdef USAGE_SWAP
-	t->used[n->level][i] = t->used[n->level][0];
-	t->used[n->level][0] = which;
-#else
-	while (i) {
-	    t->used[n->level][i] = t->used[n->level][i - 1];
-	    i--;
-	}
-	t->used[n->level][0] = which;
-#endif
-    }
-}
-
-/* update rectangle */
-void RTreeUpdateRect(struct RTree_Rect *r, struct RTree_Node *n,
-                     off_t nodepos, int b, struct RTree *t)
-{
-    int i, j, k, which;
-
-    /* check mru first */
-    i = 0;
-    while (t->nb[n->level][t->used[n->level][i]].pos != nodepos &&
-           i < NODE_BUFFER_SIZE)
-	i++;
-
-    assert(i < NODE_BUFFER_SIZE);
-    /* as it is used, it should always be mru */
-    assert(i == 0);
-    which = t->used[n->level][i];
-
-    assert(t->nb[n->level][which].n.level == n->level);
-    for (j = 0; j < t->ndims_alloc; j++) {
-	t->nb[n->level][which].n.branch[b].rect.boundary[j] =
-	                  n->branch[b].rect.boundary[j] = r->boundary[j];
-	k = j + t->ndims_alloc;
-	t->nb[n->level][which].n.branch[b].rect.boundary[k] =
-	                  n->branch[b].rect.boundary[k] = r->boundary[k];
-    }
 
     t->nb[n->level][which].dirty = 1;
 

+ 3 - 0
lib/vector/rtree/node.c

@@ -81,6 +81,8 @@ struct RTree_Node *RTreeAllocNode(struct RTree *t, int level)
 
     n->count = 0;
     n->level = level;
+    
+    n->branch = malloc(MAXCARD * sizeof(struct RTree_Branch));
 
     for (i = 0; i < MAXCARD; i++) {
 	n->branch[i].rect.boundary = RTreeAllocBoundary(t);
@@ -99,6 +101,7 @@ void RTreeFreeNode(struct RTree_Node *n)
     for (i = 0; i < MAXCARD; i++)
 	RTreeFreeBoundary(&(n->branch[i].rect));
 
+    free(n->branch);
     free(n);
 }
 

+ 8 - 16
lib/vector/rtree/rtree.h

@@ -52,7 +52,7 @@ typedef double RectReal;
 #define MAXLEVEL 20        /* 8^MAXLEVEL items are guaranteed to fit into the tree */
 
 /* number of nodes buffered per level */
-#define NODE_BUFFER_SIZE 8
+#define NODE_BUFFER_SIZE 32
 
 struct RTree_Rect
 {
@@ -78,7 +78,7 @@ struct RTree_Node       /* node for spatial index */
 {
     int count;          /* number of branches */
     int level;		/* 0 is leaf, others positive */
-    struct RTree_Branch branch[MAXCARD];
+    struct RTree_Branch *branch;
 };
 
 /*
@@ -99,20 +99,13 @@ typedef int rt_delete_fn(struct RTree_Rect *, union RTree_Child, struct RTree *)
 typedef int rt_valid_child_fn(union RTree_Child *);
 
 /* temp vars for each tree */
-/* stacks used for non-recursive insertion/deletion */
-/* stack for file-based index */
-struct fstack
+/* node stack used for non-recursive insertion/deletion */
+struct nstack
 {
     struct RTree_Node *sn;	/* stack node */
     int branch_id;		/* branch number to follow down */
     off_t pos;			/* file position of stack node */
 };
-/* stack for memory-based index */
-struct mstack
-{
-    struct RTree_Node *sn;	/* stack node pointer */
-    int branch_id;		/* branch number to follow down */
-};
 
 /* node buffer for file-based index */
 struct NodeBuffer
@@ -171,7 +164,7 @@ struct RTree
     /* usage order of buffered nodes per level
      * used[level][0] = most recently used
      * used[level][NODE_BUFFER_SIZE - 1] = least recently used */
-    int used[MAXLEVEL][NODE_BUFFER_SIZE];
+    int **used;
 
     /* insert, delete, search */
     rt_insert_fn *insert_rect;
@@ -183,13 +176,12 @@ struct RTree
 
     /* internal variables, specific for each tree,
      * allocated with tree initialization */
-    /* stacks for tree traversal */
-    struct mstack ms[MAXLEVEL];
-    struct fstack fs[MAXLEVEL];
+    /* node stack for tree traversal */
+    struct nstack *ns;
     
     /* variables for splitting / forced reinsertion */
     struct RTree_PartitionVars p;
-    struct RTree_Branch BranchBuf[MAXCARD + 1];
+    struct RTree_Branch *BranchBuf;
 
     struct RTree_Branch tmpb1, tmpb2, c;
     int BranchCount;