[GRASS-SVN] r44867 - grass/trunk/lib/vector/rtree
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Jan 4 15:06:37 EST 2011
Author: mmetz
Date: 2011-01-04 12:06:37 -0800 (Tue, 04 Jan 2011)
New Revision: 44867
Modified:
grass/trunk/lib/vector/rtree/index.c
grass/trunk/lib/vector/rtree/index.h
grass/trunk/lib/vector/rtree/io.c
Log:
R*Tree: three buffered nodes per level
Modified: grass/trunk/lib/vector/rtree/index.c
===================================================================
--- grass/trunk/lib/vector/rtree/index.c 2011-01-04 13:45:49 UTC (rev 44866)
+++ grass/trunk/lib/vector/rtree/index.c 2011-01-04 20:06:37 UTC (rev 44867)
@@ -68,9 +68,14 @@
for (i = 0; i < MAXLEVEL; i++) {
new_rtree->nb[i][0].dirty = 0;
new_rtree->nb[i][1].dirty = 0;
+ new_rtree->nb[i][2].dirty = 0;
new_rtree->nb[i][0].pos = -1;
new_rtree->nb[i][1].pos = -1;
- new_rtree->mru[i] = 0;
+ new_rtree->nb[i][2].pos = -1;
+ /* usage order */
+ new_rtree->used[i][0] = 2;
+ new_rtree->used[i][1] = 1;
+ new_rtree->used[i][2] = 0;
}
/* write empty root node */
@@ -78,7 +83,8 @@
RTreeWriteNode(n, new_rtree);
new_rtree->nb[0][0].n = *n;
new_rtree->nb[0][0].pos = rootpos;
- new_rtree->mru[0] = 0;
+ 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 2011-01-04 13:45:49 UTC (rev 44866)
+++ grass/trunk/lib/vector/rtree/index.h 2011-01-04 20:06:37 UTC (rev 44867)
@@ -129,17 +129,20 @@
off_t *pos; /* array of available positions */
} free_nodes;
- /* node buffer for file-based index, two nodes per level
- * more than two nodes per level would require too complex cache management:
- * lru or pseudo-lru replacement, searching for buffered nodes */
+ /* node buffer for file-based index, three nodes per level
+ * more than three nodes per level would require too complex cache management */
struct NodeBuffer
{
struct Node n; /* buffered node */
off_t pos; /* file position of buffered node */
char dirty; /* node in buffer was modified */
- } nb[MAXLEVEL][2];
- char mru[MAXLEVEL]; /* most recently used buffered node per level */
+ } nb[MAXLEVEL][3];
+ /* usage order of buffered nodes per level
+ * used[level][0] = most recently used
+ * used[level][2] = least recently used */
+ char used[MAXLEVEL][3];
+
/* insert, delete, search */
rt_insert_fn *insert_rect;
rt_delete_fn *delete_rect;
Modified: grass/trunk/lib/vector/rtree/io.c
===================================================================
--- grass/trunk/lib/vector/rtree/io.c 2011-01-04 13:45:49 UTC (rev 44866)
+++ grass/trunk/lib/vector/rtree/io.c 2011-01-04 20:06:37 UTC (rev 44867)
@@ -39,10 +39,20 @@
}
t->free_nodes.pos[t->free_nodes.avail++] = pos;
- which = pos == t->nb[level][1].pos;
+ 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;
- t->mru[level] = which == 0;
+
+ /* make it lru */
+ if (t->used[level][0] == which) {
+ t->used[level][0] = t->used[level][1];
+ t->used[level][1] = t->used[level][2];
+ t->used[level][2] = which;
+ }
+ else if (t->used[level][1] == which) {
+ t->used[level][1] = t->used[level][2];
+ t->used[level][2] = which;
+ }
}
/* looks for free node position, sets file pointer, returns position */
@@ -67,14 +77,11 @@
/* get node from buffer or file */
void RTreeGetNode(struct Node *n, off_t nodepos, int level, struct RTree *t)
{
- int which = nodepos == t->nb[level][1].pos;
+ int which = (nodepos == t->nb[level][2].pos ? 2 : nodepos == t->nb[level][1].pos);
if (t->nb[level][which].pos != nodepos) {
- /* which is 0 */
- /* replace least recently used */
- /* least recently used is faster than most recently used */
- if (t->nb[level][which].pos != -1)
- which = t->mru[level] == 0;
+ /* 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) {
RTreeRewriteNode(&(t->nb[level][which].n), t->nb[level][which].pos, t);
@@ -83,7 +90,16 @@
RTreeReadNode(&(t->nb[level][which].n), nodepos, t);
t->nb[level][which].pos = nodepos;
}
- t->mru[level] = which;
+ /* make it mru */
+ if (t->used[level][2] == which) {
+ t->used[level][2] = t->used[level][1];
+ t->used[level][1] = t->used[level][0];
+ t->used[level][0] = which;
+ }
+ else if (t->used[level][1] == which) {
+ t->used[level][1] = t->used[level][0];
+ t->used[level][0] = which;
+ }
*n = t->nb[level][which].n;
}
@@ -104,21 +120,41 @@
/* update node in buffer */
void RTreePutNode(struct Node *n, off_t nodepos, struct RTree *t)
{
- int which = nodepos == t->nb[n->level][1].pos;
+ int which = (nodepos == t->nb[n->level][2].pos ? 2 : nodepos == t->nb[n->level][1].pos);
t->nb[n->level][which].n = *n;
t->nb[n->level][which].dirty = 1;
- t->mru[n->level] = which;
+
+ /* make it mru */
+ if (t->used[n->level][2] == which) {
+ t->used[n->level][2] = t->used[n->level][1];
+ t->used[n->level][1] = t->used[n->level][0];
+ t->used[n->level][0] = which;
+ }
+ else if (t->used[n->level][1] == which) {
+ t->used[n->level][1] = t->used[n->level][0];
+ t->used[n->level][0] = which;
+ }
}
/* update rectangle */
void RTreeUpdateRect(struct Rect *r, struct Node *n, off_t nodepos, int b, struct RTree *t)
{
- int which = nodepos == t->nb[n->level][1].pos;
+ int which = (nodepos == t->nb[n->level][2].pos ? 2 : nodepos == t->nb[n->level][1].pos);
t->nb[n->level][which].n.branch[b].rect = n->branch[b].rect = *r;
t->nb[n->level][which].dirty = 1;
- t->mru[n->level] = which;
+
+ /* make it mru */
+ if (t->used[n->level][2] == which) {
+ t->used[n->level][2] = t->used[n->level][1];
+ t->used[n->level][1] = t->used[n->level][0];
+ t->used[n->level][0] = which;
+ }
+ else if (t->used[n->level][1] == which) {
+ t->used[n->level][1] = t->used[n->level][0];
+ t->used[n->level][0] = which;
+ }
}
/* flush pending changes to file */
@@ -131,5 +167,7 @@
RTreeRewriteNode(&(t->nb[i][0].n), t->nb[i][0].pos, t);
if (t->nb[i][1].dirty)
RTreeRewriteNode(&(t->nb[i][1].n), t->nb[i][1].pos, t);
+ if (t->nb[i][2].dirty)
+ RTreeRewriteNode(&(t->nb[i][2].n), t->nb[i][2].pos, t);
}
}
More information about the grass-commit
mailing list