GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
cell_stats.c
Go to the documentation of this file.
1 #include <grass/gis.h>
2 #include <stdlib.h>
3 
4 #define INCR 10
5 #define SHIFT 6
6 
7 static int NCATS = 1 << SHIFT;
8 
9 #define NODE struct Cell_stats_node
10 
11 static int next_node(struct Cell_stats *);
12 static int init_node(NODE *, int, int);
13 
14 
34 int G_init_cell_stats(struct Cell_stats *s)
35 {
36  s->N = 0;
37  s->tlen = INCR;
38  s->node = (NODE *) G_malloc(s->tlen * sizeof(NODE));
39  s->null_data_count = 0;
40 
41  return 1;
42 }
43 
44 
67 int G_update_cell_stats(const CELL * cell, int n, struct Cell_stats *s)
68 {
69  CELL cat;
70  register int p, q;
71  int idx, offset;
72  int N;
73  register NODE *node, *pnode;
74  register NODE *new_node;
75 
76  if (n <= 0)
77  return 1;
78 
79  node = s->node;
80 
81  /* first non-null node is special case */
82  if ((N = s->N) == 0) {
83  cat = *cell++;
84  while (G_is_c_null_value(&cat)) {
85  s->null_data_count++;
86  cat = *cell++;
87  n--;
88  }
89  if (n > 0) { /* if there are some non-null cells */
90  N = 1;
91  if (cat < 0) {
92  idx = -((-cat) >> SHIFT) - 1;
93  offset = cat + ((-idx) << SHIFT) - 1;
94  }
95  else {
96  idx = cat >> SHIFT;
97  offset = cat - (idx << SHIFT);
98  }
99  fflush(stderr);
100  init_node(&node[1], idx, offset);
101  node[1].right = 0;
102  n--;
103  }
104  }
105  while (n-- > 0) {
106  cat = *cell++;
107  if (G_is_c_null_value(&cat)) {
108  s->null_data_count++;
109  continue;
110  }
111  if (cat < 0) {
112  idx = -((-cat) >> SHIFT) - 1;
113  offset = cat + ((-idx) << SHIFT) - 1;
114  }
115  else {
116  idx = cat >> SHIFT;
117  offset = cat - (idx << SHIFT);
118  }
119 
120  q = 1;
121  while (q > 0) {
122  pnode = &node[p = q];
123  if (pnode->idx == idx) {
124  pnode->count[offset]++;
125  break;
126  }
127  if (pnode->idx > idx)
128  q = pnode->left; /* go left */
129  else
130  q = pnode->right; /* go right */
131  }
132  if (q > 0)
133  continue; /* found */
134 
135  /* new node */
136  N++;
137 
138  /* grow the tree? */
139  if (N >= s->tlen) {
140  node =
141  (NODE *) G_realloc((char *)node,
142  sizeof(NODE) * (s->tlen += INCR));
143  pnode = &node[p]; /* realloc moves node, must reassign pnode */
144  }
145 
146  /* add node to tree */
147  init_node(new_node = &node[N], idx, offset);
148 
149  if (pnode->idx > idx) {
150  new_node->right = -p; /* create thread */
151  pnode->left = N; /* insert left */
152  }
153  else {
154  new_node->right = pnode->right; /* copy right link/thread */
155  pnode->right = N; /* add right */
156  }
157  } /* while n-- > 0 */
158  s->N = N;
159  s->node = node;
160 
161  return 0;
162 }
163 
164 static int init_node(NODE * node, int idx, int offset)
165 {
166  register long *count;
167  register int i;
168 
169  count = node->count = (long *)G_calloc(i = NCATS, sizeof(long));
170  while (i--)
171  *count++ = 0;
172  node->idx = idx;
173  node->count[offset] = 1;
174  node->left = 0;
175 
176  return 0;
177 }
178 
179 
204 int G_find_cell_stat(CELL cat, long *count, const struct Cell_stats *s)
205 {
206  register int q;
207  register int idx;
208  int offset;
209 
210  *count = 0;
211  if (G_is_c_null_value(&cat)) {
212  *count = s->null_data_count;
213  return (*count != 0);
214  }
215 
216  if (s->N <= 0)
217  return 0;
218 
219  /*
220  if (cat < 0)
221  {
222  idx = -(-cat/NCATS) - 1;
223  offset = cat - idx*NCATS - 1;
224  }
225  else
226  {
227  idx = cat/NCATS;
228  offset = cat - idx*NCATS;
229  }
230  */
231  if (cat < 0) {
232  idx = -((-cat) >> SHIFT) - 1;
233  offset = cat + ((-idx) << SHIFT) - 1;
234  }
235  else {
236  idx = cat >> SHIFT;
237  offset = cat - (idx << SHIFT);
238  }
239 
240  q = 1;
241  while (q > 0) {
242  if (s->node[q].idx == idx) {
243  *count = s->node[q].count[offset];
244  return (*count != 0);
245  }
246  if (s->node[q].idx > idx)
247  q = s->node[q].left; /* go left */
248  else
249  q = s->node[q].right; /* go right */
250  }
251  return 0;
252 }
253 
254 
265 int G_rewind_cell_stats(struct Cell_stats *s)
266 {
267  int q;
268 
269  if (s->N <= 0)
270  return 1;
271  /* start at root and go all the way to the left */
272  s->curp = 1;
273  while ((q = s->node[s->curp].left))
274  s->curp = q;
275  s->curoffset = -1;
276 
277  return 0;
278 }
279 
280 static int next_node(struct Cell_stats *s)
281 {
282  int q;
283 
284  /* go to the right */
285  s->curp = s->node[s->curp].right;
286 
287  if (s->curp == 0) /* no more */
288  return 0;
289 
290  if (s->curp < 0) { /* thread. stop here */
291  s->curp = -(s->curp);
292  return 1;
293  }
294 
295  while ((q = s->node[s->curp].left)) /* now go all the way left */
296  s->curp = q;
297 
298  return 1;
299 }
300 
301 
338 int G_next_cell_stat(CELL * cat, long *count, struct Cell_stats *s)
339 {
340  int idx;
341 
342  /* first time report stats for null */
343  /* decided not to return stats for null in this function
344  static int null_reported = 0;
345  if(!null_reported && s->null_data_count > 0)
346  {
347  *count = s->null_data_count;
348  G_set_c_null_value(&cat,1);
349  null_reported = 1;
350  return 1;
351  }
352  */
353  if (s->N <= 0)
354  return 0;
355  for (;;) {
356  s->curoffset++;
357  if (s->curoffset >= NCATS) {
358  if (!next_node(s))
359  return 0;
360  s->curoffset = -1;
361  continue;
362  }
363  if ((*count = s->node[s->curp].count[s->curoffset])) {
364  idx = s->node[s->curp].idx;
365 
366  /*
367  if (idx < 0)
368  *cat = idx*NCATS + s->curoffset+1;
369  else
370  *cat = idx*NCATS + s->curoffset;
371  */
372  if (idx < 0)
373  *cat = -((-idx) << SHIFT) + s->curoffset + 1;
374  else
375  *cat = (idx << SHIFT) + s->curoffset;
376 
377  return 1;
378  }
379  }
380 }
381 
382 
396 int G_get_stats_for_null_value(long *count, const struct Cell_stats *s)
397 {
398  *count = s->null_data_count;
399  return 1;
400 }
401 
402 
413 int G_free_cell_stats(struct Cell_stats *s)
414 {
415  int i;
416 
417  for (i = 1; i <= s->N; i++)
418  G_free(s->node[i].count);
419  G_free(s->node);
420 
421  return 0;
422 }
int G_is_c_null_value(const CELL *cellVal)
Returns 1 if cell is NULL, 0 otherwise. This will test if the value cell is the largest int...
Definition: null_val.c:244
int G_free_cell_stats(struct Cell_stats *s)
free cell stats
Definition: cell_stats.c:413
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
tuple q
Definition: forms.py:2019
int count
int G_next_cell_stat(CELL *cat, long *count, struct Cell_stats *s)
retrieve sorted cell stats
Definition: cell_stats.c:338
#define SHIFT
Definition: cell_stats.c:5
#define INCR
Definition: cell_stats.c:4
int G_get_stats_for_null_value(long *count, const struct Cell_stats *s)
Get a number of null values from stats structure. Note: when reporting values which appear in a map u...
Definition: cell_stats.c:396
int G_find_cell_stat(CELL cat, long *count, const struct Cell_stats *s)
random query of cell stats
Definition: cell_stats.c:204
#define NODE
Definition: cell_stats.c:9
int G_update_cell_stats(const CELL *cell, int n, struct Cell_stats *s)
add data to cell stats
Definition: cell_stats.c:67
int G_rewind_cell_stats(struct Cell_stats *s)
reset/rewind cell stats
Definition: cell_stats.c:265
#define N
Definition: inverse.c:8
CELL cat
Definition: g3dcats.c:90
int G_init_cell_stats(struct Cell_stats *s)
initialize cell stats
Definition: cell_stats.c:34
int n
Definition: dataquad.c:291