[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