[GRASS-SVN] r52489 - grass/trunk/lib/vector/rtree
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Jul 31 11:09:03 PDT 2012
Author: mmetz
Date: 2012-07-31 11:09:02 -0700 (Tue, 31 Jul 2012)
New Revision: 52489
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/node.c
grass/trunk/lib/vector/rtree/rect.c
grass/trunk/lib/vector/rtree/rtree.h
grass/trunk/lib/vector/rtree/split.c
Log:
rtree optimizations
Modified: grass/trunk/lib/vector/rtree/index.c
===================================================================
--- grass/trunk/lib/vector/rtree/index.c 2012-07-31 18:06:18 UTC (rev 52488)
+++ grass/trunk/lib/vector/rtree/index.c 2012-07-31 18:09:02 UTC (rev 52489)
@@ -56,13 +56,13 @@
new_rtree->free_nodes.alloc = 0;
new_rtree->free_nodes.pos = NULL;
+ new_rtree->rectsize = new_rtree->nsides_alloc * sizeof(RectReal);
new_rtree->nodesize = sizeof(struct RTree_Node) -
MAXCARD * sizeof(RectReal *) +
- MAXCARD * new_rtree->nsides_alloc * sizeof(RectReal);
+ MAXCARD * new_rtree->rectsize;
new_rtree->branchsize = sizeof(struct RTree_Branch) -
- sizeof(RectReal *) +
- new_rtree->nsides_alloc * sizeof(RectReal);
+ sizeof(RectReal *) + new_rtree->rectsize;
/* create empty root node */
n = RTreeNewNode(new_rtree, 0);
Modified: grass/trunk/lib/vector/rtree/index.h
===================================================================
--- grass/trunk/lib/vector/rtree/index.h 2012-07-31 18:06:18 UTC (rev 52488)
+++ grass/trunk/lib/vector/rtree/index.h 2012-07-31 18:09:02 UTC (rev 52489)
@@ -75,7 +75,7 @@
/* node.c */
void RTreeNodeCover(struct RTree_Node *, struct RTree_Rect *, struct RTree *);
int RTreeAddBranch(struct RTree_Branch *, struct RTree_Node *, struct RTree_Node **,
- struct RTree_ListBranch **, struct RTree_Rect *, int *, struct RTree *);
+ struct RTree_ListBranch **, struct RTree_Rect *, char *, struct RTree *);
int RTreePickBranch(struct RTree_Rect *, struct RTree_Node *, struct RTree *);
void RTreeDisconnectBranch(struct RTree_Node *, int, struct RTree *);
void RTreePrintNode(struct RTree_Node *, int, struct RTree *);
@@ -97,7 +97,7 @@
/*-----------------------------------------------------------------------------
| Copy second rectangle to first rectangle.
-----------------------------------------------------------------------------*/
-#define RTreeCopyRect(r1, r2, t) memcpy((r1)->boundary, (r2)->boundary, (t)->nsides_alloc * sizeof(RectReal))
+#define RTreeCopyRect(r1, r2, t) memcpy((r1)->boundary, (r2)->boundary, (t)->rectsize)
/* split.c */
Modified: grass/trunk/lib/vector/rtree/indexf.c
===================================================================
--- grass/trunk/lib/vector/rtree/indexf.c 2012-07-31 18:06:18 UTC (rev 52488)
+++ grass/trunk/lib/vector/rtree/indexf.c 2012-07-31 18:09:02 UTC (rev 52489)
@@ -40,7 +40,7 @@
SearchHitCallback *shcb, void *cbarg)
{
struct RTree_Node *n;
- int hitCount = 0, found, currlevel;
+ int hitCount = 0, notfound, currlevel;
int i;
int top = 0;
struct fstack *s = t->fs;
@@ -57,7 +57,7 @@
while (top >= 0) {
if (s[top].sn.level > 0) { /* this is an internal node in the tree */
n = &(s[top].sn);
- found = 1;
+ notfound = 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 &&
@@ -67,11 +67,11 @@
s[top].pos = n->branch[i].child.pos;
RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t);
s[top].branch_id = 0;
- found = 0;
+ notfound = 0;
break;
}
}
- if (found) {
+ if (notfound) {
/* nothing else found, go back up */
s[top].branch_id = t->nodecard;
top--;
@@ -110,7 +110,7 @@
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, int *overflow)
+ struct RTree_ListBranch **ee, char *overflow)
{
int i, currlevel;
struct RTree_Rect *cover;
@@ -152,30 +152,22 @@
}
/* Have reached level for insertion. Add rect, split if necessary */
- if (s[top].sn.level == level) {
- 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 */
- if (top)
- cover = &(s[top - 1].sn.branch[s[top - 1].branch_id].rect);
- else
- cover = NULL;
- result = RTreeAddBranch(b, &(s[top].sn), &n2, ee, cover, overflow, 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);
+ 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);
+ /* write out new node if node was split */
+ if (result == 1) {
+ *newnode_pos = RTreeGetNodePos(t);
+ RTreeWriteNode(n2, t);
+ t->n_nodes++;
}
- else {
- /* Not supposed to happen */
- assert(s[top].sn.level == level);
- return 0;
- }
+ /* update node */
+ RTreePutNode(&(s[top].sn), s[top].pos, t);
/* go back up */
while (top) {
@@ -204,10 +196,9 @@
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);
- else
- cover = NULL;
result = RTreeAddBranch(b, &(s[top].sn), &n2, ee, cover, overflow, t);
/* write out new node if node was split */
@@ -239,8 +230,8 @@
struct RTree *t)
{
struct RTree_ListBranch *e, *reInsertList = NULL;
- int result;
- int i, overflow[MAXLEVEL];
+ int i, result;
+ char overflow[MAXLEVEL];
off_t newnode_pos = -1;
static struct RTree_Node oldroot, newroot, newnode;
@@ -257,8 +248,7 @@
}
/* R*-tree forced reinsertion: for each level only once */
- for (i = 0; i < MAXLEVEL; i++)
- overflow[i] = 1;
+ memset(overflow, 1, MAXLEVEL);
result =
RTreeInsertRect2F(r, child, level, &newnode, &newnode_pos, t,
@@ -282,8 +272,11 @@
t->rootpos = RTreeGetNodePos(t);
RTreeWriteNode(&newroot, t);
t->n_nodes++;
- }
- else if (result == 2) { /* branches were removed */
+
+ return result;
+ }
+
+ if (result == 2) { /* branches were removed */
while (reInsertList) {
/* get next branch in list */
RTreeCopyBranch(b, &(reInsertList->b), t);
@@ -353,7 +346,7 @@
RTreeGetNode(&(s[top].sn), s[top].pos, currlevel, t);
s[top].branch_id = 0;
- while (notfound) {
+ while (notfound && top >= 0) {
/* go down to level 0, remember path */
if (s[top].sn.level > 0) {
n = &(s[top].sn);
@@ -497,8 +490,7 @@
}
return 0;
}
- else {
- return 1;
- }
+
+ return 1;
}
Modified: grass/trunk/lib/vector/rtree/indexm.c
===================================================================
--- grass/trunk/lib/vector/rtree/indexm.c 2012-07-31 18:06:18 UTC (rev 52488)
+++ grass/trunk/lib/vector/rtree/indexm.c 2012-07-31 18:09:02 UTC (rev 52489)
@@ -36,7 +36,7 @@
SearchHitCallback *shcb, void *cbarg)
{
struct RTree_Node *n;
- int hitCount = 0, found;
+ int hitCount = 0, notfound;
int i;
int top = 0;
struct mstack *s = t->ms;
@@ -52,7 +52,7 @@
while (top >= 0) {
n = s[top].sn;
if (s[top].sn->level > 0) { /* this is an internal node in the tree */
- found = 1;
+ notfound = 1;
for (i = s[top].branch_id; i < t->nodecard; i++) {
if (s[top].sn->branch[i].child.ptr &&
RTreeOverlap(r, &(s[top].sn->branch[i].rect), t)) {
@@ -60,11 +60,11 @@
/* add next node to stack */
s[top].sn = n->branch[i].child.ptr;
s[top].branch_id = 0;
- found = 0;
+ notfound = 0;
break;
}
}
- if (found) {
+ if (notfound) {
/* nothing else found, go back up */
s[top].branch_id = t->nodecard;
top--;
@@ -103,7 +103,7 @@
static int RTreeInsertRect2M(struct RTree_Rect *r, union RTree_Child child, int level,
struct RTree_Node **newnode,
struct RTree *t,
- struct RTree_ListBranch **ee, int *overflow)
+ struct RTree_ListBranch **ee, char *overflow)
{
int i;
struct RTree_Node *n, *n2;
@@ -126,26 +126,18 @@
}
/* Have reached level for insertion. Remove p rectangles or split */
- if (s[top].sn->level == level) {
- 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 */
- if (top)
- cover = &(s[top - 1].sn->branch[s[top - 1].branch_id].rect);
- else
- cover = NULL;
- result = RTreeAddBranch(b, s[top].sn, &n2, ee, cover, overflow, t);
- /* update node count */
- if (result == 1) {
- t->n_nodes++;
- }
+ 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 count */
+ if (result == 1) {
+ t->n_nodes++;
}
- else {
- /* Not supposed to happen */
- assert(0);
- return 0;
- }
/* go back up */
while (top) {
@@ -166,10 +158,9 @@
RTreeNodeCover(b->child.ptr, &(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);
- else
- cover = NULL;
result =
RTreeAddBranch(b, s[top].sn, &n2, ee, cover, overflow, t);
@@ -200,12 +191,11 @@
struct RTree_ListBranch *reInsertList = NULL;
struct RTree_ListBranch *e;
int result;
- int i, overflow[MAXLEVEL];
+ char overflow[MAXLEVEL];
struct RTree_Branch *b = &(t->tmpb1);
/* R*-tree forced reinsertion: for each level only once */
- for (i = 0; i < MAXLEVEL; i++)
- overflow[i] = 1;
+ memset(overflow, 1, MAXLEVEL);
result =
RTreeInsertRect2M(r, child, level, &newnode, t, &reInsertList,
@@ -227,8 +217,11 @@
/* set new root node */
t->root = newroot;
t->n_nodes++;
+
+ return result;
}
- else if (result == 2) { /* branches were removed */
+
+ if (result == 2) { /* branches were removed */
while (reInsertList) {
/* get next branch in list */
RTreeCopyBranch(b, &(reInsertList->b), t);
@@ -287,7 +280,7 @@
s[top].branch_id = 0;
n = s[top].sn;
- while (notfound) {
+ while (notfound && top >= 0) {
/* go down to level 0, remember path */
if (s[top].sn->level > 0) {
n = s[top].sn;
@@ -308,7 +301,7 @@
s[top].branch_id = t->nodecard;
top--;
}
- else /* found a way down but not yet the item */
+ else /* found a way down but not yet the item */
notfound = 1;
}
else {
@@ -410,7 +403,6 @@
}
return 0;
}
- else {
- return 1;
- }
+
+ return 1;
}
Modified: grass/trunk/lib/vector/rtree/node.c
===================================================================
--- grass/trunk/lib/vector/rtree/node.c 2012-07-31 18:06:18 UTC (rev 52488)
+++ grass/trunk/lib/vector/rtree/node.c 2012-07-31 18:09:02 UTC (rev 52489)
@@ -338,7 +338,7 @@
*/
static int RTreePartitionDist(struct dist *d, int first, int last)
{
- int pivot, mid = (first + last) / 2;
+ int pivot, mid = ((first + last) >> 1);
int larger, smaller;
if (last - first == 1) { /* only two items in list */
@@ -349,23 +349,19 @@
}
/* Larger of two */
+ larger = pivot = mid;
+ smaller = first;
if (d[first].distance > d[mid].distance) {
larger = pivot = first;
smaller = mid;
}
- else {
- larger = pivot = mid;
- smaller = first;
- }
if (d[larger].distance > d[last].distance) {
/* larger is largest, get the larger of smaller and last */
+ pivot = last;
if (d[smaller].distance > d[last].distance) {
pivot = smaller;
}
- else {
- pivot = last;
- }
}
if (pivot != last) {
@@ -539,7 +535,7 @@
*/
int RTreeAddBranch(struct RTree_Branch *b, struct RTree_Node *n,
struct RTree_Node **newnode, struct RTree_ListBranch **ee,
- struct RTree_Rect *cover, int *overflow, struct RTree *t)
+ struct RTree_Rect *cover, char *overflow, struct RTree *t)
{
int i, maxkids;
Modified: grass/trunk/lib/vector/rtree/rect.c
===================================================================
--- grass/trunk/lib/vector/rtree/rect.c 2012-07-31 18:06:18 UTC (rev 52488)
+++ grass/trunk/lib/vector/rtree/rect.c 2012-07-31 18:09:02 UTC (rev 52489)
@@ -37,7 +37,7 @@
-----------------------------------------------------------------------------*/
void RTreeNewRect(struct RTree_Rect *r, struct RTree *t)
{
- r->boundary = (RectReal *)malloc((size_t) t->nsides_alloc * sizeof(RectReal));
+ r->boundary = (RectReal *)malloc(t->rectsize);
assert(r->boundary);
}
@@ -48,8 +48,8 @@
{
register int i;
- for (i = 0; i < t->nsides_alloc; i++)
- r->boundary[i] = (RectReal) 0;
+ for (i = 0; i < t->ndims; i++)
+ r->boundary[i] = r->boundary[i + t->ndims_alloc] = (RectReal) 0;
}
/*-----------------------------------------------------------------------------
@@ -60,7 +60,7 @@
{
register int i;
- assert(r);
+ /* assert(r); */
r->boundary[0] = (RectReal) 1;
r->boundary[t->nsides - 1] = (RectReal) - 1;
@@ -160,7 +160,8 @@
register int i;
register RectReal volume = (RectReal) 1;
- assert(r);
+ /* assert(r); */
+
if (Undefined(r, t))
return (RectReal) 0;
@@ -245,9 +246,11 @@
register int i;
RectReal maxsize = (RectReal) 0, c_size;
- assert(r);
+ /* assert(r); */
+
if (Undefined(r, t))
return (RectReal) 0;
+
for (i = 0; i < t->ndims; i++) {
c_size = r->boundary[i + NUMDIMS] - r->boundary[i];
if (c_size > maxsize)
@@ -264,18 +267,21 @@
RectReal RTreeRectSphericalVolume(struct RTree_Rect *r, struct RTree *t)
{
int i;
- double sum_of_squares = 0, radius, half_extent;
+ double sum_of_squares = 0, extent;
- assert(r);
+ /* assert(r); */
+
if (Undefined(r, t))
return (RectReal) 0;
+
for (i = 0; i < t->ndims; i++) {
- half_extent = (r->boundary[i + t->ndims_alloc] - r->boundary[i]) / 2;
+ extent = (r->boundary[i + t->ndims_alloc] - r->boundary[i]);
- sum_of_squares += half_extent * half_extent;
+ /* extent should be half extent : /4 */
+ sum_of_squares += extent * extent / 4.;
}
- radius = sqrt(sum_of_squares);
- return (RectReal) (pow(radius, t->ndims) * UnitSphereVolumes[t->ndims]);
+
+ return (RectReal) (pow(sqrt(sum_of_squares), t->ndims) * UnitSphereVolumes[t->ndims]);
}
@@ -285,21 +291,20 @@
RectReal RTreeRectSurfaceArea(struct RTree_Rect *r, struct RTree *t)
{
int i, j;
- RectReal j_extent, sum = (RectReal) 0;
+ RectReal face_area, sum = (RectReal) 0;
- assert(r);
+ /*assert(r); */
+
if (Undefined(r, t))
return (RectReal) 0;
for (i = 0; i < t->ndims; i++) {
- RectReal face_area = (RectReal) 1;
+ face_area = (RectReal) 1;
for (j = 0; j < t->ndims; j++)
/* exclude i extent from product in this dimension */
if (i != j) {
- j_extent = r->boundary[j + t->ndims_alloc] - r->boundary[j];
-
- face_area *= j_extent;
+ face_area *= (r->boundary[j + t->ndims_alloc] - r->boundary[j]);
}
sum += face_area;
}
@@ -316,7 +321,7 @@
int i;
RectReal margin = 0.0;
- assert(r);
+ /* assert(r); */
for (i = 0; i < t->ndims; i++) {
margin += r->boundary[i + t->ndims_alloc] - r->boundary[i];
@@ -334,19 +339,19 @@
{
int i, j;
- assert(r1 && r2 && r3);
+ /* assert(r1 && r2 && r3); */
if (Undefined(r1, t)) {
for (i = 0; i < t->nsides; i++)
r3->boundary[i] = r2->boundary[i];
-
+
return;
}
if (Undefined(r2, t)) {
for (i = 0; i < t->nsides; i++)
r3->boundary[i] = r1->boundary[i];
-
+
return;
}
@@ -371,7 +376,7 @@
{
int i, j;
- assert(r1 && r2);
+ /* assert(r1 && r2); */
if (Undefined(r2, t))
return;
@@ -397,7 +402,7 @@
{
register int i, j;
- assert(r && s);
+ /* assert(r && s); */
for (i = 0; i < t->ndims; i++) {
j = i + t->ndims_alloc; /* index for high sides */
@@ -417,7 +422,7 @@
{
register int i, j;
- assert(r && s);
+ /* assert(r && s); */
for (i = 0; i < t->ndims; i++) {
j = i + t->ndims_alloc; /* index for high sides */
@@ -437,7 +442,7 @@
{
register int i, j, result;
- assert(r && s);
+ /* assert(r && s); */
/* undefined rect is contained in any other */
if (Undefined(r, t))
Modified: grass/trunk/lib/vector/rtree/rtree.h
===================================================================
--- grass/trunk/lib/vector/rtree/rtree.h 2012-07-31 18:06:18 UTC (rev 52488)
+++ grass/trunk/lib/vector/rtree/rtree.h 2012-07-31 18:09:02 UTC (rev 52489)
@@ -18,6 +18,7 @@
#ifndef _R_TREE_H_
#define _R_TREE_H_
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
@@ -123,13 +124,14 @@
struct RTree
{
/* RTree setup info */
- int fd; /* file descriptor */
- unsigned char ndims; /* number of dimensions */
- unsigned char nsides; /* number of sides = 2 * ndims */
- unsigned char ndims_alloc; /* number of dimensions allocated */
+ int fd; /* file descriptor */
+ unsigned char ndims; /* number of dimensions */
+ unsigned char nsides; /* number of sides = 2 * ndims */
+ unsigned char ndims_alloc; /* number of dimensions allocated */
unsigned char nsides_alloc; /* number of sides allocated = 2 * ndims allocated */
- int nodesize; /* node size in bytes */
- int branchsize; /* branch size in bytes */
+ int nodesize; /* node size in bytes */
+ int branchsize; /* branch size in bytes */
+ int rectsize; /* rectangle size in bytes */
/* RTree info, useful to calculate space requirements */
int n_nodes; /* number of nodes */
Modified: grass/trunk/lib/vector/rtree/split.c
===================================================================
--- grass/trunk/lib/vector/rtree/split.c 2012-07-31 18:06:18 UTC (rev 52488)
+++ grass/trunk/lib/vector/rtree/split.c 2012-07-31 18:09:02 UTC (rev 52489)
@@ -312,13 +312,10 @@
----------------------------------------------------------------------*/
static int RTreeCompareBranches(struct RTree_Branch *a, struct RTree_Branch *b, int side)
{
- if (a->rect.boundary[side] > b->rect.boundary[side])
- return 1;
- else if (a->rect.boundary[side] < b->rect.boundary[side])
+ if (a->rect.boundary[side] < b->rect.boundary[side])
return -1;
- /* boundaries are equal */
- return 0;
+ return (a->rect.boundary[side] > b->rect.boundary[side]);
}
/*----------------------------------------------------------------------
@@ -342,7 +339,7 @@
----------------------------------------------------------------------*/
static int RTreePartitionBranchBuf(int first, int last, int side, struct RTree *t)
{
- int pivot, mid = (first + last) / 2;
+ int pivot, mid = ((first + last) >> 1);
int larger, smaller;
if (last - first == 1) { /* only two items in list */
@@ -354,26 +351,22 @@
}
/* larger of two */
+ larger = pivot = mid;
+ smaller = first;
if (RTreeCompareBranches(&(t->BranchBuf[first]), &(t->BranchBuf[mid]), side)
== 1) {
larger = pivot = first;
smaller = mid;
}
- else {
- larger = pivot = mid;
- smaller = first;
- }
if (RTreeCompareBranches(&(t->BranchBuf[larger]), &(t->BranchBuf[last]), side)
== 1) {
/* larger is largest, get the larger of smaller and last */
+ pivot = last;
if (RTreeCompareBranches
(&(t->BranchBuf[smaller]), &(t->BranchBuf[last]), side) == 1) {
pivot = smaller;
}
- else {
- pivot = last;
- }
}
if (pivot != last) {
@@ -488,8 +481,9 @@
smallest_overlap = DBL_MAX;
smallest_vol = DBL_MAX;
- /* first lower then upper bounds for each axis */
- for (s = 0; s < 2; s++) {
+ /* first upper then lower bounds for each axis */
+ s = 1;
+ do {
RTreeQuicksortBranchBuf(i + s * t->ndims_alloc, t);
side = s;
@@ -578,7 +572,7 @@
}
}
} /* end of distribution check */
- } /* end of side check */
+ } while (s--); /* end of side check */
} /* end of axis check */
/* Use best distribution to classify branches */
More information about the grass-commit
mailing list