YAP 7.1.0
range_list.c
Go to the documentation of this file.
1/*******************************************************************************************
2
3Copyright (C) 2004,2005,2006,2007,2008 (Nuno A. Fonseca)
4<nuno.fonseca@gmail.com>
5
6This program is free software; you can redistribute it and/or
7modify it under the terms of the GNU General Public License
8as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later
10version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21
22Last rev: $Id: range_list.c,v 1.1 2008-03-26 23:05:22 nunofonseca Exp $
23**************************************************************************/
24
34#include "range_list.h"
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38
39/*****************************************************************************/
40
41void set_num_bit(unsigned int number, char *storage, STATUS status);
42BOOLEAN is_num_bit(unsigned int number, char *storage, STATUS status);
43
44static void set_quadrant(RL_Node *node, short quadrant, QUADRANT_STATUS status);
45static QUADRANT_STATUS quadrant_status(RL_Node *node, short quadrant);
46
47static void quadrant_interval(RL_Tree *tree, short quadrant, NUM interval,
48 NUM *quad_interval);
49static NUM get_quadrant_node(RL_Tree *tree, NUM node, short quadrant,
50 NUM interval);
51static unsigned int tree_size(RL_Tree *tree, NUM node, NUM);
52
53int get_location(RL_Tree *tree, NUM node, short quadrant, NUM interval);
54
55long set_in(NUM number, NUM node, NUM node_num, NUM interval, NUM max,
56 RL_Tree *tree, STATUS status);
57long compact_node(RL_Tree *, NUM node, NUM next_node, NUM node_interval,
58 NUM next_node_interval, NUM next_node_num, short quadrant,
59 NUM max);
60
61BOOLEAN in_tree(NUM number, RL_Tree *tree, NUM node, NUM node_num,
62 NUM interval);
63void display_tree(RL_Tree *tree);
64void idisplay_tree(RL_Tree *tree, NUM node, NUM node_num, NUM interval,
65 NUM max);
66static void display_leaf(RL_Tree *tree, NUM node, NUM node_num, NUM max);
67
68NUM new_node(RL_Tree *tree, NUM node_father, short quadrant, NUM node_num,
69 NUM quad_min, NUM quad_max, STATUS);
70static void root_intervals(RL_Tree *tree);
71
72NUM next_min(RL_Tree *tree, NUM node, NUM node_num, NUM interval, NUM max,
73 NUM min);
74NUM tree_minus(RL_Tree *r1, RL_Tree *r2, NUM node1, NUM node2, NUM node_num,
75 NUM interval, NUM max);
76
77RL_Tree *minus_rl(RL_Tree *range1, RL_Tree *range2);
78void shift_right(RL_Tree *tree, const NUM idx, const long nnodes);
79void shift_left(RL_Tree *tree, const NUM idx, const long nnodes);
80void intersect_leafs(char *storage1, char *storage2);
81
82// static void print_nodes(RL_Tree* tree);
83
84//
85RL_Buffer *buffer = NULL;
86unsigned int active_bits[16] = {1, 3, 7, 15, 31, 63,
87 127, 255, 511, 1023, 2047, 4095,
88 8191, 16383, 32767, 65535};
89
90/*****************************************************************************/
91/*
92 *
93 *
94 */
95RL_Tree *new_rl(NUM max_size) {
96
97 RL_Tree *new;
98 RL_Node *buf_ptr;
99 short q;
100 NUM qi, tmp;
101
102 if (max_size < 2)
103 max_size = 2;
104
105 new = (RL_Tree *)malloc(sizeof(RL_Tree));
106 if (new == NULL)
107 return NULL;
108
109 new->range_max = max_size;
110 root_intervals(new);
111
112 // alloc a block for the nodes
113 new->root = (RL_Node *)calloc(1, NODE_SIZE);
114 new->size = 1;
115 new->mem_alloc = NODE_SIZE; // memory allocated
116
117 // reset buffer
118 buf_ptr = new->root; // tree_buffer();
119 ALL_OUT(
120 &buf_ptr[0]); // Initialize all numbers as being out of the range/interval
121 buf_ptr[0].i_node.num_subnodes = 1;
122 new->root = buf_ptr; // pointer to the buffer
123
124 buf_ptr->i_node.num_subnodes = 1;
125 quadrant_interval(new, 1, max_size, &qi);
126 tmp = qi + 1;
127 for (q = 2; q <= BRANCH_FACTOR; ++q) {
128 if (max_size < qi * (q - 1) + 1) // 16 32 48 64 - 32
129 set_quadrant(new->root, q, R_IGNORE);
130 tmp += qi; // max_size=16 16+1
131 }
132
133 return new;
134}
135/*
136 *
137 *
138 */
139RL_Tree *copy_rl(RL_Tree *tree) {
140
141 RL_Tree *new;
142 RL_Node *buf_ptr;
143
144 new = (RL_Tree *)malloc(sizeof(RL_Tree));
145 buf_ptr = (RL_Node *)calloc(tree->size, NODE_SIZE);
146 if (new == NULL) {
147 printf("new==NULL");
148 free(buf_ptr);
149 return NULL;
150 }
151 if (buf_ptr == NULL) {
152 printf("buf_ptr==NULL---%lu", tree->size);
153 free(new);
154 return NULL;
155 }
156 memmove(new, tree, sizeof(RL_Tree));
157 memmove(buf_ptr, &tree->root[0], tree->size * NODE_SIZE);
158 new->root = buf_ptr;
159 new->mem_alloc = tree->size *NODE_SIZE;
160 return new;
161}
162/*
163 *
164 *
165 */
166void free_rl(RL_Tree *range) {
167
168 // free nodes block
169 if (range->mem_alloc != 0)
170 free(range->root);
171 //
172 free(range);
173}
174/*
175
176 */
177RL_Tree *set_in_rl(RL_Tree *tree, NUM number, STATUS status) {
178
179 /* */
180 if (number > 0 && number <= tree->range_max)
181 set_in(number, ROOT(tree), 1, ROOT_INTERVAL(tree), tree->range_max, tree,
182 status);
183#ifdef DEBUG
184 printf("Setting: %lu size=%lu\n", number, tree->size);
185#endif
186 /*if (status==IN && !in_rl(tree,number)) {
187 fprintf(stderr,"Error adding %lu to tree: size=%lu
188 max=%lu\n",number,tree->size,tree->range_max);
189 display_tree(tree);
190 exit(1);
191 }*/
192 return tree;
193}
194/*
195 * Mark all examples in range IN/OUT
196 */
197void rl_all(RL_Tree *tree, STATUS status) {
198 int i;
199
200 for (i = 1; i <= BRANCH_FACTOR; ++i)
201 if (quadrant_status(NODE(tree, ROOT(tree)), i) != R_IGNORE) {
202 if (status == IN)
203 set_quadrant(NODE(tree, ROOT(tree)), i, R_TOTALLY_IN_INTERVAL);
204 else
205 set_quadrant(NODE(tree, ROOT(tree)), i, R_NOT_IN_INTERVAL);
206 }
207 tree->size = 1;
208}
209/*
210 *
211 *
212 */
213BOOLEAN in_rl(RL_Tree *tree, NUM number) {
214 if (number < 1 && number > tree->range_max)
215 return FALSE;
216 return in_tree(number, tree, ROOT(tree), 1, ROOT_INTERVAL(tree));
217}
218/*
219 *
220 *
221 */
222BOOLEAN freeze_rl(RL_Tree *range) {
223
224 // reduce memory usage if possible
225 NUM s = range->size * NODE_SIZE;
226 if (s < range->mem_alloc) {
227 range->root = (RL_Node *)realloc(range->root, s);
228 range->mem_alloc = s;
229 }
230 return TRUE;
231}
232/*
233 * Returns range1 without the numbers in range2
234 * Constraint:range1->max==range2->max
235 */
236RL_Tree *minus_rl(RL_Tree *range1, RL_Tree *range2) {
237 if (range1->range_max != range2->range_max)
238 return NULL;
240 return range1;
241}
242
243/*
244 * Returns next number in tree bigger than min
245 */
246NUM rl_next_in_bigger(RL_Tree *tree, NUM min) {
247 if (tree == NULL) {
248 fprintf(stdout, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%lu\n", min);
249 }
250 return next_min(tree, ROOT(tree), 1, ROOT_INTERVAL(tree), tree->range_max,
251 min + 1);
252}
253/* ******************************************************************************
254 Private Functions
255 ******************************************************************************
256 */
257/*
258static void print_nodes(RL_Tree* tree) {
259 RL_Node* nodes=tree->root;
260 int j;
261
262 for(j=0;j<tree->size;++j)
263 printf("[%d]=%lu\n",j,(unsigned long int)nodes[j].leaf);
264
265}
266*/
267
268// treeXquadrantXinterval->quadrant_minXquadrant_max
269static void quadrant_interval(RL_Tree *tree, short quadrant, NUM interval,
270 NUM *quad_interval) {
271
272 if (IS_ROOT(tree, interval)) {
273 *quad_interval = tree->root_i;
274 } else {
275 *quad_interval = NEXT_INTERVAL(interval);
276 }
277}
278
279// numberXtreeXinterval->quadrantXquadrant_minXquadrant_max
280static void number_quadrant(NUM number, RL_Tree *tree, NUM node_interval,
281 NUM node_num, short *quadrant, NUM *quad_min,
282 NUM *quad_max) {
283 NUM tmp = node_num - 1, quad_interval;
284 int i;
285 quadrant_interval(tree, 1, node_interval, &quad_interval);
286 i = (number - node_num) / quad_interval + 1;
287 tmp = node_num - 1 + quad_interval * i;
288 *quad_max = tmp;
289 *quadrant = i;
290 *quad_min = tmp - quad_interval + 1;
291 // printf("number=%lu node num=%lu quad_interval=%lu-------> quadrant=%d
292 // quad_max=%lu\n",number,node_num,quad_interval,i,tmp);
293}
294
295/*
296 * returns the index to the quadrant "quadrant" node
297 */
298static NUM get_quadrant_node(RL_Tree *tree, NUM node, short quadrant,
299 NUM interval) {
300 int d = get_location(tree, node, quadrant, interval);
301 return node + d;
302}
303/* src s
304 * src= 1 2 3 4 5 6 _ _
305 * offset= 2
306 * nbytes=6
307 * >>>src= 1 2 1 2 3 4 5 6
308 * src s
309 */
310void shift_right(RL_Tree *tree, const NUM idx, const long nnodes) {
311 long n = idx + nnodes;
312 RL_Node *s = tree->root;
313
314 if (nnodes <= 0)
315 return;
316 // print_nodes(tree);
317 while (n >= idx) {
318 s[n + 1].leaf = s[n].leaf;
319 --n;
320 }
321 // print_nodes(tree);
322 // printf(">>----------------\n");
323}
324
325void shift_left(RL_Tree *tree, const NUM idx, const long nnodes) {
326 long n = idx;
327 RL_Node *s = tree->root;
328
329 // printf("sfit left: idx=%u nnodes=%u max=%u\n",idx,nnodes,tree->size);
330 if (nnodes <= 0) // last element
331 return;
332
333 // print_nodes(tree);
334 while (n < idx + nnodes) {
335 s[n].leaf = s[n + 1].leaf;
336 ++n;
337 ;
338 }
339 // print_nodes(tree);
340 // printf("<<----------------\n");
341}
342
343/*
344 *
345 *
346 */
347NUM new_node(RL_Tree *tree, NUM node_father, short quadrant,
348 NUM father_interval, NUM quad_min, NUM quad_max, STATUS status) {
349 // RL_Node *new,*root_node=tree->root;
350 NUM new_interval = +NEXT_INTERVAL(father_interval);
351 NUM times;
352 NUM new;
353 RL_Node *ptr;
354 new = get_quadrant_node(tree, node_father, quadrant, father_interval);
355
356 if (tree->mem_alloc != 0) {
357 // increase array size and shift elements right
358 if (REALLOC_MEM(tree)) {
359 // printf("new node:resizing memory: current %lu -> new %lu
360 // [%lu]\n",tree->mem_alloc,MEM_SIZE(tree),tree->size);
361 ptr = (RL_Node *)realloc(tree->root, MEM_SIZE(tree));
362 if (ptr == NULL) {
363 fprintf(stderr, "Fatal error:range_list: Unable to allocate memory");
364 exit(1);
365 }
366 tree->root = ptr;
367 tree->mem_alloc = MEM_SIZE(tree);
368 }
369 // SHIFT elements at the right and including the current node one position
370 times = tree->size - 1 - new;
371 shift_right(tree, new, times);
372 // SHIFT_NODES((void*)new,times*NODE_SIZE);
373 }
374 // update father reference
375 set_quadrant(NODE(tree, node_father), quadrant, R_PARCIALLY_IN_INTERVAL);
376 // initialize node
377 if (status == IN) {
378 ALL_OUT(NODE(tree, new)); // clear all bits
379 if (!IS_LEAF(new_interval)) {
380 short q;
381 RL_Node *node_ptr = NODE(tree, new);
382 node_ptr->i_node.num_subnodes = 1;
383 for (q = 2; q <= BRANCH_FACTOR; ++q)
384 if (MIN(quad_max, tree->range_max) <
385 quad_min +
386 NEXT_INTERVAL(new_interval) * (q - 1)) // QUADRANT_MAX_VALUE(
387 set_quadrant(NODE(tree, new), q, R_IGNORE);
388 }
389 } else {
390 // status ==out
391 // SET_LEAF_IN(tree->range_max,NODE(tree,new),quad_min);
392 tree->root[new].leaf = ON_BITS(MIN(16, tree->range_max - quad_min + 1));
393 if (!IS_LEAF(new_interval)) {
394 short q;
395 RL_Node *node_ptr = NODE(tree, new);
396 node_ptr->i_node.num_subnodes = 1;
397 node_ptr->i_node.quadrant_1 = node_ptr->i_node.quadrant_2 =
398 node_ptr->i_node.quadrant_3 = node_ptr->i_node.quadrant_4 =
399 R_TOTALLY_IN_INTERVAL;
400 for (q = 2; q <= BRANCH_FACTOR; ++q)
401 if (MIN(quad_max, tree->range_max) <
402 quad_min +
403 NEXT_INTERVAL(new_interval) * (q - 1)) // QUADRANT_MAX_VALUE(
404 set_quadrant(NODE(tree, new), q, R_IGNORE);
405 }
406 }
407 // update tree size
408 tree->size++;
409 return new;
410}
411
412/*
413 * returns the offset
414 *
415 */
416int get_location(RL_Tree *tree, NUM node, short quadrant, NUM node_interval) {
417 int i, c = 1, tmp;
418 NUM next_node;
419 NUM next_interval;
420
421 if (quadrant == 1 || IS_LEAF(node_interval))
422 return 1;
423
424 //
425 if (LAST_LEVEL_INODE(node_interval)) {
426 // 1 node = current
427 for (i = 1; i < quadrant; ++i) {
428 if (quadrant_status(NODE(tree, node), i) == R_PARCIALLY_IN_INTERVAL)
429 ++c;
430 }
431 return c;
432 }
433
434 //
435 // internal range list nodes
436 quadrant_interval(tree, quadrant, node_interval, &next_interval);
437 i = 1;
438 next_node = node + 1;
439 while (i != quadrant && i <= BRANCH_FACTOR) {
440 if (quadrant_status(NODE(tree, node), i) == R_PARCIALLY_IN_INTERVAL) {
441 tmp = tree_size(tree, next_node, next_interval);
442 next_node += tmp;
443 c += tmp;
444 }
445 ++i;
446 }
447
448 return c;
449}
450/*
451 * Returns the number of nodes created/deleted.
452 *
453 * number: number to insert from the interval
454 * node: index of current node
455 * node_num: number corresponding to the beginning o the interval represented by
456 * node
457 * interval: size of the interval represented in the current node
458 */
459long set_in(NUM number, NUM node, NUM node_num, NUM node_interval, NUM max,
460 RL_Tree *tree, STATUS status) {
461 NUM next_node;
462 long ret_val = tree->size, compacted;
463 NUM interval = node_interval;
464 NUM quad_min, quad_max;
465 short quadrant;
466 NUM size;
467 /* */
468 if (IS_LEAF(interval)) {
469 // current node is a leaf
470 set_num_bit(number - node_num, (char *)NODE(tree, node), status);
471 return 0;
472 }
473 //
474 number_quadrant(number, tree, node_interval, node_num, &quadrant, &quad_min,
475 &quad_max);
476 interval = quad_max - quad_min + 1;
477 // select next node
478 switch (status) {
479 case IN:
480 // move pointer to next node
481 if (quadrant_status(NODE(tree, node), quadrant) == R_NOT_IN_INTERVAL) {
482 // new node
483 // display_tree(tree);
484 next_node = new_node(tree, node, quadrant, node_interval, quad_min,
485 quad_max, status);
486 } else if (quadrant_status(NODE(tree, node), quadrant) ==
487 R_TOTALLY_IN_INTERVAL)
488 return 0;
489 else
490 next_node = get_quadrant_node(tree, node, quadrant, node_interval);
491 break;
492 case OUT:
493 if (quadrant_status(NODE(tree, node), quadrant) == R_TOTALLY_IN_INTERVAL) {
494 // new node
495 next_node = new_node(tree, node, quadrant, node_interval, quad_min,
496 quad_max, status);
497 } else if (quadrant_status(NODE(tree, node), quadrant) == R_NOT_IN_INTERVAL)
498 return 0;
499 else
500 next_node = get_quadrant_node(tree, node, quadrant, node_interval);
501 break;
502 default:
503 printf("set_in: invalid number status %d\n", status);
504 exit(1);
505 }
506 // insert in tree
507 set_in(number, next_node, quad_min, interval, quad_max, tree, status);
508 ret_val = tree->size - ret_val; // number of nodes added/removed
509 // compact tree: only if we didn't create new nodes
510 // compacted=compact_node(tree,node,next_node,node_interval,interval,quad_min,quadrant,MIN(quad_max,tree->range_max));
511 compacted = 0;
512 if (compacted == -1) {
513 // NUM times=tree->size-1-next_node; // -1 because array position 0
514 shift_left(tree, next_node, 1);
515 // update tree size
516 tree->size += compacted;
517 ret_val += compacted;
518 // ret_val=0;//compacted;
519 }
520 // update subnodes number
521 if (tree->root[node].i_node.num_subnodes == 255)
522 size = tree_size(tree, node, interval);
523 else
524 size = ret_val + tree->root[node].i_node.num_subnodes; // new subnodes value
525
526 if (size > 254)
527 tree->root[node].i_node.num_subnodes = 255;
528 else
529 tree->root[node].i_node.num_subnodes = size;
530
531 // if (size <0 ) exit(1);
532 return ret_val;
533}
534/*
535 * Check if can change quadrant color of node. If it changes, the node is
536 * deleted and all nodes at right in the array are shifted one position.
537 *
538 */
539long compact_node(RL_Tree *tree, NUM node, NUM next_node, NUM node_interval,
540 NUM next_node_interval, NUM next_node_num, short quadrant,
541 NUM max) {
542 unsigned int j;
543
544 RL_Node *node_ptr = NODE(tree, next_node); // next node pointer
545
546 // Try to compact a leaf
547 if (IS_LEAF(next_node_interval)) {
548#ifdef DEBUG
549 fprintf(stderr, "compact_node: interval node\n");
550#endif
551 // ALL IN
552 if (LEAF_ALL_IN(node_ptr->leaf)) {
553 set_quadrant(NODE(tree, node), quadrant, R_TOTALLY_IN_INTERVAL);
554 return -1;
555 }
556 // ALL IN: part II
557 // The last node does not need to be all in
558 if (max - next_node_num + 1 <= LEAF_SIZE) {
559 j = ON_BITS(max - next_node_num + 1); // 153,154,155,156,157,.,.,.,[158
560 // -> valor do max=200 devia ser 158
561 if (node_ptr->leaf == j) {
562 set_quadrant(NODE(tree, node), quadrant, R_TOTALLY_IN_INTERVAL);
563 return -1;
564 }
565 }
566 // ALL OUT
567 if (LEAF_ALL_OUT(node_ptr->leaf)) {
568 set_quadrant(NODE(tree, node), quadrant, R_NOT_IN_INTERVAL);
569#ifdef DEBUG
570 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>compacted leaf1\n");
571#endif
572 return -1;
573 }
574 } else {
575#ifdef DEBUG
576 fprintf(stderr, "compact_node:range node\n");
577#endif
578 // INODE - range list node
579 if (node_ptr->i_node.num_subnodes > 1) // unable to compact
580 return 0;
581 // ALL IN
582 for (j = 1; j <= BRANCH_FACTOR; ++j)
583 if (quadrant_status(NODE(tree, next_node), j) != R_IGNORE &&
584 quadrant_status(NODE(tree, next_node), j) != R_TOTALLY_IN_INTERVAL)
585 break;
586
587 if (j > BRANCH_FACTOR) {
588 set_quadrant(NODE(tree, node), quadrant, R_TOTALLY_IN_INTERVAL);
589 return -1;
590 }
591 // ALL OUT
592 for (j = 1; j <= BRANCH_FACTOR; ++j)
593 if (quadrant_status(NODE(tree, next_node), j) != R_IGNORE &&
594 quadrant_status(NODE(tree, next_node), j) != R_NOT_IN_INTERVAL)
595 break;
596
597 if (j > BRANCH_FACTOR) {
598 set_quadrant(NODE(tree, node), quadrant, R_NOT_IN_INTERVAL);
599 return -1;
600 }
601 }
602 return 0;
603}
604
605/*
606 * interval: interval associated to the node
607 */
608static unsigned int tree_size(RL_Tree *tree, NUM node, NUM interval) {
609 unsigned int c = 1, tmp;
610 int i = 1;
611 short status;
612 NUM next_interval;
613 NUM next_node;
614 RL_Node *node_ptr = NODE(tree, node);
615
616 if (IS_LEAF(interval))
617 return 1;
618
619 if (node_ptr->i_node.num_subnodes == 255) {
620 // compute the size of all subtrees
621 next_interval = NEXT_INTERVAL(interval);
622 for (i = 1; i <= BRANCH_FACTOR; ++i) {
623 status = quadrant_status(NODE(tree, node), i);
624 switch (status) {
625 case R_PARCIALLY_IN_INTERVAL:
626 next_node = node + c; //
627 tmp = tree_size(tree, next_node, next_interval);
628 c += tmp;
629 // default:
630 }
631 }
632 } else
633 c = node_ptr->i_node.num_subnodes;
634 return c;
635}
636/*
637 * number >=1 && number <=16
638 */
639void set_num_bit(unsigned int number, char *storage, STATUS status) {
640 if (number >= 8) {
641 storage++;
642 number = number - 8; // =-8
643 }
644 if (status == IN)
645 BITMAP_insert(*storage, number);
646 else
647 BITMAP_delete(*storage, number);
648}
649/*
650 */
651BOOLEAN is_num_bit(unsigned int number, char *storage, STATUS status) {
652 if (number >= 8) {
653 storage++;
654 number = number - 8; // =-8
655 }
656 if (status == IN)
657 return BITMAP_member(*storage, number);
658 else
659 return !BITMAP_member(*storage, number);
660}
661/*
662 *
663 */
664static void set_quadrant(RL_Node *node, short quadrant,
665 QUADRANT_STATUS status) {
666
667 switch (quadrant) {
668 case 1:
669 node->i_node.quadrant_1 = status;
670 break;
671 case 2:
672 node->i_node.quadrant_2 = status;
673 break;
674 case 3:
675 node->i_node.quadrant_3 = status;
676 break;
677 case 4:
678 node->i_node.quadrant_4 = status;
679 break;
680 default:
681 fprintf(stderr, "ERROR: set_quadrant: invalid quadrant %d(%d)\n", quadrant,
682 status);
683 }
684}
685/*
686 *
687 */
688static QUADRANT_STATUS quadrant_status(RL_Node *node, short quadrant) {
689
690 switch (quadrant) {
691 case 1:
692 return node->i_node.quadrant_1;
693 case 2:
694 return node->i_node.quadrant_2;
695 case 3:
696 return node->i_node.quadrant_3;
697 case 4:
698 return node->i_node.quadrant_4;
699 default:
700 fprintf(stderr, "ERROR: quadrant_status: invalid quadrant(%d)\n", quadrant);
701 }
702 return 0;
703}
704/*
705 *
706 *
707 */
708static BOOLEAN in_leaf(NUM number, RL_Tree *tree, NUM node, NUM node_num,
709 NUM max) {
710
711 if (is_num_bit(number - node_num, (char *)NODE(tree, node), IN))
712 return TRUE;
713 return FALSE;
714}
715
716/*
717 *
718 *
719 */
720BOOLEAN in_tree(NUM number, RL_Tree *tree, NUM node, NUM node_num,
721 NUM node_interval) {
722 NUM next_node;
723 short quadrant;
724 NUM interval = node_interval;
725 NUM max = MIN(node_num + interval, tree->range_max);
726 NUM quad_min, quad_max;
727
728 /* */
729 if (IS_LEAF(interval))
730 // current node is a leaf
731 return in_leaf(number, tree, node, node_num, max);
732
733 number_quadrant(number, tree, node_interval, node_num, &quadrant, &quad_min,
734 &quad_max);
735 interval = quad_max - quad_min + 1;
736 node_num = quad_min;
737
738 if (quadrant_status(NODE(tree, node), quadrant) == R_PARCIALLY_IN_INTERVAL) {
739 next_node = get_quadrant_node(tree, node, quadrant, node_interval);
740 return in_tree(number, tree, next_node, node_num, interval);
741 }
742 if (quadrant_status(NODE(tree, node), quadrant) == R_TOTALLY_IN_INTERVAL)
743 return TRUE;
744
745 return FALSE;
746}
747
748/* *************************************************************************************************
749 */
750/* I/O */
751/* *************************************************************************************************
752 */
753
754/*
755 *
756 */
757static void display_leaf(RL_Tree *tree, NUM node, NUM node_num, NUM max) {
758 int i;
759 printf("|");
760 // for(i=0;i<LEAF_SIZE && node_num+i<=max;++i)
761 for (i = 0; i < LEAF_SIZE; ++i)
762 if (is_num_bit(i, (char *)NODE(tree, node), IN))
763 printf(",%lu", node_num + i);
764 else
765 printf(",.");
766 printf("|");
767}
768/*
769 *
770 */
771void display_tree(RL_Tree *tree) {
772
773 // root node
774 NUM init, max;
775 NUM next_node;
776 int i;
777 short status;
778
779 NUM qi, tmp = 0;
780 next_node = 0; // tree->root;
781
782 printf("Size:%lu -[1,%lu]\n", tree->size, tree->range_max);
783 qi = ROOT_INTERVAL(tree) / BRANCH_FACTOR;
784 // quadrant_interval(tree,1,tree->range_max,&qi);
785 for (i = 1; i <= BRANCH_FACTOR; ++i) {
786 tmp += qi;
787 //
788 init = tmp - qi + 1;
789 max = tmp;
790 status = quadrant_status(NODE(tree, 0), i);
791 switch (status) {
792 case R_PARCIALLY_IN_INTERVAL:
793 next_node = get_quadrant_node(tree, ROOT(tree), i, qi * BRANCH_FACTOR);
794 idisplay_tree(tree, next_node, init, qi, max);
795 break;
796 case R_TOTALLY_IN_INTERVAL:
797 printf(",[%lu-%lu]", init, MIN(max, tree->range_max));
798 break;
799 case R_IGNORE:
800 break;
801 default:
802 /* not in */
803 printf(",]%lu-%lu[", init, MIN(max, tree->range_max));
804 }
805 }
806 printf("\n");
807}
808/*
809 *
810 *
811 */
812void idisplay_tree(RL_Tree *tree, NUM node, NUM node_num, NUM interval,
813 NUM max) {
814 NUM next_node;
815 short quadrant;
816 NUM interval2;
817 NUM node_num2;
818 NUM quadrant_max;
819 short status;
820
821 if (IS_LEAF(interval))
822 return display_leaf(tree, node, node_num, MIN(max, tree->range_max));
823
824 interval2 = NEXT_INTERVAL(interval);
825 //
826 for (quadrant = 1; quadrant <= BRANCH_FACTOR; ++quadrant) {
827 node_num2 = node_num + (quadrant - 1) * interval2;
828 quadrant_max = QUADRANT_MAX_VALUE(node_num, quadrant, interval2, max);
829 status = quadrant_status(NODE(tree, node), quadrant);
830 switch (status) {
831 case R_PARCIALLY_IN_INTERVAL:
832 next_node = get_quadrant_node(tree, node, quadrant, interval);
833 if (IS_LEAF(interval2))
834 display_leaf(tree, next_node, node_num2,
835 MIN(quadrant_max, tree->range_max));
836 else
837 idisplay_tree(tree, next_node, node_num2, interval2, quadrant_max);
838 break;
839 case R_TOTALLY_IN_INTERVAL:
840 printf(",[%lu-%lu]", node_num2, MIN(node_num2 + interval2 - 1, max));
841 break;
842 case R_IGNORE:
843 break;
844 default:
845 printf(",]%lu-%lu[", node_num2,
846 MIN(tree->range_max, node_num2 + interval2 - 1));
847 }
848 }
849}
850
851/* ***************************************************************************************************
852 */
853static NUM next_in_leaf(RL_Tree *tree, NUM node, NUM node_num, NUM max,
854 NUM min) {
855 NUM number;
856 number = node_num;
857 if (number < min)
858 number = min;
859 // fprintf(stderr,"next_in_leaf:[%lu,%lu]:min=%lu-->number=%lu\n",node_num,max,min,number);
860 for (; number <= max; ++number)
861 if (is_num_bit(number - node_num, (char *)NODE(tree, node), IN)) {
862 // fprintf(stdout,"next_in_leaf:[%lu,%lu]:min=%lu>>>>number=%lu\n",node_num,max,min,number);
863 return number;
864 }
865 // fprintf(stderr,"!next_in_leaf:[%lu,%lu]:min=%lu-->number=%lu\n",node_num,max,min,number);
866 return 0;
867}
868
869/*
870 * Find next element bigger than min
871 *
872 */
873NUM next_min(RL_Tree *tree, NUM node, NUM node_num, NUM interval, NUM max,
874 NUM min) {
875 NUM next_node;
876 short quadrant;
877 NUM interval2;
878 NUM node_num2;
879 NUM quadrant_max;
880 short status;
881
882 if (min > tree->range_max)
883 return 0;
884 if (IS_LEAF(interval))
885 return next_in_leaf(tree, node, node_num, MIN(max, tree->range_max), min);
886
887 interval2 = NEXT_INTERVAL(interval);
888 //
889 for (quadrant = 1; quadrant <= BRANCH_FACTOR; ++quadrant) {
890 NUM found;
891 node_num2 = node_num + (quadrant - 1) * interval2;
892 quadrant_max = QUADRANT_MAX_VALUE(node_num, quadrant, interval2, max);
893 //------------------------------------------
894 status = quadrant_status(NODE(tree, node), quadrant);
895 switch (status) {
896 case R_PARCIALLY_IN_INTERVAL:
897 next_node = get_quadrant_node(tree, node, quadrant, interval);
898 found =
899 next_min(tree, next_node, node_num2, interval2, quadrant_max, min);
900 if (found > 0)
901 return found;
902 break;
903 case R_TOTALLY_IN_INTERVAL:
904 if (min <= quadrant_max && min >= node_num2)
905 return min;
906 if (min < node_num2)
907 return node_num2;
908 }
909 }
910 return 0;
911}
912
913/* *******************************************************************************************************/
914/*
915 *
916 */
917void intersect_leafs(char *storage1, char *storage2) {
918
919 BITMAP_difference(*storage1, *storage1, *storage2);
920 storage1++;
921 storage2++;
922 BITMAP_difference(*storage1, *storage1, *storage2);
923}
924/*
925 * Removes the elements in tree1 that are in tree2
926 *
927 */
928/*NUM tree_minus(RL_Tree *tree1,RL_Tree *tree2,NUM node1,NUM node2,NUM
929node_num,NUM interval,NUM max) {
930 NUM next_node1,next_node2;
931 short quadrant;
932 NUM interval2;
933 NUM node_num2;
934 NUM quadrant_max;
935 short status1,status2;
936
937
938 if ( IS_LEAF(interval) ) //
939 return intersect_leafs((char*)NODE(tree1,node1),(char*)NODE(tree2,node2));
940
941 interval2=NEXT_INTERVAL(interval);
942 //
943 for(quadrant=1;quadrant<=BRANCH_FACTOR;++quadrant){
944 node_num2=node_num+(quadrant-1)*interval2;
945 quadrant_max=QUADRANT_MAX_VALUE(node_num,quadrant,interval2,max);
946 //------------------------------------------
947 status1=quadrant_status(NODE(tree1,node1),quadrant);
948 status2=quadrant_status(NODE(tree2,node2),quadrant);
949 if (status2==R_IGNORE || status2==R_NOT_IN_INTERVAL) {
950 // do nothing
951 } else if ( status2==R_TOTALLY_IN_INTERVAL && (status1==R_IGNORE ||
952status1==R_NOT_IN_INTERVAL )) {
953 // do nothing
954 } else if ( status2==R_TOTALLY_IN_INTERVAL && status1==R_TOTALLY_IN_INTERVAL
955) {
956 // delete entire quadrant subtree in tree1
957 } else if ( status2==R_PARTIALLY_IN_INTERVAL &&
958status1==R_PARTIALLY_IN_INTERVAL){
959 // call same function
960 next_node1=get_quadrant_node(tree1,node1,quadrant,interval);
961 next_node2=get_quadrant_node(tree1,node2,quadrant,interval);
962 tree_minus(tree1,tree2,next_node1,next_node2,node_num2,interval2,quadrant_max);
963 } else if ( status2==R_PARTIALLY_IN_INTERVAL &&
964status1==R_TOTALLY_IN_INTERVAL) {
965 // foreach element of tree2, remove it in tree1
966
967 } else {
968 // this should never happen!!!!
969 }
970 switch(status) {
971 case R_PARCIALLY_IN_INTERVAL:
972 next_node=get_quadrant_node(tree,node,quadrant,interval);
973 found=next_min(tree,next_node,node_num2,interval2,quadrant_max,min);
974 if ( found>0) return found;
975 break;
976 case R_TOTALLY_IN_INTERVAL:
977 if (min<=quadrant_max && min>=node_num2)
978 return min;
979 if ( min < node_num2 ) return node_num2;
980 }
981
982 }
983 return 0;
984}*/
985/* ***************************************************************************************************
986 */
987// root level
988static NUM norm_tree_size(NUM interval) {
989 NUM tmp;
990 NUM j = BRANCH_FACTOR;
991 ;
992
993 if (interval <= LEAF_SIZE * BRANCH_FACTOR)
994 return LEAF_SIZE;
995 while (1) {
996 tmp = LEAF_SIZE * j;
997 if (tmp * BRANCH_FACTOR >= interval)
998 break;
999 j *= BRANCH_FACTOR;
1000 ;
1001 }
1002 return tmp;
1003}
1004//
1005static void root_intervals(RL_Tree *tree) {
1006 NUM first_i;
1007
1008 first_i = norm_tree_size(tree->range_max);
1009 // k=tree->range_max/first_i+1; // number of large intervals
1010
1011 tree->root_i = first_i;
1012
1013 if (tree->root_i * BRANCH_FACTOR < tree->range_max) {
1014 tree->root_i = tree->root_i * BRANCH_FACTOR;
1015 // printf("%lu---->>%lu\n",tree->range_max,tree->root_i);
1016 }
1017}
RL_Tree * minus_rl(RL_Tree *range1, RL_Tree *range2)
Definition: range_list.c:236
range list core data-structures