1 /* tag: Tom Lord Tue Dec 4 14:41:34 2001 (bits.c)
2 */
3 /* bits.c -
4 *
5 ****************************************************************
6 * Copyright (C) 2000 Tom Lord
7 *
8 * See the file "COPYING" for further information about
9 * the copyright and warranty status of this work.
10 */
11
12
13 #include "hackerlab/bitsets/bits.h"
14
15
16 /************************************************************************
17 *(h1 "Shared Bitset Trees"
18 * :includes ("hackerlab/bitsets/bits.h"))
19 *
20 * "Shared bitset trees" are ordinary bitset trees with two differences:
21 *
22 * \1./ The allocation limits that apply to a shared bitset tree are
23 * recorded when the tree is created and do not need to be passed as
24 * parameters to every bitset operation. (For more information about
25 * allocation limits, see xref:"Allocation With Limitations".
26 *
27 * \2./ When a shared bitset tree is copied, very little data is actually
28 * duplicated: the old and the new bitset tree initially share state.
29 * Instead, copying takes place when (and if) either bitset is later
30 * modified.
31 *
32 * Before reading this section, it is a good idea to first understand
33 * the material in xref:"Bitset Trees".
34 */
35
36
37
38
39 /************************************************************************
40 *(h2 "Allocating Shared Bitset Trees")
41 *
42 *
43 *
44 */
45
46 /*(c bits_alloc)
47 * bits bits_alloc (alloc_limits lim, struct bits_tree_rule * rule);
48 *
49 * Create a new shared bitset tree, subject to allocation limits `lim',
50 * using branching structure `rule'.
51 *
52 * For more information about allocation limits, see xref:"Allocation
53 * With Limitations".
54 *
55 * For more information about branching structure rules, see
56 * xref:"Bitset Tree Rules".
57 */
58 bits
bits_alloc(alloc_limits lim,struct bits_tree_rule * rule)59 bits_alloc (alloc_limits lim, struct bits_tree_rule * rule)
60 {
61 bits b;
62
63 b = (bits)lim_malloc (lim, sizeof (struct bits));
64 if (!b)
65 return 0;
66 b->lim = lim;
67 b->rule = rule;
68 b->stree = (struct bits_tree_shared *)lim_malloc (lim, sizeof (struct bits_tree_shared));
69 b->stree->refs = 1;
70 b->stree->tree = bits_tree_alloc (lim, rule);
71 return b;
72 }
73
74
75 /*(c bits_free)
76 * void bits_free (bits b);
77 *
78 * Free a previously allocated shared bitset tree.
79 */
80 void
bits_free(bits b)81 bits_free (bits b)
82 {
83 if (!b)
84 return;
85 --b->stree->refs;
86 if (!b->stree->refs)
87 {
88 bits_tree_free (b->lim, b->rule, b->stree->tree);
89 lim_free (b->lim, (void *)b->stree);
90 }
91 lim_free (b->lim, b);
92 }
93
94
95 /*(c bits_dup)
96 * bits bits_dup (bits a);
97 *
98 * Copy a shared bitset tree.
99 *
100 * This operation is inexpensive -- most data is shared between the
101 * two trees until one of the two is modified.
102 *
103 * If set `a' was created with no allocation limits, and allocation
104 * fails, this function does not return.
105 *
106 * If set `a' was created with allocation limits, and allocation
107 * fails, this function returns 0.
108 */
109 bits
bits_dup(bits a)110 bits_dup (bits a)
111 {
112 bits b;
113
114 b = (bits)lim_malloc (a->lim, sizeof (struct bits));
115 if (!b)
116 return 0;
117 b->lim = a->lim;
118 b->rule = a->rule;
119 b->stree = a->stree;
120 ++b->stree->refs;
121 return b;
122 }
123
124 static int
bits_cow(bits a)125 bits_cow (bits a)
126 {
127 if (a->stree->refs == 1)
128 return 0;
129 else
130 {
131 struct bits_tree_shared * s;
132 s = (struct bits_tree_shared *)lim_malloc (a->lim, sizeof (struct bits_tree_shared));
133 if (!s)
134 return -1;
135 s->refs = 1;
136 s->tree = bits_tree_dup (a->lim, a->rule, a->stree->tree);
137 if (!s->tree)
138 {
139 lim_free (a->lim, (void *)s);
140 return -1;
141 }
142 --a->stree->refs;
143 a->stree = s;
144 return 0;
145 }
146 }
147
148 /*(c bits_compact)
149 * void bits_compact (bits a);
150 *
151 * Optimize a shared bitset tree by compacting homogenous
152 * sub-trees. See xref:"The Bitset Tree Data Structure".
153 *
154 */
155 void
bits_compact(bits a)156 bits_compact (bits a)
157 {
158 bits_tree_compact (a->lim, a->rule, a->stree->tree);
159 }
160
161
162
163 /************************************************************************
164 *h2 "Accessing Individual Subsets of a Shared Bitset Tree")
165 *
166 *
167 *
168 */
169
170
171 /*c bits_get_subset)
172 * int bits_get_subset (bitset_subset * answer, bits b, int n);
173 *
174 * Return (in `*answer') the `bitset_subet' containing bit `n' of
175 * shared bitset tree `b'. See xref:"bitset_subset".
176 *
177 * If the indicated subset does not exist (because it is part of
178 * a homogenous subtree whose representation has been optimized)
179 * the corresponding subtree is newly allocated.
180 *
181 * If allocation fails, and `b' was created with allocation limits,
182 * return -1.
183 *
184 * If allocation fails, and `b' was created without allocation limits,
185 * this function does not return.
186 *
187 * Otherwise, 0 is returned.
188 *
189 */
190 int
bits_get_subset(bitset_subset * answer,bits b,int n)191 bits_get_subset (bitset_subset * answer, bits b, int n)
192 {
193 return bits_tree_get_subset (answer, b->lim, b->rule, b->stree->tree, n);
194 }
195
196
197
198 /************************************************************************
199 *(h2 "Operations on Shared Bitset Trees")
200 *
201 *
202 * Each of the operations defined for flat bitsets has a corresponding
203 * operation for shared bitset trees. See xref:"Flat Bitsets".
204 *
205 * The shared bitset tree operations are:
206 *
207 *
208 * |$bits_is_member| |$bits_is_equal| |$bits_is_subset| |$bits_is_empty| |$bits_is_full|
209 * |$bits_is_empty_range| |$bits_is_full_range| |$bits_adjoin| |$bits_remove|
210 * |$bits_toggle| |$bits_clear| |$bits_fill| |$bits_clear_range| |$bits_fill_range|
211 * |$bits_complement| |$bits_assign| |$bits_union| |$bits_intersection|
212 * |$bits_difference| |$bits_revdifference| |$bits_xor| |$bits_population|
213 * |$bits_population_range| |$bits_ffs| |$bits_ffc| |$bits_ffs_range| |$bits_ffc_range|
214 *
215 * int bits_is_member (bits b, int n);
216 * int bits_is_equal (bits a, bits b);
217 * int bits_is_subset (bits a, bits b);
218 * int bits_is_empty (bits a);
219 * int bits_is_full (bits a);
220 * int bits_is_empty_range (bits a, int from, int to);
221 * int bits_is_full_range (bits a, int from, int to);
222 * int bits_adjoin (bits b, int n);
223 * int bits_remove (bits b, int n);
224 * int bits_toggle (bits b, int n);
225 * int bits_clear (bits b);
226 * int bits_fill (bits b);
227 * int bits_clear_range (bits b, int from, int to);
228 * int bits_fill_range (bits b, int from, int to);
229 * int bits_complement (bits b);
230 * int bits_assign (bits a, bits b);
231 * int bits_union (bits a, bits b);
232 * int bits_intersection (bits a, bits b);
233 * int bits_difference (bits a, bits b);
234 * int bits_revdifference (bits a, bits b);
235 * int bits_xor (bits a, bits b);
236 * int bits_population (bits a);
237 * int bits_population_range (bits a, int from, int to);
238 * int bits_ffs (bits b);
239 * int bits_ffc (bits b);
240 * int bits_ffs_range (bits b, int from, int to);
241 * int bits_ffc_range (bits b, int from, int to);
242 *
243 * Each function performs the same operation as the corresponding
244 * `bitset_' function (replace `bits_' with `bitset_'.)
245 * For documentation, see xref:"Flat Bitsets". For that reason,
246 * the `bits_' functions are not individually documented.
247 *
248 * These functions:
249 *
250 * bits_adjoin
251 * bits_remove
252 * bits_toggle
253 * bits_clear
254 * bits_fill
255 * bits_clear_range
256 * bits_fill_range
257 * bits_complement
258 * bits_assign
259 * bits_union
260 * bits_intersection
261 * bits_difference
262 * bits_revdifference
263 * bits_xor
264 *
265 * return a value of type `int'. All of them will sometimes allocate
266 * memory.
267 *
268 * If no allocation limit is being used, and an allocation fails,
269 * these functions do not return.
270 *
271 * If an allocation limit is being used, and an allocation fails,
272 * these functions return -1 and have indeterminate side effect on the
273 * set being operated upon.
274 *
275 * If allocation succeeds, they return 0 (and have the intended side
276 * effect on the set being operated upon).
277 *
278 */
279
280 int
bits_is_member(bits b,int n)281 bits_is_member (bits b, int n)
282 {
283 return bits_tree_is_member (b->lim, b->rule, b->stree->tree, n);
284 }
285
286
287 int
bits_is_equal(bits a,bits b)288 bits_is_equal (bits a, bits b)
289 {
290 return bits_tree_is_equal (a->lim, a->rule, a->stree->tree, b->stree->tree);
291 }
292
293
294 int
bits_is_subset(bits a,bits b)295 bits_is_subset (bits a, bits b)
296 {
297 return bits_tree_is_subset (a->lim, a->rule, a->stree->tree, b->stree->tree);
298 }
299
300
301 int
bits_is_empty(bits a)302 bits_is_empty (bits a)
303 {
304 return bits_tree_is_empty (a->lim, a->rule, a->stree->tree);
305 }
306
307
308 int
bits_is_full(bits a)309 bits_is_full (bits a)
310 {
311 return bits_tree_is_full (a->lim, a->rule, a->stree->tree);
312 }
313
314
315 int
bits_is_empty_range(bits a,int from,int to)316 bits_is_empty_range (bits a, int from, int to)
317 {
318 return bits_tree_is_empty_range (a->lim, a->rule, a->stree->tree, from, to);
319 }
320
321
322 int
bits_is_full_range(bits a,int from,int to)323 bits_is_full_range (bits a, int from, int to)
324 {
325 return bits_tree_is_full_range (a->lim, a->rule, a->stree->tree, from, to);
326 }
327
328
329 int
bits_adjoin(bits b,int n)330 bits_adjoin (bits b, int n)
331 {
332 if (bits_cow (b))
333 return -1;
334 return bits_tree_adjoin (b->lim, b->rule, b->stree->tree, n);
335 }
336
337
338 int
bits_remove(bits b,int n)339 bits_remove (bits b, int n)
340 {
341 if (bits_cow (b))
342 return -1;
343 return bits_tree_remove (b->lim, b->rule, b->stree->tree, n);
344 }
345
346
347 int
bits_toggle(bits b,int n)348 bits_toggle (bits b, int n)
349 {
350 if (bits_cow (b))
351 return -1;
352 return bits_tree_toggle (b->lim, b->rule, b->stree->tree, n);
353 }
354
355
356 int
bits_clear(bits b)357 bits_clear (bits b)
358 {
359 if (bits_cow (b))
360 return -1;
361 bits_tree_clear (b->lim, b->rule, b->stree->tree);
362 return 0;
363 }
364
365
366 int
bits_fill(bits b)367 bits_fill (bits b)
368 {
369 if (bits_cow (b))
370 return -1;
371 bits_tree_fill (b->lim, b->rule, b->stree->tree);
372 return 0;
373 }
374
375
376 int
bits_clear_range(bits b,int from,int to)377 bits_clear_range (bits b, int from, int to)
378 {
379 if (bits_cow (b))
380 return -1;
381 return bits_tree_clear_range (b->lim, b->rule, b->stree->tree, from, to);
382 }
383
384
385 int
bits_fill_range(bits b,int from,int to)386 bits_fill_range (bits b, int from, int to)
387 {
388 if (bits_cow (b))
389 return -1;
390 return bits_tree_fill_range (b->lim, b->rule, b->stree->tree, from, to);
391 }
392
393
394 int
bits_complement(bits b)395 bits_complement (bits b)
396 {
397 if (bits_cow (b))
398 return -1;
399 bits_tree_complement (b->lim, b->rule, b->stree->tree);
400 return 0;
401 }
402
403
404 int
bits_assign(bits a,bits b)405 bits_assign (bits a, bits b)
406 {
407 if (bits_cow (b))
408 return -1;
409 return bits_tree_assign (a->lim, a->rule, a->stree->tree, b->stree->tree);
410 }
411
412
413 int
bits_union(bits a,bits b)414 bits_union (bits a, bits b)
415 {
416 if (bits_cow (b))
417 return -1;
418 return bits_tree_union (a->lim, a->rule, a->stree->tree, b->stree->tree);
419 }
420
421
422 int
bits_intersection(bits a,bits b)423 bits_intersection (bits a, bits b)
424 {
425 if (bits_cow (b))
426 return -1;
427 return bits_tree_intersection (a->lim, a->rule, a->stree->tree, b->stree->tree);
428 }
429
430
431 int
bits_difference(bits a,bits b)432 bits_difference (bits a, bits b)
433 {
434 if (bits_cow (b))
435 return -1;
436 return bits_tree_difference (a->lim, a->rule, a->stree->tree, b->stree->tree);
437 }
438
439
440 int
bits_revdifference(bits a,bits b)441 bits_revdifference (bits a, bits b)
442 {
443 if (bits_cow (b))
444 return -1;
445 return bits_tree_revdifference (a->lim, a->rule, a->stree->tree, b->stree->tree);
446 }
447
448
449 int
bits_xor(bits a,bits b)450 bits_xor (bits a, bits b)
451 {
452 if (bits_cow (b))
453 return -1;
454 return bits_tree_xor (a->lim, a->rule, a->stree->tree, b->stree->tree);
455 }
456
457
458 int
bits_population(bits a)459 bits_population (bits a)
460 {
461 return bits_tree_population (a->lim, a->rule, a->stree->tree);
462 }
463
464
465 int
bits_population_range(bits a,int from,int to)466 bits_population_range (bits a, int from, int to)
467 {
468 return bits_tree_population_range (a->lim, a->rule, a->stree->tree, from, to);
469 }
470
471
472 int
bits_ffs(bits b)473 bits_ffs (bits b)
474 {
475 return bits_tree_ffs (b->lim, b->rule, b->stree->tree);
476 }
477
478
479 int
bits_ffc(bits b)480 bits_ffc (bits b)
481 {
482 return bits_tree_ffc (b->lim, b->rule, b->stree->tree);
483 }
484
485
486 int
bits_ffs_range(bits b,int from,int to)487 bits_ffs_range (bits b, int from, int to)
488 {
489 return bits_tree_ffs_range (b->lim, b->rule, b->stree->tree, from, to);
490 }
491
492
493 int
bits_ffc_range(bits b,int from,int to)494 bits_ffc_range (bits b, int from, int to)
495 {
496 return bits_tree_ffc_range (b->lim, b->rule, b->stree->tree, from, to);
497 }
498
499
500