[GRASS-SVN] r71877 - grass-addons/grass7/raster/r.resamp.tps
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Nov 30 06:11:10 PST 2017
Author: mmetz
Date: 2017-11-30 06:11:10 -0800 (Thu, 30 Nov 2017)
New Revision: 71877
Added:
grass-addons/grass7/raster/r.resamp.tps/cache.c
grass-addons/grass7/raster/r.resamp.tps/cache.h
grass-addons/grass7/raster/r.resamp.tps/pavlrc.c
grass-addons/grass7/raster/r.resamp.tps/pavlrc.h
Removed:
grass-addons/grass7/raster/r.resamp.tps/pavl.c
grass-addons/grass7/raster/r.resamp.tps/pavl.h
Modified:
grass-addons/grass7/raster/r.resamp.tps/main.c
grass-addons/grass7/raster/r.resamp.tps/tps.c
grass-addons/grass7/raster/r.resamp.tps/tps.h
Log:
r.resamp.tps: update helper structures
Added: grass-addons/grass7/raster/r.resamp.tps/cache.c
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/cache.c (rev 0)
+++ grass-addons/grass7/raster/r.resamp.tps/cache.c 2017-11-30 14:11:10 UTC (rev 71877)
@@ -0,0 +1,98 @@
+#include <string.h>
+#include <grass/raster.h>
+#include <grass/segment.h>
+#include <grass/glocale.h>
+#include "cache.h"
+
+static void *cache_get_r(struct cache *c, void *p, int row, int col)
+{
+ return memcpy(p, c->r[row][col], c->n);
+}
+
+static void *cache_put_r(struct cache *c, void *p, int row, int col)
+{
+ return memcpy(c->r[row][col], p, c->n);
+}
+
+static void *cache_get_s(struct cache *c, void *p, int row, int col)
+{
+ Segment_get(&c->s, p, row, col);
+
+ return p;
+}
+
+static void *cache_put_s(struct cache *c, void *p, int row, int col)
+{
+ if (Segment_put(&c->s, p, row, col) != 1)
+ G_fatal_error(_("Unable to write to temporary file"));
+
+ return p;
+}
+
+int cache_create(struct cache *c, int nrows, int ncols, int seg_size,
+ int use_seg, int nbytes, int nseg)
+{
+ c->n = nbytes;
+ c->rows = nrows;
+ c->cols = ncols;
+
+ if (use_seg) {
+ G_verbose_message("Using segment lib");
+ if (Segment_open(&c->s, G_tempfile(), nrows, ncols, seg_size, seg_size,
+ nbytes, nseg) != 1)
+ G_fatal_error("Unable to create temporary file");
+
+ c->r = NULL;
+ c->get = cache_get_s;
+ c->put = cache_put_s;
+ }
+ else {
+ int row, col;
+
+ G_verbose_message("Using memory cache");
+
+ c->r = G_malloc(sizeof(char **) * c->rows);
+ row = 0;
+ c->r[row] = G_malloc(sizeof(char *) * c->rows * c->cols);
+ c->r[row][0] = G_malloc(sizeof(char) * c->rows * c->cols * c->n);
+ for (col = 1; col < c->cols; col++) {
+ c->r[row][col] = c->r[row][col - 1] + c->n;
+ }
+ for (row = 1; row < c->rows; row++) {
+ c->r[row] = c->r[row - 1] + c->cols;
+ c->r[row][0] = c->r[row - 1][0] + c->cols * c->n;
+ for (col = 1; col < c->cols; col++) {
+ c->r[row][col] = c->r[row][col - 1] + c->n;
+ }
+ }
+
+ c->get = cache_get_r;
+ c->put = cache_put_r;
+ }
+
+ return 1;
+}
+
+int cache_destroy(struct cache *c)
+{
+ if (c->r == NULL) {
+ Segment_close(&c->s);
+ }
+ else {
+ G_free(c->r[0][0]);
+ G_free(c->r[0]);
+ G_free(c->r);
+ }
+
+ return 1;
+}
+
+void *cache_get(struct cache *c, void *p, int row, int col)
+{
+ return c->get(c, p, row, col);
+}
+
+void *cache_put(struct cache *c, void *p, int row, int col)
+{
+ return c->put(c, p, row, col);
+}
Added: grass-addons/grass7/raster/r.resamp.tps/cache.h
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/cache.h (rev 0)
+++ grass-addons/grass7/raster/r.resamp.tps/cache.h 2017-11-30 14:11:10 UTC (rev 71877)
@@ -0,0 +1,17 @@
+/* grid cache */
+
+struct cache
+{
+ SEGMENT s;
+ char ***r;
+ int n; /* data size per cell in bytes */
+ int rows, cols;
+ void *(* get)(struct cache *c, void *p, int row, int col);
+ void *(* put)(struct cache *c, void *p, int row, int col);
+};
+
+int cache_create(struct cache *c, int nrows, int ncols, int seg_size,
+ int use_seg, int nbytes, int nseg);
+int cache_destroy(struct cache *c);
+void *cache_get(struct cache *c, void *p, int row, int col);
+void *cache_put(struct cache *c, void *p, int row, int col);
Modified: grass-addons/grass7/raster/r.resamp.tps/main.c
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/main.c 2017-11-30 13:04:31 UTC (rev 71876)
+++ grass-addons/grass7/raster/r.resamp.tps/main.c 2017-11-30 14:11:10 UTC (rev 71877)
@@ -22,6 +22,7 @@
#include <grass/raster.h>
#include <grass/segment.h>
#include <grass/glocale.h>
+#include "cache.h"
#include "tps.h"
int main(int argc, char *argv[])
@@ -47,10 +48,10 @@
int r, c, nrows, ncols;
DCELL **dbuf, *dval;
double regularization, overlap, lm_thresh, ep_thresh;
- SEGMENT in_seg, var_seg, out_seg;
+ struct cache in_seg, var_seg, out_seg;
int insize, varsize;
double segsize;
- int segs_mb, nsegs;
+ int segs_mb, nsegs, nsegs_total;
/*----------------------------------------------------------------*/
/* Options declarations */
@@ -259,12 +260,15 @@
segsize = segsize * 64. * 64. / (1024. * 1024.);
nsegs = segs_mb / segsize;
+ nsegs_total = ((nrows + 63) / 64) + ((ncols + 63) / 64);
+ G_message(_("Number of segments total %d, in memory %d"), nsegs_total, nsegs);
+ /* nsegs_total = nsegs + 1; */
/* load input raster and corresponding covariables */
G_message(_("Loading input..."));
insize = (1 + n_vars) * sizeof(DCELL);
- if (Segment_open(&in_seg, G_tempfile(), nrows, ncols, 32, 32,
+ if (cache_create(&in_seg, nrows, ncols, 64, nsegs < nsegs_total,
insize, nsegs) != 1) {
G_fatal_error("Unable to create input temporary files");
}
@@ -301,11 +305,10 @@
Rast_set_d_null_value(&dval[1], n_vars);
}
- if (Segment_put(&in_seg, (void *)dval, r, c) != 1)
+ if (cache_put(&in_seg, (void *)dval, r, c) == NULL)
G_fatal_error(_("Unable to write to temporary file"));
}
}
- Segment_flush(&in_seg);
G_percent(r, nrows, 5);
Rast_close(in_fd);
@@ -324,7 +327,7 @@
nrows = dst.rows;
ncols = dst.cols;
- if (Segment_open(&out_seg, G_tempfile(), nrows, ncols, 64, 64,
+ if (cache_create(&out_seg, nrows, ncols, 64, nsegs < nsegs_total,
sizeof(struct tps_out), nsegs) != 1) {
G_fatal_error("Unable to create input temporary files");
}
@@ -334,7 +337,7 @@
/* intialize output raster and load corresponding covariables */
G_message(_("Loading covariables for output..."));
varsize = (n_vars) * sizeof(DCELL);
- if (Segment_open(&var_seg, G_tempfile(), nrows, ncols, 64, 64,
+ if (cache_create(&var_seg, nrows, ncols, 64, nsegs < nsegs_total,
varsize, nsegs) != 1) {
G_fatal_error("Unable to create input temporary files");
}
@@ -360,11 +363,10 @@
break;
}
}
- if (Segment_put(&var_seg, (void *)dval, r, c) != 1)
+ if (cache_put(&var_seg, (void *)dval, r, c) == NULL)
G_fatal_error(_("Unable to write to temporary file"));
}
}
- Segment_flush(&var_seg);
G_percent(r, nrows, 5);
for (i = 0; i < n_vars; i++)
@@ -442,10 +444,10 @@
}
}
- Segment_close(&in_seg);
+ cache_destroy(&in_seg);
if (n_vars)
- Segment_close(&var_seg);
- Segment_close(&out_seg);
+ cache_destroy(&var_seg);
+ cache_destroy(&out_seg);
/* write map history */
Rast_close(out_fd);
Deleted: grass-addons/grass7/raster/r.resamp.tps/pavl.c
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/pavl.c 2017-11-30 13:04:31 UTC (rev 71876)
+++ grass-addons/grass7/raster/r.resamp.tps/pavl.c 2017-11-30 14:11:10 UTC (rev 71877)
@@ -1,843 +0,0 @@
-/* Produced by texiweb from libavl.w. */
-
-/* libavl - library for manipulation of binary trees.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
- Foundation, Inc.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- */
-
-/* Nov 2016, Markus Metz
- * from libavl-2.0.3
- * added safety checks and speed optimizations
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "pavl.h"
-
-/* Creates and returns a new table
- with comparison function |compare| using parameter |param|
- and memory allocator |allocator|.
- Returns |NULL| if memory allocation failed. */
-struct pavl_table *pavl_create(pavl_comparison_func * compare,
- struct libavl_allocator *allocator)
-{
- struct pavl_table *tree;
-
- assert(compare != NULL);
-
- if (allocator == NULL)
- allocator = &pavl_allocator_default;
-
- tree = allocator->libavl_malloc(sizeof *tree);
- if (tree == NULL)
- return NULL;
-
- tree->pavl_root = NULL;
- tree->pavl_compare = compare;
- tree->pavl_alloc = allocator;
- tree->pavl_count = 0;
-
- return tree;
-}
-
-/* Search |tree| for an item matching |item|, and return it if found.
- Otherwise return |NULL|. */
-void *pavl_find(const struct pavl_table *tree, const void *item)
-{
- const struct pavl_node *p;
-
- assert(tree != NULL && item != NULL);
-
- p = tree->pavl_root;
- while (p != NULL) {
- int cmp = tree->pavl_compare(item, p->pavl_data);
-
- if (cmp == 0)
- return p->pavl_data;
-
- p = p->pavl_link[cmp > 0];
- }
-
- return NULL;
-}
-
-/* Inserts |item| into |tree| and returns a pointer to |item|'s address.
- If a duplicate item is found in the tree,
- returns a pointer to the duplicate without inserting |item|.
- Returns |NULL| in case of memory allocation failure. */
-void **pavl_probe(struct pavl_table *tree, void *item)
-{
- struct pavl_node *y; /* Top node to update balance factor, and parent. */
- struct pavl_node *p, *q; /* Iterator, and parent. */
- struct pavl_node *n; /* Newly inserted node. */
- struct pavl_node *w; /* New root of rebalanced subtree. */
- int dir; /* Direction to descend. */
-
- assert(tree != NULL && item != NULL);
-
- y = p = tree->pavl_root;
- q = NULL;
- dir = 0;
- while (p != NULL) {
- int cmp = tree->pavl_compare(item, p->pavl_data);
-
- if (cmp == 0)
- return &p->pavl_data;
-
- dir = cmp > 0;
-
- if (p->pavl_balance != 0)
- y = p;
-
- q = p, p = p->pavl_link[dir];
- }
-
- n = tree->pavl_alloc->libavl_malloc(sizeof *p);
- if (n == NULL)
- return NULL;
-
- tree->pavl_count++;
- n->pavl_link[0] = n->pavl_link[1] = NULL;
- n->pavl_parent = q;
- n->pavl_data = item;
- n->pavl_balance = 0;
- if (q == NULL) {
- tree->pavl_root = n;
-
- return &n->pavl_data;
- }
- q->pavl_link[dir] = n;
-
- p = n;
- while (p != y) {
- q = p->pavl_parent;
- /*
- dir = q->pavl_link[0] != p;
- if (dir == 0)
- q->pavl_balance--;
- else
- q->pavl_balance++;
- */
- if (q->pavl_link[0] != p)
- q->pavl_balance++;
- else
- q->pavl_balance--;
-
- p = q;
- }
-
- if (y->pavl_balance == -2) {
- struct pavl_node *x = y->pavl_link[0];
-
- if (x->pavl_balance == -1) {
- w = x;
- y->pavl_link[0] = x->pavl_link[1];
- x->pavl_link[1] = y;
- x->pavl_balance = y->pavl_balance = 0;
- x->pavl_parent = y->pavl_parent;
- y->pavl_parent = x;
- if (y->pavl_link[0] != NULL)
- y->pavl_link[0]->pavl_parent = y;
- }
- else {
- assert(x->pavl_balance == +1);
- w = x->pavl_link[1];
- x->pavl_link[1] = w->pavl_link[0];
- w->pavl_link[0] = x;
- y->pavl_link[0] = w->pavl_link[1];
- w->pavl_link[1] = y;
- if (w->pavl_balance == -1)
- x->pavl_balance = 0, y->pavl_balance = +1;
- else if (w->pavl_balance == 0)
- x->pavl_balance = y->pavl_balance = 0;
- else /* |w->pavl_balance == +1| */
- x->pavl_balance = -1, y->pavl_balance = 0;
- w->pavl_balance = 0;
- w->pavl_parent = y->pavl_parent;
- x->pavl_parent = y->pavl_parent = w;
- if (x->pavl_link[1] != NULL)
- x->pavl_link[1]->pavl_parent = x;
- if (y->pavl_link[0] != NULL)
- y->pavl_link[0]->pavl_parent = y;
- }
- }
- else if (y->pavl_balance == +2) {
- struct pavl_node *x = y->pavl_link[1];
-
- if (x->pavl_balance == +1) {
- w = x;
- y->pavl_link[1] = x->pavl_link[0];
- x->pavl_link[0] = y;
- x->pavl_balance = y->pavl_balance = 0;
- x->pavl_parent = y->pavl_parent;
- y->pavl_parent = x;
- if (y->pavl_link[1] != NULL)
- y->pavl_link[1]->pavl_parent = y;
- }
- else {
- assert(x->pavl_balance == -1);
- w = x->pavl_link[0];
- x->pavl_link[0] = w->pavl_link[1];
- w->pavl_link[1] = x;
- y->pavl_link[1] = w->pavl_link[0];
- w->pavl_link[0] = y;
- if (w->pavl_balance == +1)
- x->pavl_balance = 0, y->pavl_balance = -1;
- else if (w->pavl_balance == 0)
- x->pavl_balance = y->pavl_balance = 0;
- else /* |w->pavl_balance == -1| */
- x->pavl_balance = +1, y->pavl_balance = 0;
- w->pavl_balance = 0;
- w->pavl_parent = y->pavl_parent;
- x->pavl_parent = y->pavl_parent = w;
- if (x->pavl_link[0] != NULL)
- x->pavl_link[0]->pavl_parent = x;
- if (y->pavl_link[1] != NULL)
- y->pavl_link[1]->pavl_parent = y;
- }
- }
- else
- return &n->pavl_data;
-
- if (w->pavl_parent != NULL)
- w->pavl_parent->pavl_link[y != w->pavl_parent->pavl_link[0]] = w;
- else
- tree->pavl_root = w;
-
- return &n->pavl_data;
-}
-
-/* Inserts |item| into |table|.
- Returns |NULL| if |item| was successfully inserted
- or if a memory allocation error occurred.
- Otherwise, returns the duplicate item. */
-void *pavl_insert(struct pavl_table *table, void *item)
-{
- void **p = pavl_probe(table, item);
-
- return p == NULL || *p == item ? NULL : *p;
-}
-
-/* Inserts |item| into |table|, replacing any duplicate item.
- Returns |NULL| if |item| was inserted without replacing a duplicate,
- or if a memory allocation error occurred.
- Otherwise, returns the item that was replaced. */
-void *pavl_replace(struct pavl_table *table, void *item)
-{
- void **p = pavl_probe(table, item);
-
- if (p == NULL || *p == item)
- return NULL;
- else {
- void *r = *p;
-
- *p = item;
-
- return r;
- }
-}
-
-/* Deletes from |tree| and returns an item matching |item|.
- Returns a null pointer if no matching item found. */
-void *pavl_delete(struct pavl_table *tree, const void *item)
-{
- struct pavl_node *p; /* Traverses tree to find node to delete. */
- struct pavl_node *q; /* Parent of |p|. */
- int dir; /* Side of |q| on which |p| is linked. */
- int cmp; /* Result of comparison between |item| and |p|. */
-
- assert(tree != NULL && item != NULL);
-
- p = tree->pavl_root;
- dir = 0;
- while (p != NULL) {
- cmp = tree->pavl_compare(item, p->pavl_data);
-
- if (cmp == 0)
- break;
-
- dir = cmp > 0;
- p = p->pavl_link[dir];
- }
- if (p == NULL)
- return NULL;
-
- item = p->pavl_data;
-
- q = p->pavl_parent;
- if (q == NULL) {
- q = (struct pavl_node *)&tree->pavl_root;
- dir = 0;
- }
-
- if (p->pavl_link[1] == NULL) {
- q->pavl_link[dir] = p->pavl_link[0];
- if (q->pavl_link[dir] != NULL)
- q->pavl_link[dir]->pavl_parent = p->pavl_parent;
- }
- else {
- struct pavl_node *r = p->pavl_link[1];
-
- if (r->pavl_link[0] == NULL) {
- r->pavl_link[0] = p->pavl_link[0];
- q->pavl_link[dir] = r;
- r->pavl_parent = p->pavl_parent;
- if (r->pavl_link[0] != NULL)
- r->pavl_link[0]->pavl_parent = r;
- r->pavl_balance = p->pavl_balance;
- q = r;
- dir = 1;
- }
- else {
- struct pavl_node *s = r->pavl_link[0];
-
- while (s->pavl_link[0] != NULL)
- s = s->pavl_link[0];
- r = s->pavl_parent;
- r->pavl_link[0] = s->pavl_link[1];
- s->pavl_link[0] = p->pavl_link[0];
- s->pavl_link[1] = p->pavl_link[1];
- q->pavl_link[dir] = s;
- if (s->pavl_link[0] != NULL)
- s->pavl_link[0]->pavl_parent = s;
- s->pavl_link[1]->pavl_parent = s;
- s->pavl_parent = p->pavl_parent;
- if (r->pavl_link[0] != NULL)
- r->pavl_link[0]->pavl_parent = r;
- s->pavl_balance = p->pavl_balance;
- q = r;
- dir = 0;
- }
- }
- tree->pavl_alloc->libavl_free(p);
-
- while (q != (struct pavl_node *)&tree->pavl_root) {
- struct pavl_node *y = q;
-
- if (y->pavl_parent != NULL)
- q = y->pavl_parent;
- else
- q = (struct pavl_node *)&tree->pavl_root;
-
- if (dir == 0) {
- dir = q->pavl_link[0] != y;
- y->pavl_balance++;
- if (y->pavl_balance == +1)
- break;
- else if (y->pavl_balance == +2) {
- struct pavl_node *x = y->pavl_link[1];
-
- if (x->pavl_balance == -1) {
- struct pavl_node *w;
-
- assert(x->pavl_balance == -1);
- w = x->pavl_link[0];
- x->pavl_link[0] = w->pavl_link[1];
- w->pavl_link[1] = x;
- y->pavl_link[1] = w->pavl_link[0];
- w->pavl_link[0] = y;
- if (w->pavl_balance == +1)
- x->pavl_balance = 0, y->pavl_balance = -1;
- else if (w->pavl_balance == 0)
- x->pavl_balance = y->pavl_balance = 0;
- else /* |w->pavl_balance == -1| */
- x->pavl_balance = +1, y->pavl_balance = 0;
- w->pavl_balance = 0;
- w->pavl_parent = y->pavl_parent;
- x->pavl_parent = y->pavl_parent = w;
- if (x->pavl_link[0] != NULL)
- x->pavl_link[0]->pavl_parent = x;
- if (y->pavl_link[1] != NULL)
- y->pavl_link[1]->pavl_parent = y;
- q->pavl_link[dir] = w;
- }
- else {
- y->pavl_link[1] = x->pavl_link[0];
- x->pavl_link[0] = y;
- x->pavl_parent = y->pavl_parent;
- y->pavl_parent = x;
- if (y->pavl_link[1] != NULL)
- y->pavl_link[1]->pavl_parent = y;
- q->pavl_link[dir] = x;
- if (x->pavl_balance == 0) {
- x->pavl_balance = -1;
- y->pavl_balance = +1;
- break;
- }
- else {
- x->pavl_balance = y->pavl_balance = 0;
- y = x;
- }
- }
- }
- }
- else {
- dir = q->pavl_link[0] != y;
- y->pavl_balance--;
- if (y->pavl_balance == -1)
- break;
- else if (y->pavl_balance == -2) {
- struct pavl_node *x = y->pavl_link[0];
-
- if (x->pavl_balance == +1) {
- struct pavl_node *w;
-
- assert(x->pavl_balance == +1);
- w = x->pavl_link[1];
- x->pavl_link[1] = w->pavl_link[0];
- w->pavl_link[0] = x;
- y->pavl_link[0] = w->pavl_link[1];
- w->pavl_link[1] = y;
- if (w->pavl_balance == -1)
- x->pavl_balance = 0, y->pavl_balance = +1;
- else if (w->pavl_balance == 0)
- x->pavl_balance = y->pavl_balance = 0;
- else /* |w->pavl_balance == +1| */
- x->pavl_balance = -1, y->pavl_balance = 0;
- w->pavl_balance = 0;
- w->pavl_parent = y->pavl_parent;
- x->pavl_parent = y->pavl_parent = w;
- if (x->pavl_link[1] != NULL)
- x->pavl_link[1]->pavl_parent = x;
- if (y->pavl_link[0] != NULL)
- y->pavl_link[0]->pavl_parent = y;
- q->pavl_link[dir] = w;
- }
- else {
- y->pavl_link[0] = x->pavl_link[1];
- x->pavl_link[1] = y;
- x->pavl_parent = y->pavl_parent;
- y->pavl_parent = x;
- if (y->pavl_link[0] != NULL)
- y->pavl_link[0]->pavl_parent = y;
- q->pavl_link[dir] = x;
- if (x->pavl_balance == 0) {
- x->pavl_balance = +1;
- y->pavl_balance = -1;
- break;
- }
- else {
- x->pavl_balance = y->pavl_balance = 0;
- y = x;
- }
- }
- }
- }
- }
-
- tree->pavl_count--;
- return (void *)item;
-}
-
-/* Initializes |trav| for use with |tree|
- and selects the null node. */
-void pavl_t_init(struct pavl_traverser *trav, struct pavl_table *tree)
-{
- trav->pavl_table = tree;
- trav->pavl_node = NULL;
-}
-
-/* Initializes |trav| for |tree|.
- Returns data item in |tree| with the least value,
- or |NULL| if |tree| is empty. */
-void *pavl_t_first(struct pavl_traverser *trav, struct pavl_table *tree)
-{
- assert(tree != NULL && trav != NULL);
-
- trav->pavl_table = tree;
- trav->pavl_node = tree->pavl_root;
- if (trav->pavl_node != NULL) {
- while (trav->pavl_node->pavl_link[0] != NULL)
- trav->pavl_node = trav->pavl_node->pavl_link[0];
-
- return trav->pavl_node->pavl_data;
- }
- else
- return NULL;
-}
-
-/* Initializes |trav| for |tree|.
- Returns data item in |tree| with the greatest value,
- or |NULL| if |tree| is empty. */
-void *pavl_t_last(struct pavl_traverser *trav, struct pavl_table *tree)
-{
- assert(tree != NULL && trav != NULL);
-
- trav->pavl_table = tree;
- trav->pavl_node = tree->pavl_root;
- if (trav->pavl_node != NULL) {
- while (trav->pavl_node->pavl_link[1] != NULL)
- trav->pavl_node = trav->pavl_node->pavl_link[1];
-
- return trav->pavl_node->pavl_data;
- }
- else
- return NULL;
-}
-
-/* Searches for |item| in |tree|.
- If found, initializes |trav| to the item found and returns the item
- as well.
- If there is no matching item, initializes |trav| to the null item
- and returns |NULL|. */
-void *pavl_t_find(struct pavl_traverser *trav, struct pavl_table *tree,
- void *item)
-{
- struct pavl_node *p;
-
- assert(trav != NULL && tree != NULL && item != NULL);
-
- trav->pavl_table = tree;
-
- p = tree->pavl_root;
- while (p != NULL) {
- int cmp = tree->pavl_compare(item, p->pavl_data);
-
- if (cmp == 0) {
- trav->pavl_node = p;
-
- return p->pavl_data;
- }
-
- p = p->pavl_link[cmp > 0];
- }
-
- trav->pavl_node = NULL;
-
- return NULL;
-}
-
-/* Attempts to insert |item| into |tree|.
- If |item| is inserted successfully, it is returned and |trav| is
- initialized to its location.
- If a duplicate is found, it is returned and |trav| is initialized to
- its location. No replacement of the item occurs.
- If a memory allocation failure occurs, |NULL| is returned and |trav|
- is initialized to the null item. */
-void *pavl_t_insert(struct pavl_traverser *trav,
- struct pavl_table *tree, void *item)
-{
- void **p;
-
- assert(trav != NULL && tree != NULL && item != NULL);
-
- p = pavl_probe(tree, item);
- if (p != NULL) {
- trav->pavl_table = tree;
- trav->pavl_node = ((struct pavl_node *)((char *)p -
- offsetof(struct pavl_node,
- pavl_data)));
-
- return *p;
- }
- else {
- pavl_t_init(trav, tree);
-
- return NULL;
- }
-}
-
-/* Initializes |trav| to have the same current node as |src|. */
-void *pavl_t_copy(struct pavl_traverser *trav,
- const struct pavl_traverser *src)
-{
- assert(trav != NULL && src != NULL);
-
- trav->pavl_table = src->pavl_table;
- trav->pavl_node = src->pavl_node;
-
- return trav->pavl_node != NULL ? trav->pavl_node->pavl_data : NULL;
-}
-
-/* Returns the next data item in inorder
- within the tree being traversed with |trav|,
- or if there are no more data items returns |NULL|. */
-void *pavl_t_next(struct pavl_traverser *trav)
-{
- assert(trav != NULL);
-
- if (trav->pavl_node == NULL)
- return pavl_t_first(trav, trav->pavl_table);
- else if (trav->pavl_node->pavl_link[1] == NULL) {
- struct pavl_node *q, *p; /* Current node and its child. */
-
- for (p = trav->pavl_node, q = p->pavl_parent;;
- p = q, q = q->pavl_parent)
- if (q == NULL || p == q->pavl_link[0]) {
- trav->pavl_node = q;
-
- return trav->pavl_node != NULL ?
- trav->pavl_node->pavl_data : NULL;
- }
- }
- else {
- trav->pavl_node = trav->pavl_node->pavl_link[1];
- while (trav->pavl_node->pavl_link[0] != NULL)
- trav->pavl_node = trav->pavl_node->pavl_link[0];
-
- return trav->pavl_node->pavl_data;
- }
-}
-
-/* Returns the previous data item in inorder
- within the tree being traversed with |trav|,
- or if there are no more data items returns |NULL|. */
-void *pavl_t_prev(struct pavl_traverser *trav)
-{
- assert(trav != NULL);
-
- if (trav->pavl_node == NULL)
- return pavl_t_last(trav, trav->pavl_table);
- else if (trav->pavl_node->pavl_link[0] == NULL) {
- struct pavl_node *q, *p; /* Current node and its child. */
-
- for (p = trav->pavl_node, q = p->pavl_parent;;
- p = q, q = q->pavl_parent)
- if (q == NULL || p == q->pavl_link[1]) {
- trav->pavl_node = q;
-
- return trav->pavl_node != NULL ?
- trav->pavl_node->pavl_data : NULL;
- }
- }
- else {
- trav->pavl_node = trav->pavl_node->pavl_link[0];
- while (trav->pavl_node->pavl_link[1] != NULL)
- trav->pavl_node = trav->pavl_node->pavl_link[1];
-
- return trav->pavl_node->pavl_data;
- }
-}
-
-/* Returns |trav|'s current item. */
-void *pavl_t_cur(struct pavl_traverser *trav)
-{
- assert(trav != NULL);
-
- return trav->pavl_node != NULL ? trav->pavl_node->pavl_data : NULL;
-}
-
-/* Replaces the current item in |trav| by |new| and returns the item replaced.
- |trav| must not have the null item selected.
- The new item must not upset the ordering of the tree. */
-void *pavl_t_replace(struct pavl_traverser *trav, void *new)
-{
- void *old;
-
- assert(trav != NULL && trav->pavl_node != NULL && new != NULL);
- old = trav->pavl_node->pavl_data;
- trav->pavl_node->pavl_data = new;
-
- return old;
-}
-
-/* Destroys |new| with |pavl_destroy (new, destroy)|,
- first initializing right links in |new| that have
- not yet been initialized at time of call. */
-static void
-copy_error_recovery(struct pavl_node *q,
- struct pavl_table *new, pavl_item_func * destroy)
-{
- assert(q != NULL && new != NULL);
-
- for (;;) {
- struct pavl_node *p = q;
-
- q = q->pavl_parent;
- if (q == NULL)
- break;
-
- if (p == q->pavl_link[0])
- q->pavl_link[1] = NULL;
- }
-
- pavl_destroy(new, destroy);
-}
-
-/* Copies |org| to a newly created tree, which is returned.
- If |copy != NULL|, each data item in |org| is first passed to |copy|,
- and the return values are inserted into the tree;
- |NULL| return values are taken as indications of failure.
- On failure, destroys the partially created new tree,
- applying |destroy|, if non-null, to each item in the new tree so far,
- and returns |NULL|.
- If |allocator != NULL|, it is used for allocation in the new tree.
- Otherwise, the same allocator used for |org| is used. */
-struct pavl_table *pavl_copy(const struct pavl_table *org,
- pavl_copy_func * copy, pavl_item_func * destroy,
- struct libavl_allocator *allocator)
-{
- struct pavl_table *new;
- const struct pavl_node *x;
- struct pavl_node *y;
-
- assert(org != NULL);
- new = pavl_create(org->pavl_compare,
- allocator != NULL ? allocator : org->pavl_alloc);
- if (new == NULL)
- return NULL;
-
- new->pavl_count = org->pavl_count;
- if (new->pavl_count == 0)
- return new;
-
- x = (const struct pavl_node *)&org->pavl_root;
- y = (struct pavl_node *)&new->pavl_root;
- while (x != NULL) {
- while (x->pavl_link[0] != NULL) {
- y->pavl_link[0] =
- new->pavl_alloc->libavl_malloc(sizeof *y->pavl_link[0]);
- if (y->pavl_link[0] == NULL) {
- if (y != (struct pavl_node *)&new->pavl_root) {
- y->pavl_data = NULL;
- y->pavl_link[1] = NULL;
- }
-
- copy_error_recovery(y, new, destroy);
-
- return NULL;
- }
- y->pavl_link[0]->pavl_parent = y;
-
- x = x->pavl_link[0];
- y = y->pavl_link[0];
- }
- y->pavl_link[0] = NULL;
-
- for (;;) {
- y->pavl_balance = x->pavl_balance;
- if (copy == NULL)
- y->pavl_data = x->pavl_data;
- else {
- y->pavl_data = copy(x->pavl_data);
- if (y->pavl_data == NULL) {
- y->pavl_link[1] = NULL;
- copy_error_recovery(y, new, destroy);
-
- return NULL;
- }
- }
-
- if (x->pavl_link[1] != NULL) {
- y->pavl_link[1] =
- new->pavl_alloc->libavl_malloc(sizeof *y->pavl_link[1]);
- if (y->pavl_link[1] == NULL) {
- copy_error_recovery(y, new, destroy);
-
- return NULL;
- }
- y->pavl_link[1]->pavl_parent = y;
-
- x = x->pavl_link[1];
- y = y->pavl_link[1];
- break;
- }
- else
- y->pavl_link[1] = NULL;
-
- for (;;) {
- const struct pavl_node *w = x;
-
- x = x->pavl_parent;
- if (x == NULL) {
- new->pavl_root->pavl_parent = NULL;
- return new;
- }
- y = y->pavl_parent;
-
- if (w == x->pavl_link[0])
- break;
- }
- }
- }
-
- return new;
-}
-
-/* Frees storage allocated for |tree|.
- If |destroy != NULL|, applies it to each data item in inorder. */
-void pavl_destroy(struct pavl_table *tree, pavl_item_func * destroy)
-{
- struct pavl_node *p, *q;
-
- assert(tree != NULL);
-
- p = tree->pavl_root;
- while (p != NULL) {
- if (p->pavl_link[0] == NULL) {
- q = p->pavl_link[1];
- if (destroy != NULL && p->pavl_data != NULL)
- destroy(p->pavl_data);
- tree->pavl_alloc->libavl_free(p);
- }
- else {
- q = p->pavl_link[0];
- p->pavl_link[0] = q->pavl_link[1];
- q->pavl_link[1] = p;
- }
- p = q;
- }
-
- tree->pavl_alloc->libavl_free(tree);
-}
-
-/* Allocates |size| bytes of space using |malloc()|.
- Returns a null pointer if allocation fails. */
-void *pavl_malloc(size_t size)
-{
- if (size > 0)
- return malloc(size);
-
- return NULL;
-}
-
-/* Frees |block|. */
-void pavl_free(void *block)
-{
- if (block)
- free(block);
-}
-
-/* Default memory allocator that uses |malloc()| and |free()|. */
-struct libavl_allocator pavl_allocator_default = {
- pavl_malloc,
- pavl_free
-};
-
-#undef NDEBUG
-#include <assert.h>
-
-/* Asserts that |pavl_insert()| succeeds at inserting |item| into |table|. */
-void (pavl_assert_insert) (struct pavl_table * table, void *item)
-{
- void **p = pavl_probe(table, item);
-
- assert(p != NULL && *p == item);
-}
-
-/* Asserts that |pavl_delete()| really removes |item| from |table|,
- and returns the removed item. */
-void *(pavl_assert_delete) (struct pavl_table * table, void *item)
-{
- void *p = pavl_delete(table, item);
-
- assert(p != NULL);
-
- return p;
-}
Deleted: grass-addons/grass7/raster/r.resamp.tps/pavl.h
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/pavl.h 2017-11-30 13:04:31 UTC (rev 71876)
+++ grass-addons/grass7/raster/r.resamp.tps/pavl.h 2017-11-30 14:11:10 UTC (rev 71877)
@@ -1,106 +0,0 @@
-/* Produced by texiweb from libavl.w. */
-
-/* libavl - library for manipulation of binary trees.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
- Foundation, Inc.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- */
-
-#ifndef PAVL_H
-#define PAVL_H 1
-
-#include <stddef.h>
-
-/* Function types. */
-typedef int pavl_comparison_func(const void *pavl_a, const void *pavl_b);
-typedef void pavl_item_func(void *pavl_item);
-typedef void *pavl_copy_func(void *pavl_item);
-
-#ifndef LIBAVL_ALLOCATOR
-#define LIBAVL_ALLOCATOR
-/* Memory allocator. */
-struct libavl_allocator
-{
- void *(*libavl_malloc) (size_t libavl_size);
- void (*libavl_free) (void *libavl_block);
-};
-#endif
-
-/* Default memory allocator. */
-extern struct libavl_allocator pavl_allocator_default;
-void *pavl_malloc(size_t);
-void pavl_free(void *);
-
-/* Maximum PAVL height, unused. */
-#ifndef PAVL_MAX_HEIGHT
-#define PAVL_MAX_HEIGHT 32
-#endif
-
-/* Tree data structure. */
-struct pavl_table
-{
- struct pavl_node *pavl_root; /* Tree's root. */
- pavl_comparison_func *pavl_compare; /* Comparison function. */
- struct libavl_allocator *pavl_alloc; /* Memory allocator. */
- size_t pavl_count; /* Number of items in tree. */
-};
-
-/* An PAVL tree node. */
-struct pavl_node
-{
- struct pavl_node *pavl_link[2]; /* Subtrees. */
- struct pavl_node *pavl_parent; /* Parent node. */
- void *pavl_data; /* Pointer to data. */
- signed char pavl_balance; /* Balance factor. */
-};
-
-/* PAVL traverser structure. */
-struct pavl_traverser
-{
- struct pavl_table *pavl_table; /* Tree being traversed. */
- struct pavl_node *pavl_node; /* Current node in tree. */
-};
-
-/* Table functions. */
-struct pavl_table *pavl_create(pavl_comparison_func *,
- struct libavl_allocator *);
-struct pavl_table *pavl_copy(const struct pavl_table *, pavl_copy_func *,
- pavl_item_func *, struct libavl_allocator *);
-void pavl_destroy(struct pavl_table *, pavl_item_func *);
-void **pavl_probe(struct pavl_table *, void *);
-void *pavl_insert(struct pavl_table *, void *);
-void *pavl_replace(struct pavl_table *, void *);
-void *pavl_delete(struct pavl_table *, const void *);
-void *pavl_find(const struct pavl_table *, const void *);
-void pavl_assert_insert(struct pavl_table *, void *);
-void *pavl_assert_delete(struct pavl_table *, void *);
-
-#define pavl_count(table) ((size_t) (table)->pavl_count)
-
-/* Table traverser functions. */
-void pavl_t_init(struct pavl_traverser *, struct pavl_table *);
-void *pavl_t_first(struct pavl_traverser *, struct pavl_table *);
-void *pavl_t_last(struct pavl_traverser *, struct pavl_table *);
-void *pavl_t_find(struct pavl_traverser *, struct pavl_table *, void *);
-void *pavl_t_insert(struct pavl_traverser *, struct pavl_table *, void *);
-void *pavl_t_copy(struct pavl_traverser *, const struct pavl_traverser *);
-void *pavl_t_next(struct pavl_traverser *);
-void *pavl_t_prev(struct pavl_traverser *);
-void *pavl_t_cur(struct pavl_traverser *);
-void *pavl_t_replace(struct pavl_traverser *, void *);
-
-#endif /* pavl.h */
Added: grass-addons/grass7/raster/r.resamp.tps/pavlrc.c
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/pavlrc.c (rev 0)
+++ grass-addons/grass7/raster/r.resamp.tps/pavlrc.c 2017-11-30 14:11:10 UTC (rev 71877)
@@ -0,0 +1,843 @@
+/* Produced by texiweb from libavl.w. */
+
+/* libavl - library for manipulation of binary trees.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
+ Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+ */
+
+/* Nov 2016, Markus Metz
+ * from libavl-2.0.3
+ * added safety checks and speed optimizations
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "pavlrc.h"
+
+#define CMP_RC(a, b) ((a)->row == (b)->row ? (a)->col - (b)->col : (a)->row - (b)->row)
+
+/* Creates and returns a new table
+ with comparison function |compare| using parameter |param|
+ and memory allocator |allocator|.
+ Returns |NULL| if memory allocation failed. */
+struct pavlrc_table *pavlrc_create(struct libavl_allocator *allocator)
+{
+ struct pavlrc_table *tree;
+
+ if (allocator == NULL)
+ allocator = &pavlrc_allocator_default;
+
+ tree = allocator->libavl_malloc(allocator, sizeof *tree);
+ if (tree == NULL)
+ return NULL;
+
+ tree->pavl_root = NULL;
+ tree->pavl_alloc = allocator;
+ tree->pavl_count = 0;
+
+ return tree;
+}
+
+/* Search |tree| for an item matching |item|, and return it if found.
+ Otherwise return |NULL|. */
+struct pavlrc *pavlrc_find(const struct pavlrc_table *tree, const struct pavlrc *item)
+{
+ struct pavlrc_node *p;
+
+ assert(tree != NULL && item != NULL);
+
+ p = tree->pavl_root;
+ while (p != NULL) {
+ int cmp = CMP_RC(item, &p->pavl_data);
+
+ if (cmp == 0)
+ return &p->pavl_data;
+
+ p = p->pavl_link[cmp > 0];
+ }
+
+ return NULL;
+}
+
+/* Inserts |item| into |tree| and returns a pointer to |item|.
+ If a duplicate item is found in the tree,
+ returns a pointer to the duplicate without inserting |item|.
+ Returns |NULL| in case of memory allocation failure. */
+struct pavlrc *pavlrc_probe(struct pavlrc_table *tree, struct pavlrc *item)
+{
+ struct pavlrc_node *y; /* Top node to update balance factor, and parent. */
+ struct pavlrc_node *p, *q; /* Iterator, and parent. */
+ struct pavlrc_node *n; /* Newly inserted node. */
+ struct pavlrc_node *w; /* New root of rebalanced subtree. */
+ int dir; /* Direction to descend. */
+
+ assert(tree != NULL && item != NULL);
+
+ y = p = tree->pavl_root;
+ q = NULL;
+ dir = 0;
+ while (p != NULL) {
+ int cmp = CMP_RC(item, &p->pavl_data);
+
+ if (cmp == 0)
+ return &p->pavl_data;
+
+ dir = cmp > 0;
+
+ if (p->pavl_balance != 0)
+ y = p;
+
+ q = p, p = p->pavl_link[dir];
+ }
+
+ n = tree->pavl_alloc->libavl_malloc(tree->pavl_alloc, sizeof *p);
+ if (n == NULL)
+ return NULL;
+
+ tree->pavl_count++;
+ n->pavl_link[0] = n->pavl_link[1] = NULL;
+ n->pavl_parent = q;
+ n->pavl_data = *item;
+ n->pavl_balance = 0;
+ if (q == NULL) {
+ tree->pavl_root = n;
+
+ return item /* &n->pavl_data */;
+ }
+ q->pavl_link[dir] = n;
+
+ p = n;
+ while (p != y) {
+ q = p->pavl_parent;
+ /*
+ dir = q->pavl_link[0] != p;
+ if (dir == 0)
+ q->pavl_balance--;
+ else
+ q->pavl_balance++;
+ */
+ if (q->pavl_link[0] != p)
+ q->pavl_balance++;
+ else
+ q->pavl_balance--;
+
+ p = q;
+ }
+
+ if (y->pavl_balance == -2) {
+ struct pavlrc_node *x = y->pavl_link[0];
+
+ if (x->pavl_balance == -1) {
+ w = x;
+ y->pavl_link[0] = x->pavl_link[1];
+ x->pavl_link[1] = y;
+ x->pavl_balance = y->pavl_balance = 0;
+ x->pavl_parent = y->pavl_parent;
+ y->pavl_parent = x;
+ if (y->pavl_link[0] != NULL)
+ y->pavl_link[0]->pavl_parent = y;
+ }
+ else {
+ assert(x->pavl_balance == +1);
+ w = x->pavl_link[1];
+ x->pavl_link[1] = w->pavl_link[0];
+ w->pavl_link[0] = x;
+ y->pavl_link[0] = w->pavl_link[1];
+ w->pavl_link[1] = y;
+ if (w->pavl_balance == -1)
+ x->pavl_balance = 0, y->pavl_balance = +1;
+ else if (w->pavl_balance == 0)
+ x->pavl_balance = y->pavl_balance = 0;
+ else /* |w->pavl_balance == +1| */
+ x->pavl_balance = -1, y->pavl_balance = 0;
+ w->pavl_balance = 0;
+ w->pavl_parent = y->pavl_parent;
+ x->pavl_parent = y->pavl_parent = w;
+ if (x->pavl_link[1] != NULL)
+ x->pavl_link[1]->pavl_parent = x;
+ if (y->pavl_link[0] != NULL)
+ y->pavl_link[0]->pavl_parent = y;
+ }
+ }
+ else if (y->pavl_balance == +2) {
+ struct pavlrc_node *x = y->pavl_link[1];
+
+ if (x->pavl_balance == +1) {
+ w = x;
+ y->pavl_link[1] = x->pavl_link[0];
+ x->pavl_link[0] = y;
+ x->pavl_balance = y->pavl_balance = 0;
+ x->pavl_parent = y->pavl_parent;
+ y->pavl_parent = x;
+ if (y->pavl_link[1] != NULL)
+ y->pavl_link[1]->pavl_parent = y;
+ }
+ else {
+ assert(x->pavl_balance == -1);
+ w = x->pavl_link[0];
+ x->pavl_link[0] = w->pavl_link[1];
+ w->pavl_link[1] = x;
+ y->pavl_link[1] = w->pavl_link[0];
+ w->pavl_link[0] = y;
+ if (w->pavl_balance == +1)
+ x->pavl_balance = 0, y->pavl_balance = -1;
+ else if (w->pavl_balance == 0)
+ x->pavl_balance = y->pavl_balance = 0;
+ else /* |w->pavl_balance == -1| */
+ x->pavl_balance = +1, y->pavl_balance = 0;
+ w->pavl_balance = 0;
+ w->pavl_parent = y->pavl_parent;
+ x->pavl_parent = y->pavl_parent = w;
+ if (x->pavl_link[0] != NULL)
+ x->pavl_link[0]->pavl_parent = x;
+ if (y->pavl_link[1] != NULL)
+ y->pavl_link[1]->pavl_parent = y;
+ }
+ }
+ else
+ return item /* &n->pavl_data */;
+
+ if (w->pavl_parent != NULL)
+ w->pavl_parent->pavl_link[y != w->pavl_parent->pavl_link[0]] = w;
+ else
+ tree->pavl_root = w;
+
+ return item /* &n->pavl_data */;
+}
+
+/* Inserts |item| into |table|.
+ Returns |NULL| if |item| was successfully inserted
+ or if a memory allocation error occurred.
+ Otherwise, returns the duplicate item. */
+struct pavlrc *pavlrc_insert(struct pavlrc_table *table, struct pavlrc *item)
+{
+ struct pavlrc *p = pavlrc_probe(table, item);
+
+ return p == NULL || p == item ? NULL : p;
+}
+
+/* Inserts |item| into |table|, replacing any duplicate item.
+ Returns |NULL| if |item| was inserted without replacing a duplicate,
+ or if a memory allocation error occurred.
+ Otherwise, returns the item that was replaced. */
+struct pavlrc *pavlrc_replace(struct pavlrc_table *table, struct pavlrc *item)
+{
+ struct pavlrc *p = pavlrc_probe(table, item);
+
+ if (p == NULL || p == item)
+ return NULL;
+ else {
+ struct pavlrc *r = p;
+
+ *p = *item;
+
+ return r;
+ }
+}
+
+/* Deletes from |tree| and returns an item matching |item|.
+ Returns a null pointer if no matching item found. */
+struct pavlrc *pavlrc_delete(struct pavlrc_table *tree, struct pavlrc *item)
+{
+ struct pavlrc_node *p; /* Traverses tree to find node to delete. */
+ struct pavlrc_node *q; /* Parent of |p|. */
+ int dir; /* Side of |q| on which |p| is linked. */
+ int cmp; /* Result of comparison between |item| and |p|. */
+
+ assert(tree != NULL && item != NULL);
+
+ p = tree->pavl_root;
+ dir = 0;
+ while (p != NULL) {
+ cmp = CMP_RC(item, &p->pavl_data);
+
+ if (cmp == 0)
+ break;
+
+ dir = cmp > 0;
+ p = p->pavl_link[dir];
+ }
+ if (p == NULL)
+ return NULL;
+
+ /* item = p->pavl_data; */
+
+ q = p->pavl_parent;
+ if (q == NULL) {
+ q = (struct pavlrc_node *)&tree->pavl_root;
+ dir = 0;
+ }
+
+ if (p->pavl_link[1] == NULL) {
+ q->pavl_link[dir] = p->pavl_link[0];
+ if (q->pavl_link[dir] != NULL)
+ q->pavl_link[dir]->pavl_parent = p->pavl_parent;
+ }
+ else {
+ struct pavlrc_node *r = p->pavl_link[1];
+
+ if (r->pavl_link[0] == NULL) {
+ r->pavl_link[0] = p->pavl_link[0];
+ q->pavl_link[dir] = r;
+ r->pavl_parent = p->pavl_parent;
+ if (r->pavl_link[0] != NULL)
+ r->pavl_link[0]->pavl_parent = r;
+ r->pavl_balance = p->pavl_balance;
+ q = r;
+ dir = 1;
+ }
+ else {
+ struct pavlrc_node *s = r->pavl_link[0];
+
+ while (s->pavl_link[0] != NULL)
+ s = s->pavl_link[0];
+ r = s->pavl_parent;
+ r->pavl_link[0] = s->pavl_link[1];
+ s->pavl_link[0] = p->pavl_link[0];
+ s->pavl_link[1] = p->pavl_link[1];
+ q->pavl_link[dir] = s;
+ if (s->pavl_link[0] != NULL)
+ s->pavl_link[0]->pavl_parent = s;
+ s->pavl_link[1]->pavl_parent = s;
+ s->pavl_parent = p->pavl_parent;
+ if (r->pavl_link[0] != NULL)
+ r->pavl_link[0]->pavl_parent = r;
+ s->pavl_balance = p->pavl_balance;
+ q = r;
+ dir = 0;
+ }
+ }
+ tree->pavl_alloc->libavl_free(tree->pavl_alloc, p);
+
+ while (q != (struct pavlrc_node *)&tree->pavl_root) {
+ struct pavlrc_node *y = q;
+
+ if (y->pavl_parent != NULL)
+ q = y->pavl_parent;
+ else
+ q = (struct pavlrc_node *)&tree->pavl_root;
+
+ if (dir == 0) {
+ dir = q->pavl_link[0] != y;
+ y->pavl_balance++;
+ if (y->pavl_balance == +1)
+ break;
+ else if (y->pavl_balance == +2) {
+ struct pavlrc_node *x = y->pavl_link[1];
+
+ if (x->pavl_balance == -1) {
+ struct pavlrc_node *w;
+
+ assert(x->pavl_balance == -1);
+ w = x->pavl_link[0];
+ x->pavl_link[0] = w->pavl_link[1];
+ w->pavl_link[1] = x;
+ y->pavl_link[1] = w->pavl_link[0];
+ w->pavl_link[0] = y;
+ if (w->pavl_balance == +1)
+ x->pavl_balance = 0, y->pavl_balance = -1;
+ else if (w->pavl_balance == 0)
+ x->pavl_balance = y->pavl_balance = 0;
+ else /* |w->pavl_balance == -1| */
+ x->pavl_balance = +1, y->pavl_balance = 0;
+ w->pavl_balance = 0;
+ w->pavl_parent = y->pavl_parent;
+ x->pavl_parent = y->pavl_parent = w;
+ if (x->pavl_link[0] != NULL)
+ x->pavl_link[0]->pavl_parent = x;
+ if (y->pavl_link[1] != NULL)
+ y->pavl_link[1]->pavl_parent = y;
+ q->pavl_link[dir] = w;
+ }
+ else {
+ y->pavl_link[1] = x->pavl_link[0];
+ x->pavl_link[0] = y;
+ x->pavl_parent = y->pavl_parent;
+ y->pavl_parent = x;
+ if (y->pavl_link[1] != NULL)
+ y->pavl_link[1]->pavl_parent = y;
+ q->pavl_link[dir] = x;
+ if (x->pavl_balance == 0) {
+ x->pavl_balance = -1;
+ y->pavl_balance = +1;
+ break;
+ }
+ else {
+ x->pavl_balance = y->pavl_balance = 0;
+ y = x;
+ }
+ }
+ }
+ }
+ else {
+ dir = q->pavl_link[0] != y;
+ y->pavl_balance--;
+ if (y->pavl_balance == -1)
+ break;
+ else if (y->pavl_balance == -2) {
+ struct pavlrc_node *x = y->pavl_link[0];
+
+ if (x->pavl_balance == +1) {
+ struct pavlrc_node *w;
+
+ assert(x->pavl_balance == +1);
+ w = x->pavl_link[1];
+ x->pavl_link[1] = w->pavl_link[0];
+ w->pavl_link[0] = x;
+ y->pavl_link[0] = w->pavl_link[1];
+ w->pavl_link[1] = y;
+ if (w->pavl_balance == -1)
+ x->pavl_balance = 0, y->pavl_balance = +1;
+ else if (w->pavl_balance == 0)
+ x->pavl_balance = y->pavl_balance = 0;
+ else /* |w->pavl_balance == +1| */
+ x->pavl_balance = -1, y->pavl_balance = 0;
+ w->pavl_balance = 0;
+ w->pavl_parent = y->pavl_parent;
+ x->pavl_parent = y->pavl_parent = w;
+ if (x->pavl_link[1] != NULL)
+ x->pavl_link[1]->pavl_parent = x;
+ if (y->pavl_link[0] != NULL)
+ y->pavl_link[0]->pavl_parent = y;
+ q->pavl_link[dir] = w;
+ }
+ else {
+ y->pavl_link[0] = x->pavl_link[1];
+ x->pavl_link[1] = y;
+ x->pavl_parent = y->pavl_parent;
+ y->pavl_parent = x;
+ if (y->pavl_link[0] != NULL)
+ y->pavl_link[0]->pavl_parent = y;
+ q->pavl_link[dir] = x;
+ if (x->pavl_balance == 0) {
+ x->pavl_balance = +1;
+ y->pavl_balance = -1;
+ break;
+ }
+ else {
+ x->pavl_balance = y->pavl_balance = 0;
+ y = x;
+ }
+ }
+ }
+ }
+ }
+
+ tree->pavl_count--;
+
+ return item;
+}
+
+/* Initializes |trav| for use with |tree|
+ and selects the null node. */
+void pavlrc_t_init(struct pavlrc_traverser *trav, struct pavlrc_table *tree)
+{
+ trav->pavl_table = tree;
+ trav->pavl_node = NULL;
+}
+
+/* Initializes |trav| for |tree|.
+ Returns data item in |tree| with the least value,
+ or |NULL| if |tree| is empty. */
+struct pavlrc *pavlrc_t_first(struct pavlrc_traverser *trav, struct pavlrc_table *tree)
+{
+ assert(tree != NULL && trav != NULL);
+
+ trav->pavl_table = tree;
+ trav->pavl_node = tree->pavl_root;
+ if (trav->pavl_node != NULL) {
+ while (trav->pavl_node->pavl_link[0] != NULL)
+ trav->pavl_node = trav->pavl_node->pavl_link[0];
+
+ return &trav->pavl_node->pavl_data;
+ }
+ else
+ return NULL;
+}
+
+/* Initializes |trav| for |tree|.
+ Returns data item in |tree| with the greatest value,
+ or |NULL| if |tree| is empty. */
+struct pavlrc *pavlrc_t_last(struct pavlrc_traverser *trav, struct pavlrc_table *tree)
+{
+ assert(tree != NULL && trav != NULL);
+
+ trav->pavl_table = tree;
+ trav->pavl_node = tree->pavl_root;
+ if (trav->pavl_node != NULL) {
+ while (trav->pavl_node->pavl_link[1] != NULL)
+ trav->pavl_node = trav->pavl_node->pavl_link[1];
+
+ return &trav->pavl_node->pavl_data;
+ }
+ else
+ return NULL;
+}
+
+/* Searches for |item| in |tree|.
+ If found, initializes |trav| to the item found and returns the item
+ as well.
+ If there is no matching item, initializes |trav| to the null item
+ and returns |NULL|. */
+struct pavlrc *pavlrc_t_find(struct pavlrc_traverser *trav, struct pavlrc_table *tree,
+ struct pavlrc *item)
+{
+ struct pavlrc_node *p;
+
+ assert(trav != NULL && tree != NULL && item != NULL);
+
+ trav->pavl_table = tree;
+
+ p = tree->pavl_root;
+ while (p != NULL) {
+ int cmp = CMP_RC(item, &p->pavl_data);
+
+ if (cmp == 0) {
+ trav->pavl_node = p;
+
+ return &p->pavl_data;
+ }
+
+ p = p->pavl_link[cmp > 0];
+ }
+
+ trav->pavl_node = NULL;
+
+ return NULL;
+}
+
+/* Attempts to insert |item| into |tree|.
+ If |item| is inserted successfully, it is returned and |trav| is
+ initialized to its location.
+ If a duplicate is found, it is returned and |trav| is initialized to
+ its location. No replacement of the item occurs.
+ If a memory allocation failure occurs, |NULL| is returned and |trav|
+ is initialized to the null item. */
+struct pavlrc *pavlrc_t_insert(struct pavlrc_traverser *trav,
+ struct pavlrc_table *tree, struct pavlrc *item)
+{
+ struct pavlrc *p;
+
+ assert(trav != NULL && tree != NULL && item != NULL);
+
+ p = pavlrc_probe(tree, item);
+ if (p != NULL) {
+ trav->pavl_table = tree;
+ trav->pavl_node = ((struct pavlrc_node *)((char *)p -
+ offsetof(struct pavlrc_node,
+ pavl_data)));
+
+ return p;
+ }
+ else {
+ pavlrc_t_init(trav, tree);
+
+ return NULL;
+ }
+}
+
+/* Initializes |trav| to have the same current node as |src|. */
+struct pavlrc *pavlrc_t_copy(struct pavlrc_traverser *trav,
+ const struct pavlrc_traverser *src)
+{
+ assert(trav != NULL && src != NULL);
+
+ trav->pavl_table = src->pavl_table;
+ trav->pavl_node = src->pavl_node;
+
+ return trav->pavl_node != NULL ? &trav->pavl_node->pavl_data : NULL;
+}
+
+/* Returns the next data item in inorder
+ within the tree being traversed with |trav|,
+ or if there are no more data items returns |NULL|. */
+struct pavlrc *pavlrc_t_next(struct pavlrc_traverser *trav)
+{
+ assert(trav != NULL);
+
+ if (trav->pavl_node == NULL)
+ return pavlrc_t_first(trav, trav->pavl_table);
+ else if (trav->pavl_node->pavl_link[1] == NULL) {
+ struct pavlrc_node *q, *p; /* Current node and its child. */
+
+ for (p = trav->pavl_node, q = p->pavl_parent;;
+ p = q, q = q->pavl_parent)
+ if (q == NULL || p == q->pavl_link[0]) {
+ trav->pavl_node = q;
+
+ return trav->pavl_node != NULL ?
+ &trav->pavl_node->pavl_data : NULL;
+ }
+ }
+ else {
+ trav->pavl_node = trav->pavl_node->pavl_link[1];
+ while (trav->pavl_node->pavl_link[0] != NULL)
+ trav->pavl_node = trav->pavl_node->pavl_link[0];
+
+ return &trav->pavl_node->pavl_data;
+ }
+}
+
+/* Returns the previous data item in inorder
+ within the tree being traversed with |trav|,
+ or if there are no more data items returns |NULL|. */
+struct pavlrc *pavlrc_t_prev(struct pavlrc_traverser *trav)
+{
+ assert(trav != NULL);
+
+ if (trav->pavl_node == NULL)
+ return pavlrc_t_last(trav, trav->pavl_table);
+ else if (trav->pavl_node->pavl_link[0] == NULL) {
+ struct pavlrc_node *q, *p; /* Current node and its child. */
+
+ for (p = trav->pavl_node, q = p->pavl_parent;;
+ p = q, q = q->pavl_parent)
+ if (q == NULL || p == q->pavl_link[1]) {
+ trav->pavl_node = q;
+
+ return trav->pavl_node != NULL ?
+ &trav->pavl_node->pavl_data : NULL;
+ }
+ }
+ else {
+ trav->pavl_node = trav->pavl_node->pavl_link[0];
+ while (trav->pavl_node->pavl_link[1] != NULL)
+ trav->pavl_node = trav->pavl_node->pavl_link[1];
+
+ return &trav->pavl_node->pavl_data;
+ }
+}
+
+/* Returns |trav|'s current item. */
+struct pavlrc *pavlrc_t_cur(struct pavlrc_traverser *trav)
+{
+ assert(trav != NULL);
+
+ return trav->pavl_node != NULL ? &trav->pavl_node->pavl_data : NULL;
+}
+
+/* Replaces the current item in |trav| by |new| and returns the item replaced.
+ |trav| must not have the null item selected.
+ The new item must not upset the ordering of the tree. */
+struct pavlrc *pavlrc_t_replace(struct pavlrc_traverser *trav, struct pavlrc *new)
+{
+ struct pavlrc *old;
+
+ assert(trav != NULL && trav->pavl_node != NULL && new != NULL);
+ old = &trav->pavl_node->pavl_data;
+ trav->pavl_node->pavl_data = *new;
+
+ return old;
+}
+
+/* Destroys |new| with |pavl_destroy (new, destroy)|,
+ first initializing right links in |new| that have
+ not yet been initialized at time of call. */
+static void
+copy_error_recovery(struct pavlrc_node *q,
+ struct pavlrc_table *new)
+{
+ assert(q != NULL && new != NULL);
+
+ for (;;) {
+ struct pavlrc_node *p = q;
+
+ q = q->pavl_parent;
+ if (q == NULL)
+ break;
+
+ if (p == q->pavl_link[0])
+ q->pavl_link[1] = NULL;
+ }
+
+ pavlrc_destroy(new);
+}
+
+/* Copies |org| to a newly created tree, which is returned.
+ If |copy != NULL|, each data item in |org| is first passed to |copy|,
+ and the return values are inserted into the tree;
+ |NULL| return values are taken as indications of failure.
+ On failure, destroys the partially created new tree,
+ applying |destroy|, if non-null, to each item in the new tree so far,
+ and returns |NULL|.
+ If |allocator != NULL|, it is used for allocation in the new tree.
+ Otherwise, the same allocator used for |org| is used. */
+struct pavlrc_table *pavlrc_copy(const struct pavlrc_table *org,
+ pavlrc_copy_func * copy,
+ struct libavl_allocator *allocator)
+{
+ struct pavlrc_table *new;
+ struct pavlrc_node *x;
+ struct pavlrc_node *y;
+
+ assert(org != NULL);
+ new = pavlrc_create(allocator != NULL ? allocator : org->pavl_alloc);
+ if (new == NULL)
+ return NULL;
+
+ new->pavl_count = org->pavl_count;
+ if (new->pavl_count == 0)
+ return new;
+
+ x = (struct pavlrc_node *)&org->pavl_root;
+ y = (struct pavlrc_node *)&new->pavl_root;
+ while (x != NULL) {
+ while (x->pavl_link[0] != NULL) {
+ y->pavl_link[0] =
+ new->pavl_alloc->libavl_malloc(new->pavl_alloc,
+ sizeof *y->pavl_link[0]);
+ if (y->pavl_link[0] == NULL) {
+ if (y != (struct pavlrc_node *)&new->pavl_root) {
+ /* y->pavl_data = NULL; */
+ y->pavl_link[1] = NULL;
+ }
+
+ copy_error_recovery(y, new);
+
+ return NULL;
+ }
+ y->pavl_link[0]->pavl_parent = y;
+
+ x = x->pavl_link[0];
+ y = y->pavl_link[0];
+ }
+ y->pavl_link[0] = NULL;
+
+ for (;;) {
+ y->pavl_balance = x->pavl_balance;
+ if (copy == NULL)
+ y->pavl_data = x->pavl_data;
+ else {
+ y->pavl_data = *(struct pavlrc *)copy(&x->pavl_data);
+ /*
+ if (y->pavl_data == NULL) {
+ y->pavl_link[1] = NULL;
+ copy_error_recovery(y, new);
+
+ return NULL;
+ }
+ */
+ }
+
+ if (x->pavl_link[1] != NULL) {
+ y->pavl_link[1] =
+ new->pavl_alloc->libavl_malloc(new->pavl_alloc,
+ sizeof *y->pavl_link[1]);
+ if (y->pavl_link[1] == NULL) {
+ copy_error_recovery(y, new);
+
+ return NULL;
+ }
+ y->pavl_link[1]->pavl_parent = y;
+
+ x = x->pavl_link[1];
+ y = y->pavl_link[1];
+ break;
+ }
+ else
+ y->pavl_link[1] = NULL;
+
+ for (;;) {
+ const struct pavlrc_node *w = x;
+
+ x = x->pavl_parent;
+ if (x == NULL) {
+ new->pavl_root->pavl_parent = NULL;
+ return new;
+ }
+ y = y->pavl_parent;
+
+ if (w == x->pavl_link[0])
+ break;
+ }
+ }
+ }
+
+ return new;
+}
+
+/* Frees storage allocated for |tree|.
+ If |destroy != NULL|, applies it to each data item in inorder. */
+void pavlrc_destroy(struct pavlrc_table *tree)
+{
+ struct pavlrc_node *p, *q;
+
+ assert(tree != NULL);
+
+ p = tree->pavl_root;
+ while (p != NULL) {
+ if (p->pavl_link[0] == NULL) {
+ q = p->pavl_link[1];
+ tree->pavl_alloc->libavl_free(tree->pavl_alloc, p);
+ }
+ else {
+ q = p->pavl_link[0];
+ p->pavl_link[0] = q->pavl_link[1];
+ q->pavl_link[1] = p;
+ }
+ p = q;
+ }
+
+ tree->pavl_alloc->libavl_free(tree->pavl_alloc, tree);
+}
+
+/* Allocates |size| bytes of space using |malloc()|.
+ Returns a null pointer if allocation fails. */
+void *pavlrc_malloc(struct libavl_allocator *allocator, size_t size)
+{
+ assert(allocator != NULL && size > 0);
+
+ return malloc(size);
+}
+
+/* Frees |block|. */
+void pavlrc_free(struct libavl_allocator *allocator, void *block)
+{
+ assert(allocator != NULL && block != NULL);
+
+ free(block);
+}
+
+/* Default memory allocator that uses |malloc()| and |free()|. */
+struct libavl_allocator pavlrc_allocator_default = {
+ pavlrc_malloc,
+ pavlrc_free
+};
+
+#undef NDEBUG
+#include <assert.h>
+
+/* Asserts that |pavl_insert()| succeeds at inserting |item| into |table|. */
+void (pavlrc_assert_insert) (struct pavlrc_table * table, struct pavlrc *item)
+{
+ struct pavlrc *p = pavlrc_probe(table, item);
+
+ assert(p != NULL && p == item);
+}
+
+/* Asserts that |pavl_delete()| really removes |item| from |table|,
+ and returns the removed item. */
+struct pavlrc *(pavlrc_assert_delete) (struct pavlrc_table * table, struct pavlrc *item)
+{
+ struct pavlrc *p = pavlrc_delete(table, item);
+
+ assert(p != NULL);
+
+ return p;
+}
Added: grass-addons/grass7/raster/r.resamp.tps/pavlrc.h
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/pavlrc.h (rev 0)
+++ grass-addons/grass7/raster/r.resamp.tps/pavlrc.h 2017-11-30 14:11:10 UTC (rev 71877)
@@ -0,0 +1,107 @@
+/* Produced by texiweb from libavl.w. */
+
+/* libavl - library for manipulation of binary trees.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
+ Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+ */
+
+#ifndef PAVLRC_H
+#define PAVLRC_H 1
+
+#include <stddef.h>
+
+struct pavlrc
+{
+ int row, col;
+};
+
+/* Function types. */
+typedef void *pavlrc_copy_func(void *pavl_item);
+
+#ifndef LIBAVL_ALLOCATOR
+#define LIBAVL_ALLOCATOR
+/* Memory allocator. */
+struct libavl_allocator
+{
+ void *(*libavl_malloc) (struct libavl_allocator *, size_t libavl_size);
+ void (*libavl_free) (struct libavl_allocator *, void *libavl_block);
+};
+#endif
+
+/* Default memory allocator. */
+extern struct libavl_allocator pavlrc_allocator_default;
+void *pavlrc_malloc(struct libavl_allocator *, size_t);
+void pavlrc_free(struct libavl_allocator *, void *);
+
+/* Maximum PAVL height, unused. */
+#ifndef PAVL_MAX_HEIGHT
+#define PAVL_MAX_HEIGHT 32
+#endif
+
+/* Tree data structure. */
+struct pavlrc_table
+{
+ struct pavlrc_node *pavl_root; /* Tree's root. */
+ struct libavl_allocator *pavl_alloc; /* Memory allocator. */
+ size_t pavl_count; /* Number of items in tree. */
+};
+
+/* An PAVL tree node. */
+struct pavlrc_node
+{
+ struct pavlrc_node *pavl_link[2]; /* Subtrees. */
+ struct pavlrc_node *pavl_parent; /* Parent node. */
+ struct pavlrc pavl_data; /* data. */
+ signed char pavl_balance; /* Balance factor. */
+};
+
+/* PAVL traverser structure. */
+struct pavlrc_traverser
+{
+ struct pavlrc_table *pavl_table; /* Tree being traversed. */
+ struct pavlrc_node *pavl_node; /* Current node in tree. */
+};
+
+/* Table functions. */
+struct pavlrc_table *pavlrc_create(struct libavl_allocator *);
+struct pavlrc_table *pavlrc_copy(const struct pavlrc_table *, pavlrc_copy_func *,
+ struct libavl_allocator *);
+void pavlrc_destroy(struct pavlrc_table *);
+struct pavlrc *pavlrc_probe(struct pavlrc_table *, struct pavlrc *);
+struct pavlrc *pavlrc_insert(struct pavlrc_table *, struct pavlrc *);
+struct pavlrc *pavlrc_replace(struct pavlrc_table *, struct pavlrc *);
+struct pavlrc *pavlrc_delete(struct pavlrc_table *, struct pavlrc *);
+struct pavlrc *pavlrc_find(const struct pavlrc_table *, const struct pavlrc *);
+void pavlrc_assert_insert(struct pavlrc_table *, struct pavlrc *);
+struct pavlrc *pavlrc_assert_delete(struct pavlrc_table *, struct pavlrc *);
+
+#define pavlrc_count(table) ((size_t) (table)->pavlrc_count)
+
+/* Table traverser functions. */
+void pavlrc_t_init(struct pavlrc_traverser *, struct pavlrc_table *);
+struct pavlrc *pavlrc_t_first(struct pavlrc_traverser *, struct pavlrc_table *);
+struct pavlrc *pavlrc_t_last(struct pavlrc_traverser *, struct pavlrc_table *);
+struct pavlrc *pavlrc_t_find(struct pavlrc_traverser *, struct pavlrc_table *, struct pavlrc *);
+struct pavlrc *pavlrc_t_insert(struct pavlrc_traverser *, struct pavlrc_table *, struct pavlrc *);
+struct pavlrc *pavlrc_t_copy(struct pavlrc_traverser *, const struct pavlrc_traverser *);
+struct pavlrc *pavlrc_t_next(struct pavlrc_traverser *);
+struct pavlrc *pavlrc_t_prev(struct pavlrc_traverser *);
+struct pavlrc *pavlrc_t_cur(struct pavlrc_traverser *);
+struct pavlrc *pavlrc_t_replace(struct pavlrc_traverser *, struct pavlrc *);
+
+#endif /* pavlrc.h */
Modified: grass-addons/grass7/raster/r.resamp.tps/tps.c
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/tps.c 2017-11-30 13:04:31 UTC (rev 71876)
+++ grass-addons/grass7/raster/r.resamp.tps/tps.c 2017-11-30 14:11:10 UTC (rev 71877)
@@ -6,10 +6,11 @@
#include <grass/raster.h>
#include <grass/segment.h>
#include <grass/glocale.h>
+#include "cache.h"
#include "tps.h"
#include "flag.h"
#include "rclist.h"
-#include "pavl.h"
+#include "pavlrc.h"
static int solvemat(double **m, double a[], double B[], int n)
{
@@ -105,7 +106,7 @@
return (a->r - b->r);
}
-static int load_tps_pnts(SEGMENT *in_seg, DCELL *dval, int n_vars,
+static int load_tps_pnts(struct cache *in_seg, DCELL *dval, int n_vars,
struct tps_pnt *pnts, int n_points,
struct Cell_head *src, struct Cell_head *dst,
double regularization,
@@ -138,7 +139,7 @@
distsum = 0;
for (i = 0; i < n_points; i++) {
- Segment_get(in_seg, (void *)dval, pnts[i].r, pnts[i].c);
+ cache_get(in_seg, (void *)dval, pnts[i].r, pnts[i].c);
/* global */
a[i + 1 + n_vars] = dval[0];
@@ -230,22 +231,6 @@
return 1;
}
-
-static int cmp_rc(const void *first, const void *second)
-{
- struct rc *a = (struct rc *)first, *b = (struct rc *)second;
-
- if (a->row == b->row)
- return (a->col - b->col);
-
- return (a->row - b->row);
-}
-
-static void avl_free_item(void *avl_item)
-{
- G_free(avl_item);
-}
-
static int bfs_search_nn(FLAG *pnt_flag, struct Cell_head *src,
struct tps_pnt *cur_pnts, int max_points,
int row, int col,
@@ -256,19 +241,17 @@
int nextr[8] = {0, -1, 0, 1, -1, -1, 1, 1};
int nextc[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int n, found;
- struct rc next, ngbr_rc, *pngbr_rc;
+ struct rc next;
struct rclist rilist;
- struct pavl_table *visited;
+ struct pavlrc ngbr_rc;
+ struct pavlrc_table *visited;
double dx, dy, dist;
- visited = pavl_create(cmp_rc, NULL);
+ visited = pavlrc_create(NULL);
ngbr_rc.row = row;
ngbr_rc.col = col;
- pngbr_rc = G_malloc(sizeof(struct rc));
- *pngbr_rc = ngbr_rc;
- pavl_insert(visited, pngbr_rc);
- pngbr_rc = NULL;
+ pavlrc_insert(visited, &ngbr_rc);
nrows = src->rows;
ncols = src->cols;
@@ -308,16 +291,9 @@
ngbr_rc.row = rown;
ngbr_rc.col = coln;
- if (pngbr_rc == NULL)
- pngbr_rc = G_malloc(sizeof(struct rc));
-
- *pngbr_rc = ngbr_rc;
-
- if (pavl_insert(visited, pngbr_rc) != NULL) {
+ if (pavlrc_insert(visited, &ngbr_rc) != NULL) {
continue;
}
-
- pngbr_rc = NULL;
rclist_add(&rilist, rown, coln);
@@ -354,9 +330,7 @@
rclist_destroy(&rilist);
- if (pngbr_rc)
- G_free(pngbr_rc);
- pavl_destroy(visited, avl_free_item);
+ pavlrc_destroy(visited);
return found;
}
@@ -371,19 +345,17 @@
int nextr[8] = {0, -1, 0, 1, -1, -1, 1, 1};
int nextc[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int n, found;
- struct rc next, ngbr_rc, *pngbr_rc;
+ struct rc next;
struct rclist rilist;
- struct pavl_table *visited;
+ struct pavlrc ngbr_rc;
+ struct pavlrc_table *visited;
double dx, dy, dist;
- visited = pavl_create(cmp_rc, NULL);
+ visited = pavlrc_create(NULL);
ngbr_rc.row = row;
ngbr_rc.col = col;
- pngbr_rc = G_malloc(sizeof(struct rc));
- *pngbr_rc = ngbr_rc;
- pavl_insert(visited, pngbr_rc);
- pngbr_rc = NULL;
+ pavlrc_insert(visited, &ngbr_rc);
nrows = src->rows;
ncols = src->cols;
@@ -408,16 +380,9 @@
ngbr_rc.row = rown;
ngbr_rc.col = coln;
- if (pngbr_rc == NULL)
- pngbr_rc = G_malloc(sizeof(struct rc));
-
- *pngbr_rc = ngbr_rc;
-
- if (pavl_insert(visited, pngbr_rc) != NULL) {
+ if (pavlrc_insert(visited, &ngbr_rc) != NULL) {
continue;
}
-
- pngbr_rc = NULL;
if (!(FLAG_GET(pnt_flag, rown, coln))) {
rclist_add(&rilist, rown, coln);
@@ -442,9 +407,7 @@
} while (rclist_drop(&rilist, &next)); /* while there are cells to check */
rclist_destroy(&rilist);
- if (pngbr_rc == NULL)
- G_free(pngbr_rc);
- pavl_destroy(visited, avl_free_item);
+ pavlrc_destroy(visited);
return found;
}
@@ -507,7 +470,7 @@
return found;
}
-static double interp_wa(SEGMENT *in_seg, DCELL *dval,
+static double interp_wa(struct cache *in_seg, DCELL *dval,
struct tps_pnt *cur_pnts, int pfound,
int row, int col,
struct Cell_head *src, struct Cell_head *dst,
@@ -533,7 +496,7 @@
src_row = (src->north - cur_pnts[i].r) / src->ns_res;
src_col = (cur_pnts[i].c - src->west) / src->ew_res;
- Segment_get(in_seg, (void *)dval, src_row, src_col);
+ cache_get(in_seg, (void *)dval, src_row, src_col);
dx = cur_pnts[i].c - i_e;
dy = cur_pnts[i].r - i_n;
@@ -557,7 +520,7 @@
return result;
}
-static double lm_rsqr(SEGMENT *in_seg, int n_vars, struct Cell_head *src,
+static double lm_rsqr(struct cache *in_seg, int n_vars, struct Cell_head *src,
struct tps_pnt *cur_pnts, int pfound, double *B)
{
int i, j, r, c;
@@ -575,7 +538,7 @@
r = (int)((src->north - cur_pnts[i].r) / src->ns_res);
c = (int)((cur_pnts[i].c - src->west) / src->ew_res);
- Segment_get(in_seg, (void *)dval, r, c);
+ cache_get(in_seg, (void *)dval, r, c);
obs[i] = dval[0];
est[i] = B[0];
for (j = 1; j <= n_vars; j++) {
@@ -600,8 +563,8 @@
}
-int tps_nn(SEGMENT *in_seg, SEGMENT *var_seg, int n_vars,
- SEGMENT *out_seg, int out_fd, char *mask_name,
+int tps_nn(struct cache *in_seg, struct cache *var_seg, int n_vars,
+ struct cache *out_seg, int out_fd, char *mask_name,
struct Cell_head *src, struct Cell_head *dst,
off_t n_points, int min_points, int max_points,
double regularization, double overlap, int clustered,
@@ -723,7 +686,7 @@
G_percent(row, src->rows, 2);
for (col = 0; col < src->cols; col++) {
- Segment_get(in_seg, (void *)dval, row, col);
+ cache_get(in_seg, (void *)dval, row, col);
if (!Rast_is_d_null_value(dval)) {
FLAG_SET(pnt_flag, row, col);
if (rminp > row)
@@ -751,7 +714,7 @@
G_percent(row, nrows, 2);
for (col = 0; col < ncols; col++) {
- if (Segment_put(out_seg, (void *)&tps_out, row, col) != 1)
+ if (cache_put(out_seg, (void *)&tps_out, row, col) == NULL)
G_fatal_error(_("Unable to write to temporary file"));
}
}
@@ -795,13 +758,13 @@
if (n_vars) {
- Segment_get(var_seg, (void *)varbuf, row, col);
+ cache_get(var_seg, (void *)varbuf, row, col);
if (Rast_is_d_null_value(varbuf))
continue;
}
- Segment_get(out_seg, (void *)&tps_out, row, col);
+ cache_get(out_seg, (void *)&tps_out, row, col);
if (tps_out.wmax > overlap)
continue;
@@ -1074,7 +1037,7 @@
row, col, src, dst, distmax,
&weight);
- Segment_get(out_seg, (void *)&tps_out, irow, icol);
+ cache_get(out_seg, (void *)&tps_out, irow, icol);
/* weight according to distance to nearest point */
if (tps_out.wmax < weight)
@@ -1082,7 +1045,7 @@
tps_out.val += result * weight;
tps_out.wsum += weight;
- Segment_put(out_seg, (void *)&tps_out, row, col);
+ cache_put(out_seg, (void *)&tps_out, row, col);
cnt_wa++;
}
@@ -1177,7 +1140,7 @@
if (n_vars_i) {
- Segment_get(var_seg, (void *)varbuf, irow, icol);
+ cache_get(var_seg, (void *)varbuf, irow, icol);
if (Rast_is_d_null_value(varbuf)) {
continue;
}
@@ -1200,7 +1163,7 @@
i_e = dst->west + (icol + 0.5) * dst->ew_res;
- Segment_get(out_seg, (void *)&tps_out, irow, icol);
+ cache_get(out_seg, (void *)&tps_out, irow, icol);
result = Bc[0];
if (n_vars_ic) {
@@ -1238,7 +1201,7 @@
tps_out.val += result * weight;
tps_out.wsum += weight;
- Segment_put(out_seg, (void *)&tps_out, irow, icol);
+ cache_put(out_seg, (void *)&tps_out, irow, icol);
}
}
}
@@ -1280,7 +1243,7 @@
continue;
}
- Segment_get(out_seg, (void *)&tps_out, row, col);
+ cache_get(out_seg, (void *)&tps_out, row, col);
if (tps_out.wsum == 0)
Rast_set_d_null_value(&outbuf[col], 1);
@@ -1297,8 +1260,8 @@
return 1;
}
-int tps_window(SEGMENT *in_seg, SEGMENT *var_seg, int n_vars,
- SEGMENT *out_seg, int out_fd, char *mask_name,
+int tps_window(struct cache *in_seg, struct cache *var_seg, int n_vars,
+ struct cache *out_seg, int out_fd, char *mask_name,
struct Cell_head *src, struct Cell_head *dst,
off_t n_points, double regularization, double overlap,
int radius, double lm_thresh)
@@ -1394,7 +1357,7 @@
G_percent(row, src->rows, 2);
for (col = 0; col < src->cols; col++) {
- Segment_get(in_seg, (void *)dval, row, col);
+ cache_get(in_seg, (void *)dval, row, col);
if (!Rast_is_d_null_value(dval)) {
FLAG_SET(pnt_flag, row, col);
if (rminp > row)
@@ -1422,7 +1385,7 @@
G_percent(row, nrows, 2);
for (col = 0; col < ncols; col++) {
- if (Segment_put(out_seg, (void *)&tps_out, row, col) != 1)
+ if (cache_put(out_seg, (void *)&tps_out, row, col) == NULL)
G_fatal_error(_("Unable to write to temporary file"));
}
}
@@ -1463,13 +1426,13 @@
if (n_vars) {
- Segment_get(var_seg, (void *)varbuf, row, col);
+ cache_get(var_seg, (void *)varbuf, row, col);
if (Rast_is_d_null_value(varbuf))
continue;
}
- Segment_get(out_seg, (void *)&tps_out, row, col);
+ cache_get(out_seg, (void *)&tps_out, row, col);
if (tps_out.wmax > overlap)
continue;
@@ -1563,7 +1526,7 @@
tps_out.val += result * weight;
tps_out.wsum += weight;
- Segment_put(out_seg, (void *)&tps_out, row, col);
+ cache_put(out_seg, (void *)&tps_out, row, col);
wacnt++;
}
@@ -1637,7 +1600,7 @@
if (n_vars_i) {
- Segment_get(var_seg, (void *)varbuf, irow, icol);
+ cache_get(var_seg, (void *)varbuf, irow, icol);
if (Rast_is_d_null_value(varbuf)) {
continue;
}
@@ -1645,7 +1608,7 @@
i_e = dst->west + (icol + 0.5) * dst->ew_res;
- Segment_get(out_seg, (void *)&tps_out, irow, icol);
+ cache_get(out_seg, (void *)&tps_out, irow, icol);
j = 0;
@@ -1686,7 +1649,7 @@
tps_out.val += result * weight;
tps_out.wsum += weight;
- Segment_put(out_seg, (void *)&tps_out, irow, icol);
+ cache_put(out_seg, (void *)&tps_out, irow, icol);
}
}
}
@@ -1712,7 +1675,7 @@
continue;
}
- Segment_get(out_seg, (void *)&tps_out, row, col);
+ cache_get(out_seg, (void *)&tps_out, row, col);
if (tps_out.wsum == 0)
Rast_set_d_null_value(&outbuf[col], 1);
Modified: grass-addons/grass7/raster/r.resamp.tps/tps.h
===================================================================
--- grass-addons/grass7/raster/r.resamp.tps/tps.h 2017-11-30 13:04:31 UTC (rev 71876)
+++ grass-addons/grass7/raster/r.resamp.tps/tps.h 2017-11-30 14:11:10 UTC (rev 71877)
@@ -12,15 +12,15 @@
double wmax;
};
-int tps_nn(SEGMENT *in_seg, SEGMENT *var_seg, int n_vars,
- SEGMENT *out_seg, int out_fd, char *mask_name,
+int tps_nn(struct cache *in_seg, struct cache *var_seg, int n_vars,
+ struct cache *out_seg, int out_fd, char *mask_name,
struct Cell_head *src, struct Cell_head *dst,
off_t n_points, int min_points, int max_points,
double regularization, double overlap, int do_bfs,
double lm_thresh, double ep_thresh);
-int tps_window(SEGMENT *in_seg, SEGMENT *var_seg, int n_vars,
- SEGMENT *out_seg, int out_fd, char *mask_name,
+int tps_window(struct cache *in_seg, struct cache *var_seg, int n_vars,
+ struct cache *out_seg, int out_fd, char *mask_name,
struct Cell_head *src, struct Cell_head *dst,
off_t n_points, double regularization, double overlap,
int radius, double lm_thresh);
More information about the grass-commit
mailing list