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