[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