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

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Nov 19 02:20:54 PST 2012


Author: mmetz
Date: 2012-11-19 02:20:54 -0800 (Mon, 19 Nov 2012)
New Revision: 53906

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/io.c
   grass/trunk/lib/vector/rtree/rtree.h
Log:
rtree: spatial index with buffered external memory, work in progress

Modified: grass/trunk/lib/vector/rtree/index.c
===================================================================
--- grass/trunk/lib/vector/rtree/index.c	2012-11-19 09:54:19 UTC (rev 53905)
+++ grass/trunk/lib/vector/rtree/index.c	2012-11-19 10:20:54 UTC (rev 53906)
@@ -112,9 +112,11 @@
 
 	for (i = 0; i < MAXLEVEL; i++) {
 
+	    /*
 	    for (j = 0; j < MAXCARD; j++) {
 		new_rtree->fs[i].sn.branch[j].rect.boundary = RTreeAllocBoundary(new_rtree);
 	    }
+	    */
 	    for (j = 0; j < NODE_BUFFER_SIZE; j++) {
 		new_rtree->nb[i][j].dirty = 0;
 		new_rtree->nb[i][j].pos = -1;

Modified: grass/trunk/lib/vector/rtree/index.h
===================================================================
--- grass/trunk/lib/vector/rtree/index.h	2012-11-19 09:54:19 UTC (rev 53905)
+++ grass/trunk/lib/vector/rtree/index.h	2012-11-19 10:20:54 UTC (rev 53906)
@@ -109,7 +109,7 @@
 int RTreeGetLeafMax(struct RTree *);
 
 /* io.c */
-void RTreeGetNode(struct RTree_Node *n, off_t, int, struct RTree *);
+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 *);

Modified: grass/trunk/lib/vector/rtree/indexf.c
===================================================================
--- grass/trunk/lib/vector/rtree/indexf.c	2012-11-19 09:54:19 UTC (rev 53905)
+++ grass/trunk/lib/vector/rtree/indexf.c	2012-11-19 10:20:54 UTC (rev 53906)
@@ -50,23 +50,23 @@
     /* 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].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) {
-	n = &(s[top].sn);
-	if (s[top].sn.level > 0) {		/* this is an internal node in the tree */
+	n = s[top].sn;
+	if (s[top].sn->level > 0) {		/* this is an internal node in the tree */
 	    notfound = 1;
-	    currlevel = s[top].sn.level - 1;
+	    currlevel = s[top].sn->level - 1;
 	    for (i = s[top].branch_id; i < t->nodecard; i++) {
-		if (s[top].sn.branch[i].child.pos > -1 &&
-		    RTreeOverlap(r, &(s[top].sn.branch[i].rect), t)) {
+		if (s[top].sn->branch[i].child.pos > -1 &&
+		    RTreeOverlap(r, &(s[top].sn->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); */
-		    RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t);
+		    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;
@@ -80,12 +80,12 @@
 	}
 	else {			/* this is a leaf node */
 	    for (i = 0; i < t->leafcard; i++) {
-		if (s[top].sn.branch[i].child.id &&
-		    RTreeOverlap(r, &(s[top].sn.branch[i].rect), t)) {
+		if (s[top].sn->branch[i].child.id &&
+		    RTreeOverlap(r, &(s[top].sn->branch[i].rect), t)) {
 		    hitCount++;
 		    if (shcb) {	/* call the user-provided callback */
-			if (!shcb(s[top].sn.branch[i].child.id,
-			          &s[top].sn.branch[i].rect, cbarg)) {
+			if (!shcb(s[top].sn->branch[i].child.id,
+			          &(s[top].sn->branch[i].rect), cbarg)) {
 			    /* callback wants to terminate search early */
 			    return hitCount;
 			}
@@ -139,22 +139,22 @@
     /* 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].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) {
-	n = &(s[top].sn);
-	currlevel = s[top].sn.level - 1;
+    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); */
-	RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t);
-	assert(s[top].sn.level == currlevel);
+	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);
+    assert(s[top].sn->level == level);
 
     /* Have reached level for insertion. Add rect, split if necessary */
     RTreeCopyRect(&(b->rect), r, t);
@@ -163,11 +163,11 @@
     /* 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);
+	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); */
+    /* 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) {
 	*newnode_pos = RTreeGetNodePos(t);
@@ -180,32 +180,30 @@
 	down = top--;
 	i = s[top].branch_id;
 	if (result == 0) {        /* branch was added */
-	    RTreeCombineRect(&(s[top].sn.branch[i].rect), r, &nr, 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);
 	    }
-	    /*
+	    */
 	    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);
-		/*
+	    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);
 		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);
+	    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);
@@ -213,13 +211,13 @@
 	    /* add branch, may split node or remove branches */
 	    cover = NULL;
 	    if (top)
-		cover = &(s[top - 1].sn.branch[s[top - 1].branch_id].rect);
+		cover = &(s[top - 1].sn->branch[s[top - 1].branch_id].rect);
 	    result =
-		RTreeAddBranch(b, &(s[top].sn), &n2, ee, cover, overflow, t);
+		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); */
+	    /* 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) {
@@ -254,13 +252,13 @@
     struct RTree_Branch *b = &(t->tmpb1);
     off_t newnode_pos = -1;
 
-    static struct RTree_Node oldroot;
+    struct RTree_Node *oldroot;
     static struct RTree_Node newroot, newnode;
     static int rect_init = 0;
     
     if (!rect_init) {
 	for (i = 0; i < MAXCARD; i++) {
-	    oldroot.branch[i].rect.boundary = RTreeAllocBoundary(t);
+	    /* oldroot.branch[i].rect.boundary = RTreeAllocBoundary(t); */
 	    newroot.branch[i].rect.boundary = RTreeAllocBoundary(t);
 	    newnode.branch[i].rect.boundary = RTreeAllocBoundary(t);
 	}
@@ -274,14 +272,14 @@
 			       t, &reInsertList, overflow);
 
     if (result == 1) {	/* root split */
-	/* oldroot = RTreeGetNode(t->rootpos, t->rootlevel, t); */
-	RTreeGetNode(&oldroot, t->rootpos, t->rootlevel, t);
+	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;
 	/* branch for old root */
-	RTreeNodeCover(&oldroot, &(b->rect), t);
+	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() */
@@ -310,14 +308,14 @@
 				 &reInsertList, overflow);
 
 	    if (result == 1) {	/* root split */
-		/* oldroot = RTreeGetNode(t->rootpos, t->rootlevel, t); */
-		RTreeGetNode(&oldroot, t->rootpos, t->rootlevel, t);
+		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;
 		/* branch for old root */
-		RTreeNodeCover(&oldroot, &(b->rect), t);
+		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() */
@@ -364,23 +362,23 @@
     /* 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].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) {
 	/* go down to level 0, remember path */
-	if (s[top].sn.level > 0) {
-	    n = &(s[top].sn);
-	    currlevel = s[top].sn.level - 1;
+	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); */
-		    RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t);
+		    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;
@@ -397,11 +395,11 @@
 	}
 	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);
-		    RTreePutNode(&(s[top].sn), s[top].pos, t);
-		    /* RTreeNodeChanged(s[top].sn, s[top].pos, 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;
 		    break;
@@ -421,33 +419,31 @@
 	down = top;
 	top--;
 	i = s[top].branch_id - 1;
-	assert(s[down].sn.level == s[top].sn.level - 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) {
+	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);
-		/*
+	    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);
 		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);
+	    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);
-	    RTreeAddNodePos(s[down].pos, s[down].sn.level, t);
+	    RTreeCopyNode(n, s[down].sn, t);
+	    RTreeAddNodePos(s[down].pos, s[down].sn->level, t);
 	    RTreeReInsertNode(n, ee);
-	    RTreeDisconnectBranch(&(s[top].sn), i, t);
+	    RTreeDisconnectBranch(s[top].sn, i, t);
 
-	    RTreePutNode(&(s[top].sn), s[top].pos, t);
-	    /* RTreeNodeChanged(s[top].sn, s[top].pos, t); */
+	    /* RTreePutNode(&(s[top].sn), s[top].pos, t); */
+	    RTreeNodeChanged(s[top].sn, s[top].pos, t);
 	}
     }
 
@@ -508,9 +504,11 @@
 	}
 
 	/* check for redundant root (not leaf, 1 child) and eliminate */
-	/* n = RTreeGetNode(t->rootpos, t->rootlevel, t); */
+	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++) {

Modified: grass/trunk/lib/vector/rtree/io.c
===================================================================
--- grass/trunk/lib/vector/rtree/io.c	2012-11-19 09:54:19 UTC (rev 53905)
+++ grass/trunk/lib/vector/rtree/io.c	2012-11-19 10:20:54 UTC (rev 53906)
@@ -47,6 +47,7 @@
            i < NODE_BUFFER_SIZE)
 	i++;
 
+    /* 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);
@@ -55,16 +56,14 @@
     
     /* make it lru */
     if (i < NODE_BUFFER_SIZE - 1) { /* which != t->used[level][NODE_BUFFER_SIZE - 1] */
-#ifdef USAGE_SWAP
-	t->used[level][i] = t->used[level][NODE_BUFFER_SIZE - 1];
-	t->used[level][NODE_BUFFER_SIZE - 1] = which;
-#else
-	while (i < NODE_BUFFER_SIZE - 1) {
+	/* simple swap does not work here */
+	while (i < NODE_BUFFER_SIZE - 1 &&
+	       t->nb[level][t->used[level][i + 1]].pos != -1) {
 	    t->used[level][i] = t->used[level][i + 1];
 	    i++;
 	}
-	t->used[level][NODE_BUFFER_SIZE - 1] = which;
-#endif
+	assert(i < NODE_BUFFER_SIZE);
+	t->used[level][i] = which;
     }
 }
 
@@ -109,7 +108,7 @@
 }
 
 /* get node from buffer or file */
-void RTreeGetNode(struct RTree_Node *n, off_t nodepos, int level, struct RTree *t)
+struct RTree_Node *RTreeGetNode(off_t nodepos, int level, struct RTree *t)
 {
     int which, i = 0;
 
@@ -122,9 +121,6 @@
     which = t->used[level][i];
 
     if (t->nb[level][which].pos != nodepos) {
-	if (t->nb[level][which].pos >= 0) {
-	    assert(i == NODE_BUFFER_SIZE - 1);
-	}
 	/* rewrite node in buffer */
 	if (t->nb[level][which].dirty) {
 	    assert(t->nb[level][which].pos >= 0);
@@ -151,9 +147,9 @@
 #endif
     }
 
-    RTreeCopyNode(n, &(t->nb[level][which].n), t);
+    /* RTreeCopyNode(n, &(t->nb[level][which].n), t); */
     
-    /* return &(t->nb[level][which].n); */
+    return &(t->nb[level][which].n);
 }
 
 /* write branch to file */

Modified: grass/trunk/lib/vector/rtree/rtree.h
===================================================================
--- grass/trunk/lib/vector/rtree/rtree.h	2012-11-19 09:54:19 UTC (rev 53905)
+++ grass/trunk/lib/vector/rtree/rtree.h	2012-11-19 10:20:54 UTC (rev 53906)
@@ -52,7 +52,7 @@
 #define MAXLEVEL 20        /* 8^MAXLEVEL items are guaranteed to fit into the tree */
 
 /* number of nodes buffered per level */
-#define NODE_BUFFER_SIZE 4
+#define NODE_BUFFER_SIZE 8
 
 struct RTree_Rect
 {
@@ -103,7 +103,7 @@
 /* stack for file-based index */
 struct fstack
 {
-    struct RTree_Node sn;	/* stack node */
+    struct RTree_Node *sn;	/* stack node */
     int branch_id;		/* branch number to follow down */
     off_t pos;			/* file position of stack node */
 };



More information about the grass-commit mailing list