| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | /*******************************************************************************************
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | Copyright (C) 2004,2005,2006,2007,2008 (Nuno A. Fonseca) | 
					
						
							|  |  |  | <nuno.fonseca@gmail.com> | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | as published by the Free Software Foundation; either | 
					
						
							|  |  |  | version 2 of the License, or (at your option) any later | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This program 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 General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Last rev: $Id: range_list.c,v 1.1 2008-03-26 23:05:22 nunofonseca Exp $ | 
					
						
							|  |  |  | **************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-01 23:25:58 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file range_list.c | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @brief Nuno Fonseca range list implementation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @namespace rltree | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | #include "range_list.h"
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void set_num_bit(unsigned int number, char *storage, STATUS status); | 
					
						
							|  |  |  | BOOLEAN is_num_bit(unsigned int number, char *storage, STATUS status); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static void set_quadrant(RL_Node *node, short quadrant, QUADRANT_STATUS status); | 
					
						
							|  |  |  | static QUADRANT_STATUS quadrant_status(RL_Node *node, short quadrant); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static void quadrant_interval(RL_Tree *tree, short quadrant, NUM interval, | 
					
						
							|  |  |  |                               NUM *quad_interval); | 
					
						
							|  |  |  | static NUM get_quadrant_node(RL_Tree *tree, NUM node, short quadrant, | 
					
						
							|  |  |  |                              NUM interval); | 
					
						
							|  |  |  | static unsigned int tree_size(RL_Tree *tree, NUM node, NUM); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | int get_location(RL_Tree *tree, NUM node, short quadrant, NUM interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | long set_in(NUM number, NUM node, NUM node_num, NUM interval, NUM max, | 
					
						
							|  |  |  |             RL_Tree *tree, STATUS status); | 
					
						
							|  |  |  | long compact_node(RL_Tree *, NUM node, NUM next_node, NUM node_interval, | 
					
						
							|  |  |  |                   NUM next_node_interval, NUM next_node_num, short quadrant, | 
					
						
							|  |  |  |                   NUM max); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | BOOLEAN in_tree(NUM number, RL_Tree *tree, NUM node, NUM node_num, | 
					
						
							|  |  |  |                 NUM interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | void display_tree(RL_Tree *tree); | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void idisplay_tree(RL_Tree *tree, NUM node, NUM node_num, NUM interval, | 
					
						
							|  |  |  |                    NUM max); | 
					
						
							|  |  |  | static void display_leaf(RL_Tree *tree, NUM node, NUM node_num, NUM max); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | NUM new_node(RL_Tree *tree, NUM node_father, short quadrant, NUM node_num, | 
					
						
							|  |  |  |              NUM quad_min, NUM quad_max, STATUS); | 
					
						
							|  |  |  | static void root_intervals(RL_Tree *tree); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | NUM next_min(RL_Tree *tree, NUM node, NUM node_num, NUM interval, NUM max, | 
					
						
							|  |  |  |              NUM min); | 
					
						
							|  |  |  | NUM tree_minus(RL_Tree *r1, RL_Tree *r2, NUM node1, NUM node2, NUM node_num, | 
					
						
							|  |  |  |                NUM interval, NUM max); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | RL_Tree *minus_rl(RL_Tree *range1, RL_Tree *range2); | 
					
						
							|  |  |  | void shift_right(RL_Tree *tree, const NUM idx, const long nnodes); | 
					
						
							|  |  |  | void shift_left(RL_Tree *tree, const NUM idx, const long nnodes); | 
					
						
							|  |  |  | void intersect_leafs(char *storage1, char *storage2); | 
					
						
							| 
									
										
										
										
											2008-10-23 22:17:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | // static void print_nodes(RL_Tree* tree);
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | RL_Buffer *buffer = NULL; | 
					
						
							|  |  |  | unsigned int active_bits[16] = {1,    3,     7,     15,   31,   63, | 
					
						
							|  |  |  |                                 127,  255,   511,   1023, 2047, 4095, | 
					
						
							|  |  |  |                                 8191, 16383, 32767, 65535}; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | RL_Tree *new_rl(NUM max_size) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   RL_Tree *new; | 
					
						
							|  |  |  |   RL_Node *buf_ptr; | 
					
						
							|  |  |  |   short q; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   NUM qi, tmp; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (max_size < 2) | 
					
						
							|  |  |  |     max_size = 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   new = (RL_Tree *)malloc(sizeof(RL_Tree)); | 
					
						
							|  |  |  |   if (new == NULL) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   new->range_max = max_size; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   root_intervals(new); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // alloc a block for the nodes
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   new->root = (RL_Node *)calloc(1, NODE_SIZE); | 
					
						
							|  |  |  |   new->size = 1; | 
					
						
							|  |  |  |   new->mem_alloc = NODE_SIZE; // memory allocated
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // reset buffer
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   buf_ptr = new->root; // tree_buffer();
 | 
					
						
							|  |  |  |   ALL_OUT( | 
					
						
							|  |  |  |       &buf_ptr[0]); // Initialize all numbers as being out of the range/interval
 | 
					
						
							|  |  |  |   buf_ptr[0].i_node.num_subnodes = 1; | 
					
						
							|  |  |  |   new->root = buf_ptr; // pointer to the buffer
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   buf_ptr->i_node.num_subnodes = 1; | 
					
						
							|  |  |  |   quadrant_interval(new, 1, max_size, &qi); | 
					
						
							|  |  |  |   tmp = qi + 1; | 
					
						
							|  |  |  |   for (q = 2; q <= BRANCH_FACTOR; ++q) { | 
					
						
							|  |  |  |     if (max_size < qi * (q - 1) + 1) // 16 32 48 64 - 32
 | 
					
						
							|  |  |  |       set_quadrant(new->root, q, R_IGNORE); | 
					
						
							|  |  |  |     tmp += qi; // max_size=16  16+1
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return new; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | RL_Tree *copy_rl(RL_Tree *tree) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   RL_Tree *new; | 
					
						
							|  |  |  |   RL_Node *buf_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   new = (RL_Tree *)malloc(sizeof(RL_Tree)); | 
					
						
							|  |  |  |   buf_ptr = (RL_Node *)calloc(tree->size, NODE_SIZE); | 
					
						
							|  |  |  |   if (new == NULL) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     printf("new==NULL"); | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     free(buf_ptr); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (buf_ptr == NULL) { | 
					
						
							|  |  |  |     printf("buf_ptr==NULL---%lu", tree->size); | 
					
						
							|  |  |  |     free(new); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-30 14:33:32 +01:00
										 |  |  |   memmove(new, tree, sizeof(RL_Tree)); | 
					
						
							|  |  |  |   memmove(buf_ptr, &tree->root[0], tree->size * NODE_SIZE); | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   new->root = buf_ptr; | 
					
						
							|  |  |  |   new->mem_alloc = tree->size *NODE_SIZE; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   return new; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void free_rl(RL_Tree *range) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   // free nodes block
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (range->mem_alloc != 0) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     free(range->root); | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   free(range); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | RL_Tree *set_in_rl(RL_Tree *tree, NUM number, STATUS status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (number > 0 && number <= tree->range_max) | 
					
						
							|  |  |  |     set_in(number, ROOT(tree), 1, ROOT_INTERVAL(tree), tree->range_max, tree, | 
					
						
							|  |  |  |            status); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   printf("Setting: %lu  size=%lu\n", number, tree->size); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   /*if (status==IN && !in_rl(tree,number)) {
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     fprintf(stderr,"Error adding %lu to tree: size=%lu | 
					
						
							|  |  |  |     max=%lu\n",number,tree->size,tree->range_max); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     display_tree(tree); | 
					
						
							|  |  |  |     exit(1); | 
					
						
							|  |  |  |     }*/ | 
					
						
							|  |  |  |   return tree; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Mark all examples in range IN/OUT | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void rl_all(RL_Tree *tree, STATUS status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   for (i = 1; i <= BRANCH_FACTOR; ++i) | 
					
						
							|  |  |  |     if (quadrant_status(NODE(tree, ROOT(tree)), i) != R_IGNORE) { | 
					
						
							|  |  |  |       if (status == IN) | 
					
						
							|  |  |  |         set_quadrant(NODE(tree, ROOT(tree)), i, R_TOTALLY_IN_INTERVAL); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |         set_quadrant(NODE(tree, ROOT(tree)), i, R_NOT_IN_INTERVAL); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   tree->size = 1; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | BOOLEAN in_rl(RL_Tree *tree, NUM number) { | 
					
						
							|  |  |  |   if (number < 1 && number > tree->range_max) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   return in_tree(number, tree, ROOT(tree), 1, ROOT_INTERVAL(tree)); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | BOOLEAN freeze_rl(RL_Tree *range) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   //  reduce memory usage if possible
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   NUM s = range->size * NODE_SIZE; | 
					
						
							|  |  |  |   if (s < range->mem_alloc) { | 
					
						
							|  |  |  |     range->root = (RL_Node *)realloc(range->root, s); | 
					
						
							|  |  |  |     range->mem_alloc = s; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Returns range1 without the numbers in range2 | 
					
						
							|  |  |  |  * Constraint:range1->max==range2->max | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | RL_Tree *minus_rl(RL_Tree *range1, RL_Tree *range2) { | 
					
						
							|  |  |  |   if (range1->range_max != range2->range_max) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   //!!!!tree_minus(range1,range2,ROOT(range1),ROOT(range2),1,ROOT_INTERVAL(range1),range1->range_max);
 | 
					
						
							|  |  |  |   return range1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |  * Returns next number in tree bigger than min | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | NUM rl_next_in_bigger(RL_Tree *tree, NUM min) { | 
					
						
							|  |  |  |   if (tree == NULL) { | 
					
						
							|  |  |  |     fprintf(stdout, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%lu\n", min); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   return next_min(tree, ROOT(tree), 1, ROOT_INTERVAL(tree), tree->range_max, | 
					
						
							|  |  |  |                   min + 1); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | /* ******************************************************************************
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |    Private Functions | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |    ****************************************************************************** | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-05-30 01:01:58 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | static void print_nodes(RL_Tree* tree) { | 
					
						
							|  |  |  |   RL_Node* nodes=tree->root; | 
					
						
							|  |  |  |   int j; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for(j=0;j<tree->size;++j) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     printf("[%d]=%lu\n",j,(unsigned long int)nodes[j].leaf); | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-30 01:01:58 +01:00
										 |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | // treeXquadrantXinterval->quadrant_minXquadrant_max
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static void quadrant_interval(RL_Tree *tree, short quadrant, NUM interval, | 
					
						
							|  |  |  |                               NUM *quad_interval) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IS_ROOT(tree, interval)) { | 
					
						
							|  |  |  |     *quad_interval = tree->root_i; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     *quad_interval = NEXT_INTERVAL(interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // numberXtreeXinterval->quadrantXquadrant_minXquadrant_max
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static void number_quadrant(NUM number, RL_Tree *tree, NUM node_interval, | 
					
						
							|  |  |  |                             NUM node_num, short *quadrant, NUM *quad_min, | 
					
						
							|  |  |  |                             NUM *quad_max) { | 
					
						
							|  |  |  |   NUM tmp = node_num - 1, quad_interval; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   int i; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   quadrant_interval(tree, 1, node_interval, &quad_interval); | 
					
						
							|  |  |  |   i = (number - node_num) / quad_interval + 1; | 
					
						
							|  |  |  |   tmp = node_num - 1 + quad_interval * i; | 
					
						
							|  |  |  |   *quad_max = tmp; | 
					
						
							|  |  |  |   *quadrant = i; | 
					
						
							|  |  |  |   *quad_min = tmp - quad_interval + 1; | 
					
						
							|  |  |  |   // printf("number=%lu node num=%lu quad_interval=%lu-------> quadrant=%d
 | 
					
						
							|  |  |  |   // quad_max=%lu\n",number,node_num,quad_interval,i,tmp);
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * returns the index to the quadrant "quadrant" node | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static NUM get_quadrant_node(RL_Tree *tree, NUM node, short quadrant, | 
					
						
							|  |  |  |                              NUM interval) { | 
					
						
							|  |  |  |   int d = get_location(tree, node, quadrant, interval); | 
					
						
							|  |  |  |   return node + d; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | /*                 src    s
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |  *  src= 1 2 3 4 5 6 _ _ | 
					
						
							|  |  |  |  *  offset= 2 | 
					
						
							|  |  |  |  *  nbytes=6 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |  *  >>>src= 1 2 1 2 3 4 5 6 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |  *                    src    s | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void shift_right(RL_Tree *tree, const NUM idx, const long nnodes) { | 
					
						
							|  |  |  |   long n = idx + nnodes; | 
					
						
							|  |  |  |   RL_Node *s = tree->root; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (nnodes <= 0) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   // print_nodes(tree);
 | 
					
						
							|  |  |  |   while (n >= idx) { | 
					
						
							|  |  |  |     s[n + 1].leaf = s[n].leaf; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     --n; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   // print_nodes(tree);
 | 
					
						
							|  |  |  |   // printf(">>----------------\n");
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void shift_left(RL_Tree *tree, const NUM idx, const long nnodes) { | 
					
						
							|  |  |  |   long n = idx; | 
					
						
							|  |  |  |   RL_Node *s = tree->root; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   // printf("sfit left: idx=%u nnodes=%u max=%u\n",idx,nnodes,tree->size);
 | 
					
						
							|  |  |  |   if (nnodes <= 0) // last element
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   //  print_nodes(tree);
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   while (n < idx + nnodes) { | 
					
						
							|  |  |  |     s[n].leaf = s[n + 1].leaf; | 
					
						
							|  |  |  |     ++n; | 
					
						
							|  |  |  |     ; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   //  print_nodes(tree);
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   // printf("<<----------------\n");
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | NUM new_node(RL_Tree *tree, NUM node_father, short quadrant, | 
					
						
							|  |  |  |              NUM father_interval, NUM quad_min, NUM quad_max, STATUS status) { | 
					
						
							|  |  |  |   // RL_Node *new,*root_node=tree->root;
 | 
					
						
							|  |  |  |   NUM new_interval = +NEXT_INTERVAL(father_interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM times; | 
					
						
							|  |  |  |   NUM new; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   RL_Node *ptr; | 
					
						
							|  |  |  |   new = get_quadrant_node(tree, node_father, quadrant, father_interval); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (tree->mem_alloc != 0) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     // increase array size and shift elements right
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     if (REALLOC_MEM(tree)) { | 
					
						
							|  |  |  |       // printf("new node:resizing memory: current %lu -> new %lu
 | 
					
						
							|  |  |  |       // [%lu]\n",tree->mem_alloc,MEM_SIZE(tree),tree->size);
 | 
					
						
							|  |  |  |       ptr = (RL_Node *)realloc(tree->root, MEM_SIZE(tree)); | 
					
						
							|  |  |  |       if (ptr == NULL) { | 
					
						
							|  |  |  |         fprintf(stderr, "Fatal error:range_list: Unable to allocate memory"); | 
					
						
							|  |  |  |         exit(1); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       tree->root = ptr; | 
					
						
							|  |  |  |       tree->mem_alloc = MEM_SIZE(tree); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     // SHIFT elements at the right and including the current node one position
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     times = tree->size - 1 - new; | 
					
						
							|  |  |  |     shift_right(tree, new, times); | 
					
						
							|  |  |  |     //      SHIFT_NODES((void*)new,times*NODE_SIZE);
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   // update father reference
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   set_quadrant(NODE(tree, node_father), quadrant, R_PARCIALLY_IN_INTERVAL); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   // initialize node
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (status == IN) { | 
					
						
							|  |  |  |     ALL_OUT(NODE(tree, new)); // clear all bits
 | 
					
						
							|  |  |  |     if (!IS_LEAF(new_interval)) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       short q; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       RL_Node *node_ptr = NODE(tree, new); | 
					
						
							|  |  |  |       node_ptr->i_node.num_subnodes = 1; | 
					
						
							|  |  |  |       for (q = 2; q <= BRANCH_FACTOR; ++q) | 
					
						
							|  |  |  |         if (MIN(quad_max, tree->range_max) < | 
					
						
							|  |  |  |             quad_min + | 
					
						
							|  |  |  |                 NEXT_INTERVAL(new_interval) * (q - 1)) // QUADRANT_MAX_VALUE(
 | 
					
						
							|  |  |  |           set_quadrant(NODE(tree, new), q, R_IGNORE); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     // status ==out
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     // SET_LEAF_IN(tree->range_max,NODE(tree,new),quad_min);
 | 
					
						
							|  |  |  |     tree->root[new].leaf = ON_BITS(MIN(16, tree->range_max - quad_min + 1)); | 
					
						
							|  |  |  |     if (!IS_LEAF(new_interval)) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       short q; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       RL_Node *node_ptr = NODE(tree, new); | 
					
						
							|  |  |  |       node_ptr->i_node.num_subnodes = 1; | 
					
						
							|  |  |  |       node_ptr->i_node.quadrant_1 = node_ptr->i_node.quadrant_2 = | 
					
						
							|  |  |  |           node_ptr->i_node.quadrant_3 = node_ptr->i_node.quadrant_4 = | 
					
						
							|  |  |  |               R_TOTALLY_IN_INTERVAL; | 
					
						
							|  |  |  |       for (q = 2; q <= BRANCH_FACTOR; ++q) | 
					
						
							|  |  |  |         if (MIN(quad_max, tree->range_max) < | 
					
						
							|  |  |  |             quad_min + | 
					
						
							|  |  |  |                 NEXT_INTERVAL(new_interval) * (q - 1)) // QUADRANT_MAX_VALUE(
 | 
					
						
							|  |  |  |           set_quadrant(NODE(tree, new), q, R_IGNORE); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // update tree size
 | 
					
						
							|  |  |  |   tree->size++; | 
					
						
							|  |  |  |   return new; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * returns the offset | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | int get_location(RL_Tree *tree, NUM node, short quadrant, NUM node_interval) { | 
					
						
							|  |  |  |   int i, c = 1, tmp; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM next_node; | 
					
						
							|  |  |  |   NUM next_interval; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (quadrant == 1 || IS_LEAF(node_interval)) | 
					
						
							|  |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (LAST_LEVEL_INODE(node_interval)) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     // 1 node = current
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     for (i = 1; i < quadrant; ++i) { | 
					
						
							|  |  |  |       if (quadrant_status(NODE(tree, node), i) == R_PARCIALLY_IN_INTERVAL) | 
					
						
							|  |  |  |         ++c; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return c; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   //
 | 
					
						
							|  |  |  |   // internal range list nodes
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   quadrant_interval(tree, quadrant, node_interval, &next_interval); | 
					
						
							|  |  |  |   i = 1; | 
					
						
							|  |  |  |   next_node = node + 1; | 
					
						
							|  |  |  |   while (i != quadrant && i <= BRANCH_FACTOR) { | 
					
						
							|  |  |  |     if (quadrant_status(NODE(tree, node), i) == R_PARCIALLY_IN_INTERVAL) { | 
					
						
							|  |  |  |       tmp = tree_size(tree, next_node, next_interval); | 
					
						
							|  |  |  |       next_node += tmp; | 
					
						
							|  |  |  |       c += tmp; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     ++i; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   return c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Returns the number of nodes created/deleted. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * number: number to insert from the interval | 
					
						
							|  |  |  |  * node:   index of current node | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |  * node_num: number corresponding to the beginning o the interval represented by | 
					
						
							|  |  |  |  * node | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |  * interval: size of the interval represented in the current node | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | long set_in(NUM number, NUM node, NUM node_num, NUM node_interval, NUM max, | 
					
						
							|  |  |  |             RL_Tree *tree, STATUS status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM next_node; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   long ret_val = tree->size, compacted; | 
					
						
							|  |  |  |   NUM interval = node_interval; | 
					
						
							|  |  |  |   NUM quad_min, quad_max; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   short quadrant; | 
					
						
							|  |  |  |   NUM size; | 
					
						
							|  |  |  |   /* */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (IS_LEAF(interval)) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     // current node is a leaf
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     set_num_bit(number - node_num, (char *)NODE(tree, node), status); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   number_quadrant(number, tree, node_interval, node_num, &quadrant, &quad_min, | 
					
						
							|  |  |  |                   &quad_max); | 
					
						
							|  |  |  |   interval = quad_max - quad_min + 1; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   // select next node
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   switch (status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   case IN: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     // move pointer to next node
 | 
					
						
							|  |  |  |     if (quadrant_status(NODE(tree, node), quadrant) == R_NOT_IN_INTERVAL) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       // new node
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       // display_tree(tree);
 | 
					
						
							|  |  |  |       next_node = new_node(tree, node, quadrant, node_interval, quad_min, | 
					
						
							|  |  |  |                            quad_max, status); | 
					
						
							|  |  |  |     } else if (quadrant_status(NODE(tree, node), quadrant) == | 
					
						
							|  |  |  |                R_TOTALLY_IN_INTERVAL) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       return 0; | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       next_node = get_quadrant_node(tree, node, quadrant, node_interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     break; | 
					
						
							|  |  |  |   case OUT: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     if (quadrant_status(NODE(tree, node), quadrant) == R_TOTALLY_IN_INTERVAL) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       // new node
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       next_node = new_node(tree, node, quadrant, node_interval, quad_min, | 
					
						
							|  |  |  |                            quad_max, status); | 
					
						
							|  |  |  |     } else if (quadrant_status(NODE(tree, node), quadrant) == R_NOT_IN_INTERVAL) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       return 0; | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       next_node = get_quadrant_node(tree, node, quadrant, node_interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     break; | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     printf("set_in: invalid number status %d\n", status); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     exit(1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // insert in tree
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   set_in(number, next_node, quad_min, interval, quad_max, tree, status); | 
					
						
							|  |  |  |   ret_val = tree->size - ret_val; // number of nodes added/removed
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   // compact tree: only if we didn't create new nodes
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   // compacted=compact_node(tree,node,next_node,node_interval,interval,quad_min,quadrant,MIN(quad_max,tree->range_max));
 | 
					
						
							|  |  |  |   compacted = 0; | 
					
						
							|  |  |  |   if (compacted == -1) { | 
					
						
							|  |  |  |     // NUM times=tree->size-1-next_node; // -1 because array position 0
 | 
					
						
							|  |  |  |     shift_left(tree, next_node, 1); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     // update tree size
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     tree->size += compacted; | 
					
						
							|  |  |  |     ret_val += compacted; | 
					
						
							|  |  |  |     // ret_val=0;//compacted;
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   // update subnodes number
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (tree->root[node].i_node.num_subnodes == 255) | 
					
						
							|  |  |  |     size = tree_size(tree, node, interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     size = ret_val + tree->root[node].i_node.num_subnodes; // new subnodes value
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (size > 254) | 
					
						
							|  |  |  |     tree->root[node].i_node.num_subnodes = 255; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     tree->root[node].i_node.num_subnodes = size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   //  if (size <0 ) exit(1);
 | 
					
						
							|  |  |  |   return ret_val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |  * Check if can change quadrant color of node. If it changes, the node is | 
					
						
							|  |  |  |  * deleted and all nodes at right in the array are shifted one position. | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | long compact_node(RL_Tree *tree, NUM node, NUM next_node, NUM node_interval, | 
					
						
							|  |  |  |                   NUM next_node_interval, NUM next_node_num, short quadrant, | 
					
						
							|  |  |  |                   NUM max) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   unsigned int j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   RL_Node *node_ptr = NODE(tree, next_node); // next node pointer
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   // Try to compact a leaf
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (IS_LEAF(next_node_interval)) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     fprintf(stderr, "compact_node: interval node\n"); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     // ALL IN
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     if (LEAF_ALL_IN(node_ptr->leaf)) { | 
					
						
							|  |  |  |       set_quadrant(NODE(tree, node), quadrant, R_TOTALLY_IN_INTERVAL); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // ALL IN: part II
 | 
					
						
							|  |  |  |     // The last node does not need to be all in
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     if (max - next_node_num + 1 <= LEAF_SIZE) { | 
					
						
							|  |  |  |       j = ON_BITS(max - next_node_num + 1); // 153,154,155,156,157,.,.,.,[158
 | 
					
						
							|  |  |  |                                             // -> valor do max=200 devia ser 158
 | 
					
						
							|  |  |  |       if (node_ptr->leaf == j) { | 
					
						
							|  |  |  |         set_quadrant(NODE(tree, node), quadrant, R_TOTALLY_IN_INTERVAL); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // ALL OUT
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     if (LEAF_ALL_OUT(node_ptr->leaf)) { | 
					
						
							|  |  |  |       set_quadrant(NODE(tree, node), quadrant, R_NOT_IN_INTERVAL); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							|  |  |  |       printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>compacted leaf1\n"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     fprintf(stderr, "compact_node:range node\n"); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     // INODE - range list node
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     if (node_ptr->i_node.num_subnodes > 1) // unable to compact
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       return 0; | 
					
						
							|  |  |  |     // ALL IN
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     for (j = 1; j <= BRANCH_FACTOR; ++j) | 
					
						
							|  |  |  |       if (quadrant_status(NODE(tree, next_node), j) != R_IGNORE && | 
					
						
							|  |  |  |           quadrant_status(NODE(tree, next_node), j) != R_TOTALLY_IN_INTERVAL) | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     if (j > BRANCH_FACTOR) { | 
					
						
							|  |  |  |       set_quadrant(NODE(tree, node), quadrant, R_TOTALLY_IN_INTERVAL); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // ALL OUT
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     for (j = 1; j <= BRANCH_FACTOR; ++j) | 
					
						
							|  |  |  |       if (quadrant_status(NODE(tree, next_node), j) != R_IGNORE && | 
					
						
							|  |  |  |           quadrant_status(NODE(tree, next_node), j) != R_NOT_IN_INTERVAL) | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     if (j > BRANCH_FACTOR) { | 
					
						
							|  |  |  |       set_quadrant(NODE(tree, node), quadrant, R_NOT_IN_INTERVAL); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * interval: interval associated to the node | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static unsigned int tree_size(RL_Tree *tree, NUM node, NUM interval) { | 
					
						
							|  |  |  |   unsigned int c = 1, tmp; | 
					
						
							|  |  |  |   int i = 1; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   short status; | 
					
						
							|  |  |  |   NUM next_interval; | 
					
						
							|  |  |  |   NUM next_node; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   RL_Node *node_ptr = NODE(tree, node); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (IS_LEAF(interval)) | 
					
						
							|  |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (node_ptr->i_node.num_subnodes == 255) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     // compute the size of all subtrees
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     next_interval = NEXT_INTERVAL(interval); | 
					
						
							|  |  |  |     for (i = 1; i <= BRANCH_FACTOR; ++i) { | 
					
						
							|  |  |  |       status = quadrant_status(NODE(tree, node), i); | 
					
						
							|  |  |  |       switch (status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       case R_PARCIALLY_IN_INTERVAL: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |         next_node = node + c; //
 | 
					
						
							|  |  |  |         tmp = tree_size(tree, next_node, next_interval); | 
					
						
							|  |  |  |         c += tmp; | 
					
						
							|  |  |  |         //      default:
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   } else | 
					
						
							|  |  |  |     c = node_ptr->i_node.num_subnodes; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   return c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * number >=1 && number <=16 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void set_num_bit(unsigned int number, char *storage, STATUS status) { | 
					
						
							|  |  |  |   if (number >= 8) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     storage++; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     number = number - 8; // =-8
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (status == IN) | 
					
						
							|  |  |  |     BITMAP_insert(*storage, number); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     BITMAP_delete(*storage, number); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | BOOLEAN is_num_bit(unsigned int number, char *storage, STATUS status) { | 
					
						
							|  |  |  |   if (number >= 8) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     storage++; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     number = number - 8; // =-8
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (status == IN) | 
					
						
							|  |  |  |     return BITMAP_member(*storage, number); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     return !BITMAP_member(*storage, number); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static void set_quadrant(RL_Node *node, short quadrant, | 
					
						
							|  |  |  |                          QUADRANT_STATUS status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   switch (quadrant) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   case 1: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     node->i_node.quadrant_1 = status; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     break; | 
					
						
							|  |  |  |   case 2: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     node->i_node.quadrant_2 = status; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     break; | 
					
						
							|  |  |  |   case 3: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     node->i_node.quadrant_3 = status; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     break; | 
					
						
							|  |  |  |   case 4: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     node->i_node.quadrant_4 = status; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     break; | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     fprintf(stderr, "ERROR: set_quadrant: invalid quadrant %d(%d)\n", quadrant, | 
					
						
							|  |  |  |             status); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static QUADRANT_STATUS quadrant_status(RL_Node *node, short quadrant) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   switch (quadrant) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   case 1: | 
					
						
							|  |  |  |     return node->i_node.quadrant_1; | 
					
						
							|  |  |  |   case 2: | 
					
						
							|  |  |  |     return node->i_node.quadrant_2; | 
					
						
							|  |  |  |   case 3: | 
					
						
							|  |  |  |     return node->i_node.quadrant_3; | 
					
						
							|  |  |  |   case 4: | 
					
						
							|  |  |  |     return node->i_node.quadrant_4; | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     fprintf(stderr, "ERROR: quadrant_status: invalid quadrant(%d)\n", quadrant); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static BOOLEAN in_leaf(NUM number, RL_Tree *tree, NUM node, NUM node_num, | 
					
						
							|  |  |  |                        NUM max) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (is_num_bit(number - node_num, (char *)NODE(tree, node), IN)) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | BOOLEAN in_tree(NUM number, RL_Tree *tree, NUM node, NUM node_num, | 
					
						
							|  |  |  |                 NUM node_interval) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM next_node; | 
					
						
							|  |  |  |   short quadrant; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   NUM interval = node_interval; | 
					
						
							|  |  |  |   NUM max = MIN(node_num + interval, tree->range_max); | 
					
						
							|  |  |  |   NUM quad_min, quad_max; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (IS_LEAF(interval)) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     // current node is a leaf
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     return in_leaf(number, tree, node, node_num, max); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   number_quadrant(number, tree, node_interval, node_num, &quadrant, &quad_min, | 
					
						
							|  |  |  |                   &quad_max); | 
					
						
							|  |  |  |   interval = quad_max - quad_min + 1; | 
					
						
							|  |  |  |   node_num = quad_min; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (quadrant_status(NODE(tree, node), quadrant) == R_PARCIALLY_IN_INTERVAL) { | 
					
						
							|  |  |  |     next_node = get_quadrant_node(tree, node, quadrant, node_interval); | 
					
						
							|  |  |  |     return in_tree(number, tree, next_node, node_num, interval); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (quadrant_status(NODE(tree, node), quadrant) == R_TOTALLY_IN_INTERVAL) | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | /* *************************************************************************************************
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | /* I/O */ | 
					
						
							|  |  |  | /* *************************************************************************************************
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static void display_leaf(RL_Tree *tree, NUM node, NUM node_num, NUM max) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   int i; | 
					
						
							|  |  |  |   printf("|"); | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   // for(i=0;i<LEAF_SIZE && node_num+i<=max;++i)
 | 
					
						
							|  |  |  |   for (i = 0; i < LEAF_SIZE; ++i) | 
					
						
							|  |  |  |     if (is_num_bit(i, (char *)NODE(tree, node), IN)) | 
					
						
							|  |  |  |       printf(",%lu", node_num + i); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |       printf(",."); | 
					
						
							|  |  |  |   printf("|"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void display_tree(RL_Tree *tree) { | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   // root node
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   NUM init, max; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM next_node; | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   short status; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   NUM qi, tmp = 0; | 
					
						
							|  |  |  |   next_node = 0; // tree->root;
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   printf("Size:%lu -[1,%lu]\n", tree->size, tree->range_max); | 
					
						
							|  |  |  |   qi = ROOT_INTERVAL(tree) / BRANCH_FACTOR; | 
					
						
							|  |  |  |   // quadrant_interval(tree,1,tree->range_max,&qi);
 | 
					
						
							|  |  |  |   for (i = 1; i <= BRANCH_FACTOR; ++i) { | 
					
						
							|  |  |  |     tmp += qi; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     //
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     init = tmp - qi + 1; | 
					
						
							|  |  |  |     max = tmp; | 
					
						
							|  |  |  |     status = quadrant_status(NODE(tree, 0), i); | 
					
						
							|  |  |  |     switch (status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     case R_PARCIALLY_IN_INTERVAL: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       next_node = get_quadrant_node(tree, ROOT(tree), i, qi * BRANCH_FACTOR); | 
					
						
							|  |  |  |       idisplay_tree(tree, next_node, init, qi, max); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case R_TOTALLY_IN_INTERVAL: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       printf(",[%lu-%lu]", init, MIN(max, tree->range_max)); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     case R_IGNORE: | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       /*  not in */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       printf(",]%lu-%lu[", init, MIN(max, tree->range_max)); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   printf("\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void idisplay_tree(RL_Tree *tree, NUM node, NUM node_num, NUM interval, | 
					
						
							|  |  |  |                    NUM max) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM next_node; | 
					
						
							|  |  |  |   short quadrant; | 
					
						
							|  |  |  |   NUM interval2; | 
					
						
							|  |  |  |   NUM node_num2; | 
					
						
							|  |  |  |   NUM quadrant_max; | 
					
						
							|  |  |  |   short status; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (IS_LEAF(interval)) | 
					
						
							|  |  |  |     return display_leaf(tree, node, node_num, MIN(max, tree->range_max)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   interval2 = NEXT_INTERVAL(interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   for (quadrant = 1; quadrant <= BRANCH_FACTOR; ++quadrant) { | 
					
						
							|  |  |  |     node_num2 = node_num + (quadrant - 1) * interval2; | 
					
						
							|  |  |  |     quadrant_max = QUADRANT_MAX_VALUE(node_num, quadrant, interval2, max); | 
					
						
							|  |  |  |     status = quadrant_status(NODE(tree, node), quadrant); | 
					
						
							|  |  |  |     switch (status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     case R_PARCIALLY_IN_INTERVAL: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       next_node = get_quadrant_node(tree, node, quadrant, interval); | 
					
						
							|  |  |  |       if (IS_LEAF(interval2)) | 
					
						
							|  |  |  |         display_leaf(tree, next_node, node_num2, | 
					
						
							|  |  |  |                      MIN(quadrant_max, tree->range_max)); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         idisplay_tree(tree, next_node, node_num2, interval2, quadrant_max); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case R_TOTALLY_IN_INTERVAL: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       printf(",[%lu-%lu]", node_num2, MIN(node_num2 + interval2 - 1, max)); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case R_IGNORE: | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       printf(",]%lu-%lu[", node_num2, | 
					
						
							|  |  |  |              MIN(tree->range_max, node_num2 + interval2 - 1)); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | /* ***************************************************************************************************
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static NUM next_in_leaf(RL_Tree *tree, NUM node, NUM node_num, NUM max, | 
					
						
							|  |  |  |                         NUM min) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM number; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   number = node_num; | 
					
						
							|  |  |  |   if (number < min) | 
					
						
							|  |  |  |     number = min; | 
					
						
							|  |  |  |   // fprintf(stderr,"next_in_leaf:[%lu,%lu]:min=%lu-->number=%lu\n",node_num,max,min,number);
 | 
					
						
							|  |  |  |   for (; number <= max; ++number) | 
					
						
							|  |  |  |     if (is_num_bit(number - node_num, (char *)NODE(tree, node), IN)) { | 
					
						
							|  |  |  |       // fprintf(stdout,"next_in_leaf:[%lu,%lu]:min=%lu>>>>number=%lu\n",node_num,max,min,number);
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       return number; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   // fprintf(stderr,"!next_in_leaf:[%lu,%lu]:min=%lu-->number=%lu\n",node_num,max,min,number);
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Find next element bigger than min | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | NUM next_min(RL_Tree *tree, NUM node, NUM node_num, NUM interval, NUM max, | 
					
						
							|  |  |  |              NUM min) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM next_node; | 
					
						
							|  |  |  |   short quadrant; | 
					
						
							|  |  |  |   NUM interval2; | 
					
						
							|  |  |  |   NUM node_num2; | 
					
						
							|  |  |  |   NUM quadrant_max; | 
					
						
							|  |  |  |   short status; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (min > tree->range_max) | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   if (IS_LEAF(interval)) | 
					
						
							|  |  |  |     return next_in_leaf(tree, node, node_num, MIN(max, tree->range_max), min); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   interval2 = NEXT_INTERVAL(interval); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   for (quadrant = 1; quadrant <= BRANCH_FACTOR; ++quadrant) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     NUM found; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     node_num2 = node_num + (quadrant - 1) * interval2; | 
					
						
							|  |  |  |     quadrant_max = QUADRANT_MAX_VALUE(node_num, quadrant, interval2, max); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     //------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     status = quadrant_status(NODE(tree, node), quadrant); | 
					
						
							|  |  |  |     switch (status) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     case R_PARCIALLY_IN_INTERVAL: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       next_node = get_quadrant_node(tree, node, quadrant, interval); | 
					
						
							|  |  |  |       found = | 
					
						
							|  |  |  |           next_min(tree, next_node, node_num2, interval2, quadrant_max, min); | 
					
						
							|  |  |  |       if (found > 0) | 
					
						
							|  |  |  |         return found; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     case R_TOTALLY_IN_INTERVAL: | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |       if (min <= quadrant_max && min >= node_num2) | 
					
						
							|  |  |  |         return min; | 
					
						
							|  |  |  |       if (min < node_num2) | 
					
						
							|  |  |  |         return node_num2; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* *******************************************************************************************************/ | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | void intersect_leafs(char *storage1, char *storage2) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BITMAP_difference(*storage1, *storage1, *storage2); | 
					
						
							|  |  |  |   storage1++; | 
					
						
							|  |  |  |   storage2++; | 
					
						
							|  |  |  |   BITMAP_difference(*storage1, *storage1, *storage2); | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Removes the elements in tree1 that are in tree2 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | /*NUM tree_minus(RL_Tree *tree1,RL_Tree *tree2,NUM node1,NUM node2,NUM
 | 
					
						
							|  |  |  | node_num,NUM interval,NUM max) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM next_node1,next_node2; | 
					
						
							|  |  |  |   short quadrant; | 
					
						
							|  |  |  |   NUM interval2; | 
					
						
							|  |  |  |   NUM node_num2; | 
					
						
							|  |  |  |   NUM quadrant_max; | 
					
						
							|  |  |  |   short status1,status2; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   if ( IS_LEAF(interval) ) //
 | 
					
						
							|  |  |  |     return intersect_leafs((char*)NODE(tree1,node1),(char*)NODE(tree2,node2)); | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   interval2=NEXT_INTERVAL(interval); | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   for(quadrant=1;quadrant<=BRANCH_FACTOR;++quadrant){ | 
					
						
							|  |  |  |     node_num2=node_num+(quadrant-1)*interval2; | 
					
						
							|  |  |  |     quadrant_max=QUADRANT_MAX_VALUE(node_num,quadrant,interval2,max); | 
					
						
							|  |  |  |     //------------------------------------------
 | 
					
						
							|  |  |  |     status1=quadrant_status(NODE(tree1,node1),quadrant); | 
					
						
							|  |  |  |     status2=quadrant_status(NODE(tree2,node2),quadrant); | 
					
						
							|  |  |  |     if (status2==R_IGNORE || status2==R_NOT_IN_INTERVAL) { | 
					
						
							|  |  |  |       // do nothing
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     } else if ( status2==R_TOTALLY_IN_INTERVAL && (status1==R_IGNORE || | 
					
						
							|  |  |  | status1==R_NOT_IN_INTERVAL )) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       // do nothing
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     } else if ( status2==R_TOTALLY_IN_INTERVAL && status1==R_TOTALLY_IN_INTERVAL | 
					
						
							|  |  |  | ) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       //  delete entire quadrant subtree in tree1
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     } else if ( status2==R_PARTIALLY_IN_INTERVAL && | 
					
						
							|  |  |  | status1==R_PARTIALLY_IN_INTERVAL){ | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       // call same function
 | 
					
						
							|  |  |  |       next_node1=get_quadrant_node(tree1,node1,quadrant,interval); | 
					
						
							|  |  |  |       next_node2=get_quadrant_node(tree1,node2,quadrant,interval); | 
					
						
							|  |  |  |       tree_minus(tree1,tree2,next_node1,next_node2,node_num2,interval2,quadrant_max); | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |     } else if ( status2==R_PARTIALLY_IN_INTERVAL && | 
					
						
							|  |  |  | status1==R_TOTALLY_IN_INTERVAL) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       // foreach element of tree2, remove it in tree1
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       // this should never happen!!!!
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     switch(status) { | 
					
						
							|  |  |  |     case R_PARCIALLY_IN_INTERVAL: | 
					
						
							|  |  |  |       next_node=get_quadrant_node(tree,node,quadrant,interval); | 
					
						
							|  |  |  |       found=next_min(tree,next_node,node_num2,interval2,quadrant_max,min); | 
					
						
							|  |  |  |       if ( found>0) return found; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case R_TOTALLY_IN_INTERVAL: | 
					
						
							|  |  |  |       if (min<=quadrant_max && min>=node_num2) | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |         return min; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |       if ( min < node_num2 ) return node_num2; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | }*/ | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | /* ***************************************************************************************************
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | // root level
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static NUM norm_tree_size(NUM interval) { | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   NUM tmp; | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   NUM j = BRANCH_FACTOR; | 
					
						
							|  |  |  |   ; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (interval <= LEAF_SIZE * BRANCH_FACTOR) | 
					
						
							|  |  |  |     return LEAF_SIZE; | 
					
						
							|  |  |  |   while (1) { | 
					
						
							|  |  |  |     tmp = LEAF_SIZE * j; | 
					
						
							|  |  |  |     if (tmp * BRANCH_FACTOR >= interval) | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     j *= BRANCH_FACTOR; | 
					
						
							|  |  |  |     ; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return tmp; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  | static void root_intervals(RL_Tree *tree) { | 
					
						
							|  |  |  |   NUM first_i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   first_i = norm_tree_size(tree->range_max); | 
					
						
							|  |  |  |   // k=tree->range_max/first_i+1; // number of large intervals
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   tree->root_i = first_i; | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 15:28:46 +00:00
										 |  |  |   if (tree->root_i * BRANCH_FACTOR < tree->range_max) { | 
					
						
							|  |  |  |     tree->root_i = tree->root_i * BRANCH_FACTOR; | 
					
						
							|  |  |  |     // printf("%lu---->>%lu\n",tree->range_max,tree->root_i);
 | 
					
						
							| 
									
										
										
										
											2008-03-26 23:05:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } |