[GRASS-SVN] r53797 - grass/trunk/lib/vector/rtree

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Nov 13 23:20:31 PST 2012


Author: mmetz
Date: 2012-11-13 23:20:30 -0800 (Tue, 13 Nov 2012)
New Revision: 53797

Modified:
   grass/trunk/lib/vector/rtree/index.c
   grass/trunk/lib/vector/rtree/index.h
   grass/trunk/lib/vector/rtree/indexf.c
   grass/trunk/lib/vector/rtree/indexm.c
   grass/trunk/lib/vector/rtree/io.c
   grass/trunk/lib/vector/rtree/rect.c
Log:
rtree bug fixes

Modified: grass/trunk/lib/vector/rtree/index.c
===================================================================
--- grass/trunk/lib/vector/rtree/index.c	2012-11-14 06:19:02 UTC (rev 53796)
+++ grass/trunk/lib/vector/rtree/index.c	2012-11-14 07:20:30 UTC (rev 53797)
@@ -130,10 +130,6 @@
 	/* write empty root node */
 	lseek(new_rtree->fd, rootpos, SEEK_SET);
 	RTreeWriteNode(n, new_rtree);
-	new_rtree->nb[0][0].n = *n;
-	new_rtree->nb[0][0].pos = rootpos;
-	new_rtree->used[0][0] = 0;
-	new_rtree->used[0][2] = 2;
 	RTreeFreeNode(n);
 
 	new_rtree->insert_rect = RTreeInsertRectF;

Modified: grass/trunk/lib/vector/rtree/index.h
===================================================================
--- grass/trunk/lib/vector/rtree/index.h	2012-11-14 06:19:02 UTC (rev 53796)
+++ grass/trunk/lib/vector/rtree/index.h	2012-11-14 07:20:30 UTC (rev 53797)
@@ -90,7 +90,7 @@
 RectReal RTreeRectVolume(struct RTree_Rect *, struct RTree *);
 RectReal RTreeRectMargin(struct RTree_Rect *, struct RTree *);
 void RTreeCombineRect(struct RTree_Rect *, struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
-void RTreeExpandRect(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
+int RTreeExpandRect(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
 int RTreeCompareRect(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
 
 /*-----------------------------------------------------------------------------

Modified: grass/trunk/lib/vector/rtree/indexf.c
===================================================================
--- grass/trunk/lib/vector/rtree/indexf.c	2012-11-14 06:19:02 UTC (rev 53796)
+++ grass/trunk/lib/vector/rtree/indexf.c	2012-11-14 07:20:30 UTC (rev 53797)
@@ -21,7 +21,6 @@
 #include <string.h>
 #include <sys/types.h>
 #include <assert.h>
-#include <grass/config.h>
 #include <grass/gis.h>
 #include "index.h"
 //#include "card.h"
@@ -55,8 +54,8 @@
     s[top].branch_id = i = 0;
     
     while (top >= 0) {
+	n = &(s[top].sn);
 	if (s[top].sn.level > 0) {		/* this is an internal node in the tree */
-	    n = &(s[top].sn);
 	    notfound = 1;
 	    currlevel = s[top].sn.level - 1;
 	    for (i = s[top].branch_id; i < t->nodecard; i++) {
@@ -113,11 +112,11 @@
 			     struct RTree_ListBranch **ee, char *overflow)
 {
     int i, currlevel;
+    struct RTree_Node *n, *n2;
     struct RTree_Rect *cover;
-    struct RTree_Node *n, *n2;
     int top = 0, down = 0;
+    int result;
     struct RTree_Branch *b = &(t->tmpb2);
-    int result;
     struct fstack *s = t->fs;
 
     static struct RTree_Node nn;
@@ -142,15 +141,16 @@
     /* 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;
-	currlevel--;
-	RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t);
+	RTreeGetNode(&(s[top].sn), s[top].pos, n->level - 1, 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);
     /* child field of leaves contains tid of data record */
@@ -160,21 +160,21 @@
     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 */
+    RTreePutNode(&(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++;
     }
-    /* update node */
-    RTreePutNode(&(s[top].sn), s[top].pos, t);
-    
+
     /* go back up */
     while (top) {
 	down = top--;
 	i = s[top].branch_id;
 	if (result == 0) {        /* branch was added */
-	    RTreeCombineRect(&(s[top].sn.branch[i].rect), &nr, r, t);
+	    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);
@@ -194,21 +194,23 @@
 	    /* 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);
-	    
+	    result =
+		RTreeAddBranch(b, &(s[top].sn), &n2, ee, cover, overflow, t);
+
+	    /* update node */
+	    RTreePutNode(&(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++;
 	    }
-	    /* update node */
-	    RTreePutNode(&(s[top].sn), s[top].pos, t);
 	}
     }
 
@@ -220,7 +222,7 @@
 
 /* 
  * Insert a data rectangle into an index structure.
- * RTreeInsertRect1 provides for splitting the root;
+ * 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.
@@ -229,13 +231,14 @@
 int RTreeInsertRectF(struct RTree_Rect *r, union RTree_Child child, int level,
                      struct RTree *t)
 {
-    struct RTree_ListBranch *e, *reInsertList = NULL;
+    struct RTree_ListBranch *reInsertList = NULL;
+    struct RTree_ListBranch *e;
     int i, result;
     char overflow[MAXLEVEL];
+    struct RTree_Branch *b = &(t->tmpb1);
     off_t newnode_pos = -1;
 
     static struct RTree_Node oldroot, newroot, newnode;
-    struct RTree_Branch *b = &(t->tmpb1);
     static int rect_init = 0;
     
     if (!rect_init) {
@@ -250,10 +253,9 @@
     /* 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);
-    
+    result = RTreeInsertRect2F(r, child, level, &newnode, &newnode_pos,
+			       t, &reInsertList, overflow);
+
     if (result == 1) {	/* root split */
 	RTreeGetNode(&oldroot, t->rootpos, t->rootlevel, t);
 	/* grow a new root, & tree taller */
@@ -264,7 +266,7 @@
 	RTreeNodeCover(&oldroot, &(b->rect), t);
 	b->child.pos = t->rootpos;
 	RTreeAddBranch(b, &newroot, NULL, NULL, NULL, NULL, t);
-	/* branch for new node created by RTreeInsertRect2F() */
+	/* 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);
@@ -272,7 +274,7 @@
 	t->rootpos = RTreeGetNodePos(t);
 	RTreeWriteNode(&newroot, t);
 	t->n_nodes++;
-	
+
 	return result;
     }
 
@@ -299,7 +301,7 @@
 		RTreeNodeCover(&oldroot, &(b->rect), t);
 		b->child.pos = t->rootpos;
 		RTreeAddBranch(b, &newroot, NULL, NULL, NULL, NULL, t);
-		/* branch for new node created by RTreeInsertRect2F() */
+		/* 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);
@@ -358,7 +360,7 @@
 		    s[top].pos = n->branch[i].child.pos;
 		    RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t);
 		    s[top].branch_id = 0;
-		    
+
 		    notfound = 0;
 		    break;
 		}
@@ -386,17 +388,18 @@
 		top--;
 	}
     }
-    
+
     if (notfound) {
 	return notfound;
     }
-    
+
     /* go back up */
     while (top) {
-	down = top--;
+	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 */
@@ -488,9 +491,9 @@
 	    t->rootpos = rn.branch[i].child.pos;
 	    t->rootlevel--;
 	}
+
 	return 0;
     }
 
     return 1;
 }
-

Modified: grass/trunk/lib/vector/rtree/indexm.c
===================================================================
--- grass/trunk/lib/vector/rtree/indexm.c	2012-11-14 06:19:02 UTC (rev 53796)
+++ grass/trunk/lib/vector/rtree/indexm.c	2012-11-14 07:20:30 UTC (rev 53797)
@@ -178,7 +178,7 @@
 
 /* 
  * Insert a data rectangle into an index structure.
- * RTreeInsertRectM provides for splitting the root;
+ * 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.
@@ -197,10 +197,9 @@
     /* R*-tree forced reinsertion: for each level only once */
     memset(overflow, t->overflow, MAXLEVEL);
 
-    result =
-	RTreeInsertRect2M(r, child, level, &newnode, t, &reInsertList,
-			 overflow);
-			 
+    result = RTreeInsertRect2M(r, child, level, &newnode, t,
+                               &reInsertList, overflow);
+
     if (result == 1) {		/* root split */
 	/* grow a new root, & tree taller */
 	t->rootlevel++;

Modified: grass/trunk/lib/vector/rtree/io.c
===================================================================
--- grass/trunk/lib/vector/rtree/io.c	2012-11-14 06:19:02 UTC (rev 53796)
+++ grass/trunk/lib/vector/rtree/io.c	2012-11-14 07:20:30 UTC (rev 53797)
@@ -38,7 +38,9 @@
 	assert(t->free_nodes.pos);
     }
     t->free_nodes.pos[t->free_nodes.avail++] = pos;
-    
+
+    /* TODO: search with t->used[level][which] instead of which,
+     * then which = t->used[level][which] */
     which = (pos == t->nb[level][2].pos ? 2 : pos == t->nb[level][1].pos);
     t->nb[level][which].pos = -1;
     t->nb[level][which].dirty = 0;
@@ -72,7 +74,7 @@
 {
     size_t size = 0;
 
-    size += read(t->fd, b->rect.boundary, t->nsides * sizeof(RectReal));
+    size += read(t->fd, b->rect.boundary, t->rectsize);
     size += read(t->fd, &(b->child), sizeof(union RTree_Child));
 
     return size;
@@ -98,13 +100,20 @@
 /* get node from buffer or file */
 void RTreeGetNode(struct RTree_Node *n, off_t nodepos, int level, struct RTree *t)
 {
-    int which = (nodepos == t->nb[level][2].pos ? 2 : nodepos == t->nb[level][1].pos);
+    int which = 0;
 
+    /* TODO: search with t->used[level][which] instead of which,
+     * then which = t->used[level][which] */
+    while (t->nb[level][which].pos != nodepos &&
+           t->nb[level][which].pos >= 0 && which < 2)
+	which++;
+
     if (t->nb[level][which].pos != nodepos) {
 	/* replace least recently used (fastest method of lru, pseudo-lru, mru) */
 	which = t->used[level][2];
 	/* rewrite node in buffer */
 	if (t->nb[level][which].dirty) {
+	    assert(t->nb[level][which].pos >= 0);
 	    RTreeRewriteNode(&(t->nb[level][which].n), t->nb[level][which].pos, t);
 	    t->nb[level][which].dirty = 0;
 	}
@@ -123,6 +132,7 @@
     }
     /* copy node */
     RTreeCopyNode(n, &(t->nb[level][which].n), t);
+    assert(n->level == level);
 }
 
 /* write branch to file */
@@ -130,7 +140,7 @@
 {
     size_t size = 0;
 
-    size += write(t->fd, b->rect.boundary, t->nsides * sizeof(RectReal));
+    size += write(t->fd, b->rect.boundary, t->rectsize);
     size += write(t->fd, &(b->child), sizeof(union RTree_Child));
 
     return size;
@@ -157,14 +167,22 @@
 size_t RTreeRewriteNode(struct RTree_Node *n, off_t nodepos, struct RTree *t)
 {
     lseek(t->fd, nodepos, SEEK_SET);
-    return write(t->fd, n, t->nodesize);
+
+    return RTreeWriteNode(n, t);
 }
 
 /* update node in buffer */
 void RTreePutNode(struct RTree_Node *n, off_t nodepos, struct RTree *t)
 {
-    int which = (nodepos == t->nb[n->level][2].pos ? 2 : nodepos == t->nb[n->level][1].pos);
-    
+    int which = 0;
+
+    /* TODO: search with t->used[level][which] instead of which,
+     * then which = t->used[level][which] */
+    while (t->nb[n->level][which].pos != nodepos && which < 2)
+	which++;
+
+    assert(t->nb[n->level][which].pos == nodepos);
+    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;
@@ -182,15 +200,22 @@
 }
 
 /* update rectangle */
-void RTreeUpdateRect(struct RTree_Rect *r, struct RTree_Node *n, off_t nodepos, int b, struct RTree *t)
+void RTreeUpdateRect(struct RTree_Rect *r, struct RTree_Node *n,
+                     off_t nodepos, int b, struct RTree *t)
 {
-    int i;
-    int which = (nodepos == t->nb[n->level][2].pos ?
-		 2 : nodepos == t->nb[n->level][1].pos);
+    int i, j;
+    int which = 0;
     
-    for (i = 0; i < t->nsides; i++) {
+    while (t->nb[n->level][which].pos != nodepos && which < 2)
+	which++;
+
+    assert(t->nb[n->level][which].n.level == n->level);
+    for (i = 0; i < t->ndims_alloc; i++) {
 	t->nb[n->level][which].n.branch[b].rect.boundary[i] =
 	                  n->branch[b].rect.boundary[i] = r->boundary[i];
+	j = i + t->ndims_alloc;
+	t->nb[n->level][which].n.branch[b].rect.boundary[j] =
+	                  n->branch[b].rect.boundary[j] = r->boundary[j];
     }
 
     t->nb[n->level][which].dirty = 1;

Modified: grass/trunk/lib/vector/rtree/rect.c
===================================================================
--- grass/trunk/lib/vector/rtree/rect.c	2012-11-14 06:19:02 UTC (rev 53796)
+++ grass/trunk/lib/vector/rtree/rect.c	2012-11-14 07:20:30 UTC (rev 53797)
@@ -537,20 +537,26 @@
 /*-----------------------------------------------------------------------------
 | Expand first rectangle to cover second rectangle.
 -----------------------------------------------------------------------------*/
-void RTreeExpandRect(struct RTree_Rect *r1, struct RTree_Rect *r2,
+int RTreeExpandRect(struct RTree_Rect *r1, struct RTree_Rect *r2,
 		     struct RTree *t)
 {
-    int i, j;
+    int i, j, ret = 0;
 
     /* assert(r1 && r2); */
 
     if (Undefined(r2, t))
-	return;
+	return ret;
 
     for (i = 0; i < t->ndims; i++) {
-	r1->boundary[i] = MIN(r1->boundary[i], r2->boundary[i]);
+	if (r1->boundary[i] > r2->boundary[i]) {
+	    r1->boundary[i] = r2->boundary[i];
+	    ret = 1;
+	}
 	j = i + t->ndims_alloc;
-	r1->boundary[j] = MAX(r1->boundary[j], r2->boundary[j]);
+	if (r1->boundary[j] < r2->boundary[j]) {
+	    r1->boundary[j] = r2->boundary[j];
+	    ret = 1;
+	}
     }
 
     for (i = t->ndims; i < t->ndims_alloc; i++) {
@@ -558,6 +564,8 @@
 	j = i + t->ndims_alloc;
 	r1->boundary[j] = 0;
     }
+    
+    return ret;
 }
 
 



More information about the grass-commit mailing list