YAP 7.1.0
range_list.h
Go to the documentation of this file.
1/*******************************************************************************************
2
3Copyright (C) 2004,2005,2006,2007,2008 (Nuno A. Fonseca)
4<nuno.fonseca@gmail.com>
5
6This program is free software; you can redistribute it and/or
7modify it under the terms of the GNU General Public License
8as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later
10version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21
22Last rev: $Id: range_list.h,v 1.1 2008-03-26 23:05:22 nunofonseca Exp $
23**************************************************************************/
24
34/*
35 Leaf
36 Each leaf uses 16 bits ( each bit represents one number )
37
38 */
39#define NUM unsigned long
40/*
41 Node
42 Each node (non leaf) uses 8 bits.
43 - 8 bits are used to represent the state of the 4 subtrees ( subranges ).
44 - 2 bits are used to represent the state for each subtreee
45
46 States of a subtree:
47 00 (0) - range not in interval
48 11 (3)- all range in interval
49 10 (2)- range parcially in interval
50
51 An extra byte is used to keep the number of nodes in the subtrees.
52 */
53struct s_node {
54 // short quadrant;
55 unsigned short int quadrant_1 : 2; //
56 unsigned short int quadrant_2 : 2;
57 unsigned short int quadrant_3 : 2;
58 unsigned short int quadrant_4 : 2;
59 unsigned short int num_subnodes : 8;
60};
61
62typedef enum {
63 R_TOTALLY_IN_INTERVAL = 3,
64 R_PARCIALLY_IN_INTERVAL = 2,
65 R_NOT_IN_INTERVAL = 0,
66 R_IGNORE = 1
67} QUADRANT_STATUS;
68
69#define BRANCH_FACTOR 4 /* factor of division of the range */
70#define LEAF_SIZE 16 /* how many numbers are represented by a leaf */
71
72#define NODE_SIZE sizeof(RL_Node)
73
74#define NODE(tree, idx) (RL_Node *)&tree->root[idx]
75#define ROOT(tree) 0
76
77#define IS_ROOT(tree, interval) (tree->range_max <= interval)
78#define ROOT_INTERVAL(tree) (tree->root_i * BRANCH_FACTOR)
79
80#define MIN(a, b) ((a < b) ? a : b)
81
82#define ON_BITS(n) (active_bits[n - 1]) // mask to check if bits until n are in
83#define SET_LEAF_IN(max, node, quad_i) \
84 (node.leaf = \
85 ON_BITS(max - quad_i + 1)) // mask to check if bits until n are in
86
87#define LEAF_ALL_IN(leaf) \
88 (leaf == 65535) // return true if all numbers in leaf are IN (selected)
89#define LEAF_ALL_OUT(leaf) \
90 (leaf == 0) // return true if all numbers in leaf are OUT
91
92#define ALL_OUT(n) memset(n, 0, NODE_SIZE) // turn out a node
93#define ALL_IN(n) memset(n, 32767, NODE_SIZE) // turn in a leaf
94#define INODE_CAPACITY \
95 (LEAF_SIZE * BRANCH_FACTOR) // minimum range that a inode stores
96
97// returns the maximum number that a quadrant stores
98#define QUADRANT_MAX_VALUE(node_num, quadrant, quadrant_interval, max) \
99 (MIN(node_num + quadrant_interval * quadrant - 1, max))
100
101// returns the interval size for the next level in the tree
102#define NEXT_INTERVAL(interval) \
103 ((interval <= LEAF_SIZE * BRANCH_FACTOR) \
104 ? LEAF_SIZE \
105 : interval / BRANCH_FACTOR + interval % BRANCH_FACTOR)
106
107#define IS_LEAF(interval) \
108 ((interval <= LEAF_SIZE) ? 1 : 0) // check if a interval of type Leaf
109#define LAST_LEVEL_INODE(interval) \
110 ((interval <= LEAF_SIZE * BRANCH_FACTOR && interval > LEAF_SIZE) ? 1 : 0)
111
112#define REALLOC_MEM(tree) (tree->mem_alloc < (tree->size + 1) * NODE_SIZE)
113#define MEM_SIZE(tree) (tree->size + 2) * NODE_SIZE
114
115#define TREE_SIZE(tree) tree->mem_alloc + sizeof(RL_Tree)
116
117typedef union {
118 struct s_node i_node;
119 unsigned short int leaf;
120} RL_Node; /* A node is a internal node (inode) or a leaf depending on their
121 depth in the tree */
122
123/*
124 Range_List
125 Contains the root node, max range size,
126*/
127struct rl_struct {
128 RL_Node *root;
129 NUM size; // number of nodes
130 NUM mem_alloc; // memory allocated for *root
131 NUM range_max; // maximum value of the interval
132 NUM root_i; // root interval
133};
134typedef struct rl_struct RL_Tree;
135
136/* Buffer */
137struct s_buffer {
138 RL_Node *root_node;
139 unsigned long size; // memory (in bytes) allocated for root_node
140};
141typedef struct s_buffer RL_Buffer;
142
143//----------------------------------------------------------------
144// Bits operations
145#define BITMAP_empty(b) ((b) == 0)
146#define BITMAP_member(b, n) (((b) & (1 << (n))) != 0)
147#define BITMAP_alone(b, n) ((b) == (1 << (n)))
148#define BITMAP_subset(b1, b2) (((b1) & (b2)) == b2)
149#define BITMAP_same(b1, b2) ((b1) == (b2))
150
151#define BITMAP_on_all(b) ((b) = 255)
152
153#define BITMAP_clear(b) ((b) = 0)
154#define BITMAP_and(b1, b2) ((b1) &= (b2))
155#define BITMAP_minus(b1, b2) ((b1) &= ~(b2))
156#define BITMAP_insert(b, n) ((b) |= (1 << (n)))
157#define BITMAP_delete(b, n) ((b) &= (~(1 << (n))))
158#define BITMAP_copy(b1, b2) ((b1) = (b2))
159#define BITMAP_intersection(b1, b2, b3) ((b1) = ((b2) & (b3)))
160#define BITMAP_difference(b1, b2, b3) ((b1) = ((b2) & (~(b3))))
161
162#
163//----------------------------------------------------------------
164typedef enum { TRUE = 1, FALSE = 0 } BOOLEAN;
165typedef enum { IN = 1, OUT = 0 } STATUS;
166
167//
168#define BUFFER_SIZE 1000
169/* **********************************************************************************
170 */
171/* API */
172extern RL_Tree *new_rl(NUM max_size);
173extern RL_Tree *copy_rl(RL_Tree *tree);
174extern void free_rl(RL_Tree *range);
175
176extern void rl_all(RL_Tree *tree, STATUS status);
177extern void display_tree(RL_Tree *tree);
178extern RL_Tree *set_in_rl(RL_Tree *tree, NUM number, STATUS status);
179extern BOOLEAN in_rl(RL_Tree *range, NUM number);
180extern BOOLEAN
181freeze_rl(RL_Tree *tree); /* write operations on the range are finishe */
182extern RL_Tree *intersect_rl(RL_Tree *range1, RL_Tree *range2);
183
184extern NUM
185rl_next_in_bigger(RL_Tree *tree,
186 NUM min); /* Returns next number in tree bigger than min */
187
188#define IS_FREEZED(tree) (tree->mem_alloc != 0)