1 /* Bitset statistics.
2
3 Copyright (C) 2002-2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
4
5 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>. */
19
20 /* This file is a wrapper bitset implementation for the other bitset
21 implementations. It provides bitset compatibility checking and
22 statistics gathering without having to instrument the bitset
23 implementations. When statistics gathering is enabled, the bitset
24 operations get vectored through here and we then call the appropriate
25 routines. */
26
27 #include <config.h>
28
29 #include "bitset/stats.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "gettext.h"
36 #define _(Msgid) gettext (Msgid)
37
38 #include "bitset/array.h"
39 #include "bitset/base.h"
40 #include "bitset/list.h"
41 #include "bitset/table.h"
42 #include "bitset/vector.h"
43
44 /* Configuration macros. */
45 #define BITSET_STATS_FILE "bitset.dat"
46 #define BITSET_LOG_COUNT_BINS 10
47 #define BITSET_LOG_SIZE_BINS 16
48 #define BITSET_DENSITY_BINS 20
49
50
51 /* Accessor macros. */
52 #define BITSET_STATS_ALLOCS_INC(TYPE) \
53 bitset_stats_info->types[(TYPE)].allocs++
54 #define BITSET_STATS_FREES_INC(BSET) \
55 bitset_stats_info->types[BITSET_TYPE_ (BSET)].frees++
56 #define BITSET_STATS_SETS_INC(BSET) \
57 bitset_stats_info->types[BITSET_TYPE_ (BSET)].sets++
58 #define BITSET_STATS_CACHE_SETS_INC(BSET) \
59 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_sets++
60 #define BITSET_STATS_RESETS_INC(BSET) \
61 bitset_stats_info->types[BITSET_TYPE_ (BSET)].resets++
62 #define BITSET_STATS_CACHE_RESETS_INC(BSET) \
63 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_resets++
64 #define BITSET_STATS_TESTS_INC(BSET) \
65 bitset_stats_info->types[BITSET_TYPE_ (BSET)].tests++
66 #define BITSET_STATS_CACHE_TESTS_INC(BSET) \
67 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_tests++
68 #define BITSET_STATS_LISTS_INC(BSET) \
69 bitset_stats_info->types[BITSET_TYPE_ (BSET)].lists++
70 #define BITSET_STATS_LIST_COUNTS_INC(BSET, I) \
71 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_counts[(I)]++
72 #define BITSET_STATS_LIST_SIZES_INC(BSET, I) \
73 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_sizes[(I)]++
74 #define BITSET_STATS_LIST_DENSITY_INC(BSET, I) \
75 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_density[(I)]++
76
77
78 struct bitset_type_info_struct
79 {
80 unsigned allocs;
81 unsigned frees;
82 unsigned lists;
83 unsigned sets;
84 unsigned cache_sets;
85 unsigned resets;
86 unsigned cache_resets;
87 unsigned tests;
88 unsigned cache_tests;
89 unsigned list_counts[BITSET_LOG_COUNT_BINS];
90 unsigned list_sizes[BITSET_LOG_SIZE_BINS];
91 unsigned list_density[BITSET_DENSITY_BINS];
92 };
93
94 struct bitset_stats_info_struct
95 {
96 unsigned runs;
97 struct bitset_type_info_struct types[BITSET_TYPE_NUM];
98 };
99
100
101 struct bitset_stats_info_struct bitset_stats_info_data;
102 struct bitset_stats_info_struct *bitset_stats_info;
103 bool bitset_stats_enabled = false;
104
105
106 /* Print a percentage histogram with message MSG to FILE. */
107 static void
bitset_percent_histogram_print(FILE * file,const char * name,const char * msg,unsigned n_bins,unsigned * bins)108 bitset_percent_histogram_print (FILE *file, const char *name, const char *msg,
109 unsigned n_bins, unsigned *bins)
110 {
111 unsigned total = 0;
112 for (unsigned i = 0; i < n_bins; i++)
113 total += bins[i];
114
115 if (!total)
116 return;
117
118 fprintf (file, "%s %s", name, msg);
119 for (unsigned i = 0; i < n_bins; i++)
120 fprintf (file, "%.0f-%.0f%%\t%8u (%5.1f%%)\n",
121 i * 100.0 / n_bins,
122 (i + 1) * 100.0 / n_bins, bins[i],
123 (100.0 * bins[i]) / total);
124 }
125
126
127 /* Print a log histogram with message MSG to FILE. */
128 static void
bitset_log_histogram_print(FILE * file,const char * name,const char * msg,unsigned n_bins,unsigned * bins)129 bitset_log_histogram_print (FILE *file, const char *name, const char *msg,
130 unsigned n_bins, unsigned *bins)
131 {
132 unsigned total = 0;
133 for (unsigned i = 0; i < n_bins; i++)
134 total += bins[i];
135
136 if (!total)
137 return;
138
139 /* Determine number of useful bins. */
140 {
141 unsigned i;
142 for (i = n_bins; i > 3 && ! bins[i - 1]; i--)
143 continue;
144 n_bins = i;
145 }
146
147 /* 2 * ceil (log10 (2) * (N - 1)) + 1. */
148 unsigned max_width = 2 * (unsigned) (0.30103 * (n_bins - 1) + 0.9999) + 1;
149
150 fprintf (file, "%s %s", name, msg);
151 {
152 unsigned i;
153 for (i = 0; i < 2; i++)
154 fprintf (file, "%*d\t%8u (%5.1f%%)\n",
155 max_width, i, bins[i], 100.0 * bins[i] / total);
156
157 for (; i < n_bins; i++)
158 fprintf (file, "%*lu-%lu\t%8u (%5.1f%%)\n",
159 max_width - ((unsigned) (0.30103 * (i) + 0.9999) + 1),
160 1UL << (i - 1),
161 (1UL << i) - 1,
162 bins[i],
163 (100.0 * bins[i]) / total);
164 }
165 }
166
167
168 /* Print bitset statistics to FILE. */
169 static void
bitset_stats_print_1(FILE * file,const char * name,struct bitset_type_info_struct * stats)170 bitset_stats_print_1 (FILE *file, const char *name,
171 struct bitset_type_info_struct *stats)
172 {
173 if (!stats)
174 return;
175
176 fprintf (file, "%s:\n", name);
177 fprintf (file, _("%u bitset_allocs, %u freed (%.2f%%).\n"),
178 stats->allocs, stats->frees,
179 stats->allocs ? 100.0 * stats->frees / stats->allocs : 0);
180 fprintf (file, _("%u bitset_sets, %u cached (%.2f%%)\n"),
181 stats->sets, stats->cache_sets,
182 stats->sets ? 100.0 * stats->cache_sets / stats->sets : 0);
183 fprintf (file, _("%u bitset_resets, %u cached (%.2f%%)\n"),
184 stats->resets, stats->cache_resets,
185 stats->resets ? 100.0 * stats->cache_resets / stats->resets : 0);
186 fprintf (file, _("%u bitset_tests, %u cached (%.2f%%)\n"),
187 stats->tests, stats->cache_tests,
188 stats->tests ? 100.0 * stats->cache_tests / stats->tests : 0);
189
190 fprintf (file, _("%u bitset_lists\n"), stats->lists);
191
192 bitset_log_histogram_print (file, name, _("count log histogram\n"),
193 BITSET_LOG_COUNT_BINS, stats->list_counts);
194
195 bitset_log_histogram_print (file, name, _("size log histogram\n"),
196 BITSET_LOG_SIZE_BINS, stats->list_sizes);
197
198 bitset_percent_histogram_print (file, name, _("density histogram\n"),
199 BITSET_DENSITY_BINS, stats->list_density);
200 }
201
202
203 /* Print all bitset statistics to FILE. */
204 static void
bitset_stats_print(FILE * file,bool verbose MAYBE_UNUSED)205 bitset_stats_print (FILE *file, bool verbose MAYBE_UNUSED)
206 {
207 if (!bitset_stats_info)
208 return;
209
210 fprintf (file, _("Bitset statistics:\n\n"));
211
212 if (bitset_stats_info->runs > 1)
213 fprintf (file, _("Accumulated runs = %u\n"), bitset_stats_info->runs);
214
215 for (int i = 0; i < BITSET_TYPE_NUM; i++)
216 bitset_stats_print_1 (file, bitset_type_names[i],
217 &bitset_stats_info->types[i]);
218 }
219
220
221 /* Initialise bitset statistics logging. */
222 void
bitset_stats_enable(void)223 bitset_stats_enable (void)
224 {
225 if (!bitset_stats_info)
226 bitset_stats_info = &bitset_stats_info_data;
227 bitset_stats_enabled = true;
228 }
229
230
231 void
bitset_stats_disable(void)232 bitset_stats_disable (void)
233 {
234 bitset_stats_enabled = false;
235 }
236
237
238 /* Read bitset statistics file. */
239 void
bitset_stats_read(const char * file_name)240 bitset_stats_read (const char *file_name)
241 {
242 if (!bitset_stats_info)
243 return;
244
245 if (!file_name)
246 file_name = BITSET_STATS_FILE;
247
248 FILE *file = fopen (file_name, "re");
249 if (file)
250 {
251 if (fread (&bitset_stats_info_data, sizeof (bitset_stats_info_data),
252 1, file) != 1)
253 {
254 if (ferror (file))
255 perror (_("cannot read stats file"));
256 else
257 fprintf (stderr, _("bad stats file size\n"));
258 }
259 if (fclose (file) != 0)
260 perror (_("cannot read stats file"));
261 }
262 bitset_stats_info_data.runs++;
263 }
264
265
266 /* Write bitset statistics file. */
267 void
bitset_stats_write(const char * file_name)268 bitset_stats_write (const char *file_name)
269 {
270 if (!bitset_stats_info)
271 return;
272
273 if (!file_name)
274 file_name = BITSET_STATS_FILE;
275
276 FILE *file = fopen (file_name, "we");
277 if (file)
278 {
279 if (fwrite (&bitset_stats_info_data, sizeof (bitset_stats_info_data),
280 1, file) != 1)
281 perror (_("cannot write stats file"));
282 if (fclose (file) != 0)
283 perror (_("cannot write stats file"));
284 }
285 else
286 perror (_("cannot open stats file for writing"));
287 }
288
289
290 /* Dump bitset statistics to FILE. */
291 void
bitset_stats_dump(FILE * file)292 bitset_stats_dump (FILE *file)
293 {
294 bitset_stats_print (file, false);
295 }
296
297
298 /* Function to be called from debugger to print bitset stats. */
299 void
debug_bitset_stats(void)300 debug_bitset_stats (void)
301 {
302 bitset_stats_print (stderr, true);
303 }
304
305
306 static void
bitset_stats_set(bitset dst,bitset_bindex bitno)307 bitset_stats_set (bitset dst, bitset_bindex bitno)
308 {
309 bitset bset = dst->s.bset;
310 bitset_windex wordno = bitno / BITSET_WORD_BITS;
311 bitset_windex offset = wordno - bset->b.cindex;
312
313 BITSET_STATS_SETS_INC (bset);
314
315 if (offset < bset->b.csize)
316 {
317 bset->b.cdata[offset] |= (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
318 BITSET_STATS_CACHE_SETS_INC (bset);
319 }
320 else
321 BITSET_SET_ (bset, bitno);
322 }
323
324
325 static void
bitset_stats_reset(bitset dst,bitset_bindex bitno)326 bitset_stats_reset (bitset dst, bitset_bindex bitno)
327 {
328 bitset bset = dst->s.bset;
329 bitset_windex wordno = bitno / BITSET_WORD_BITS;
330 bitset_windex offset = wordno - bset->b.cindex;
331
332 BITSET_STATS_RESETS_INC (bset);
333
334 if (offset < bset->b.csize)
335 {
336 bset->b.cdata[offset] &=
337 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
338 BITSET_STATS_CACHE_RESETS_INC (bset);
339 }
340 else
341 BITSET_RESET_ (bset, bitno);
342 }
343
344
345 static bool
bitset_stats_toggle(bitset src,bitset_bindex bitno)346 bitset_stats_toggle (bitset src, bitset_bindex bitno)
347 {
348 return BITSET_TOGGLE_ (src->s.bset, bitno);
349 }
350
351
352 static bool
bitset_stats_test(bitset src,bitset_bindex bitno)353 bitset_stats_test (bitset src, bitset_bindex bitno)
354 {
355 bitset bset = src->s.bset;
356 bitset_windex wordno = bitno / BITSET_WORD_BITS;
357 bitset_windex offset = wordno - bset->b.cindex;
358
359 BITSET_STATS_TESTS_INC (bset);
360
361 if (offset < bset->b.csize)
362 {
363 BITSET_STATS_CACHE_TESTS_INC (bset);
364 return (bset->b.cdata[offset] >> (bitno % BITSET_WORD_BITS)) & 1;
365 }
366 else
367 return BITSET_TEST_ (bset, bitno);
368 }
369
370
371 static bitset_bindex
bitset_stats_resize(bitset src,bitset_bindex size)372 bitset_stats_resize (bitset src, bitset_bindex size)
373 {
374 return BITSET_RESIZE_ (src->s.bset, size);
375 }
376
377
378 static bitset_bindex
bitset_stats_size(bitset src)379 bitset_stats_size (bitset src)
380 {
381 return BITSET_SIZE_ (src->s.bset);
382 }
383
384
385 static bitset_bindex
bitset_stats_count(bitset src)386 bitset_stats_count (bitset src)
387 {
388 return BITSET_COUNT_ (src->s.bset);
389 }
390
391
392 static bool
bitset_stats_empty_p(bitset dst)393 bitset_stats_empty_p (bitset dst)
394 {
395 return BITSET_EMPTY_P_ (dst->s.bset);
396 }
397
398
399 static void
bitset_stats_ones(bitset dst)400 bitset_stats_ones (bitset dst)
401 {
402 BITSET_ONES_ (dst->s.bset);
403 }
404
405
406 static void
bitset_stats_zero(bitset dst)407 bitset_stats_zero (bitset dst)
408 {
409 BITSET_ZERO_ (dst->s.bset);
410 }
411
412
413 static void
bitset_stats_copy(bitset dst,bitset src)414 bitset_stats_copy (bitset dst, bitset src)
415 {
416 BITSET_CHECK2_ (dst, src);
417 BITSET_COPY_ (dst->s.bset, src->s.bset);
418 }
419
420
421 static bool
bitset_stats_disjoint_p(bitset dst,bitset src)422 bitset_stats_disjoint_p (bitset dst, bitset src)
423 {
424 BITSET_CHECK2_ (dst, src);
425 return BITSET_DISJOINT_P_ (dst->s.bset, src->s.bset);
426 }
427
428
429 static bool
bitset_stats_equal_p(bitset dst,bitset src)430 bitset_stats_equal_p (bitset dst, bitset src)
431 {
432 BITSET_CHECK2_ (dst, src);
433 return BITSET_EQUAL_P_ (dst->s.bset, src->s.bset);
434 }
435
436
437 static void
bitset_stats_not(bitset dst,bitset src)438 bitset_stats_not (bitset dst, bitset src)
439 {
440 BITSET_CHECK2_ (dst, src);
441 BITSET_NOT_ (dst->s.bset, src->s.bset);
442 }
443
444
445 static bool
bitset_stats_subset_p(bitset dst,bitset src)446 bitset_stats_subset_p (bitset dst, bitset src)
447 {
448 BITSET_CHECK2_ (dst, src);
449 return BITSET_SUBSET_P_ (dst->s.bset, src->s.bset);
450 }
451
452
453 static void
bitset_stats_and(bitset dst,bitset src1,bitset src2)454 bitset_stats_and (bitset dst, bitset src1, bitset src2)
455 {
456 BITSET_CHECK3_ (dst, src1, src2);
457 BITSET_AND_ (dst->s.bset, src1->s.bset, src2->s.bset);
458 }
459
460
461 static bool
bitset_stats_and_cmp(bitset dst,bitset src1,bitset src2)462 bitset_stats_and_cmp (bitset dst, bitset src1, bitset src2)
463 {
464 BITSET_CHECK3_ (dst, src1, src2);
465 return BITSET_AND_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset);
466 }
467
468
469 static void
bitset_stats_andn(bitset dst,bitset src1,bitset src2)470 bitset_stats_andn (bitset dst, bitset src1, bitset src2)
471 {
472 BITSET_CHECK3_ (dst, src1, src2);
473 BITSET_ANDN_ (dst->s.bset, src1->s.bset, src2->s.bset);
474 }
475
476
477 static bool
bitset_stats_andn_cmp(bitset dst,bitset src1,bitset src2)478 bitset_stats_andn_cmp (bitset dst, bitset src1, bitset src2)
479 {
480 BITSET_CHECK3_ (dst, src1, src2);
481 return BITSET_ANDN_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset);
482 }
483
484
485 static void
bitset_stats_or(bitset dst,bitset src1,bitset src2)486 bitset_stats_or (bitset dst, bitset src1, bitset src2)
487 {
488 BITSET_CHECK3_ (dst, src1, src2);
489 BITSET_OR_ (dst->s.bset, src1->s.bset, src2->s.bset);
490 }
491
492
493 static bool
bitset_stats_or_cmp(bitset dst,bitset src1,bitset src2)494 bitset_stats_or_cmp (bitset dst, bitset src1, bitset src2)
495 {
496 BITSET_CHECK3_ (dst, src1, src2);
497 return BITSET_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset);
498 }
499
500
501 static void
bitset_stats_xor(bitset dst,bitset src1,bitset src2)502 bitset_stats_xor (bitset dst, bitset src1, bitset src2)
503 {
504 BITSET_CHECK3_ (dst, src1, src2);
505 BITSET_XOR_ (dst->s.bset, src1->s.bset, src2->s.bset);
506 }
507
508
509 static bool
bitset_stats_xor_cmp(bitset dst,bitset src1,bitset src2)510 bitset_stats_xor_cmp (bitset dst, bitset src1, bitset src2)
511 {
512 BITSET_CHECK3_ (dst, src1, src2);
513 return BITSET_XOR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset);
514 }
515
516
517 static void
bitset_stats_and_or(bitset dst,bitset src1,bitset src2,bitset src3)518 bitset_stats_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
519 {
520 BITSET_CHECK4_ (dst, src1, src2, src3);
521 BITSET_AND_OR_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
522 }
523
524
525 static bool
bitset_stats_and_or_cmp(bitset dst,bitset src1,bitset src2,bitset src3)526 bitset_stats_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
527 {
528 BITSET_CHECK4_ (dst, src1, src2, src3);
529 return BITSET_AND_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
530 }
531
532
533 static void
bitset_stats_andn_or(bitset dst,bitset src1,bitset src2,bitset src3)534 bitset_stats_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
535 {
536 BITSET_CHECK4_ (dst, src1, src2, src3);
537 BITSET_ANDN_OR_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
538 }
539
540
541 static bool
bitset_stats_andn_or_cmp(bitset dst,bitset src1,bitset src2,bitset src3)542 bitset_stats_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
543 {
544 BITSET_CHECK4_ (dst, src1, src2, src3);
545 return BITSET_ANDN_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
546 }
547
548
549 static void
bitset_stats_or_and(bitset dst,bitset src1,bitset src2,bitset src3)550 bitset_stats_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
551 {
552 BITSET_CHECK4_ (dst, src1, src2, src3);
553 BITSET_OR_AND_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
554 }
555
556
557 static bool
bitset_stats_or_and_cmp(bitset dst,bitset src1,bitset src2,bitset src3)558 bitset_stats_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
559 {
560 BITSET_CHECK4_ (dst, src1, src2, src3);
561 return BITSET_OR_AND_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
562 }
563
564
565 static bitset_bindex
bitset_stats_list(bitset bset,bitset_bindex * list,bitset_bindex num,bitset_bindex * next)566 bitset_stats_list (bitset bset, bitset_bindex *list,
567 bitset_bindex num, bitset_bindex *next)
568 {
569 bitset_bindex count = BITSET_LIST_ (bset->s.bset, list, num, next);
570
571 BITSET_STATS_LISTS_INC (bset->s.bset);
572
573 /* Log histogram of number of set bits. */
574 {
575 bitset_bindex i;
576 bitset_bindex tmp;
577 for (i = 0, tmp = count; tmp; tmp >>= 1, i++)
578 continue;
579 if (i >= BITSET_LOG_COUNT_BINS)
580 i = BITSET_LOG_COUNT_BINS - 1;
581 BITSET_STATS_LIST_COUNTS_INC (bset->s.bset, i);
582 }
583
584 /* Log histogram of number of bits in set. */
585 bitset_bindex size = BITSET_SIZE_ (bset->s.bset);
586 {
587 bitset_bindex i;
588 bitset_bindex tmp;
589 for (i = 0, tmp = size; tmp; tmp >>= 1, i++)
590 continue;
591 if (i >= BITSET_LOG_SIZE_BINS)
592 i = BITSET_LOG_SIZE_BINS - 1;
593 BITSET_STATS_LIST_SIZES_INC (bset->s.bset, i);
594 }
595
596 /* Histogram of fraction of bits set. */
597 {
598 bitset_bindex i = size ? (count * BITSET_DENSITY_BINS) / size : 0;
599 if (i >= BITSET_DENSITY_BINS)
600 i = BITSET_DENSITY_BINS - 1;
601 BITSET_STATS_LIST_DENSITY_INC (bset->s.bset, i);
602 }
603 return count;
604 }
605
606
607 static bitset_bindex
bitset_stats_list_reverse(bitset bset,bitset_bindex * list,bitset_bindex num,bitset_bindex * next)608 bitset_stats_list_reverse (bitset bset, bitset_bindex *list,
609 bitset_bindex num, bitset_bindex *next)
610 {
611 return BITSET_LIST_REVERSE_ (bset->s.bset, list, num, next);
612 }
613
614
615 static void
bitset_stats_free(bitset bset)616 bitset_stats_free (bitset bset)
617 {
618 BITSET_STATS_FREES_INC (bset->s.bset);
619 BITSET_FREE_ (bset->s.bset);
620 }
621
622
623 struct bitset_vtable bitset_stats_vtable = {
624 bitset_stats_set,
625 bitset_stats_reset,
626 bitset_stats_toggle,
627 bitset_stats_test,
628 bitset_stats_resize,
629 bitset_stats_size,
630 bitset_stats_count,
631 bitset_stats_empty_p,
632 bitset_stats_ones,
633 bitset_stats_zero,
634 bitset_stats_copy,
635 bitset_stats_disjoint_p,
636 bitset_stats_equal_p,
637 bitset_stats_not,
638 bitset_stats_subset_p,
639 bitset_stats_and,
640 bitset_stats_and_cmp,
641 bitset_stats_andn,
642 bitset_stats_andn_cmp,
643 bitset_stats_or,
644 bitset_stats_or_cmp,
645 bitset_stats_xor,
646 bitset_stats_xor_cmp,
647 bitset_stats_and_or,
648 bitset_stats_and_or_cmp,
649 bitset_stats_andn_or,
650 bitset_stats_andn_or_cmp,
651 bitset_stats_or_and,
652 bitset_stats_or_and_cmp,
653 bitset_stats_list,
654 bitset_stats_list_reverse,
655 bitset_stats_free,
656 BITSET_STATS
657 };
658
659
660 /* Return enclosed bitset type. */
661 enum bitset_type
bitset_stats_type_get(bitset bset)662 bitset_stats_type_get (bitset bset)
663 {
664 return BITSET_TYPE_ (bset->s.bset);
665 }
666
667
668 size_t
bitset_stats_bytes(void)669 bitset_stats_bytes (void)
670 {
671 return sizeof (struct bitset_stats_struct);
672 }
673
674
675 bitset
bitset_stats_init(bitset bset,bitset_bindex n_bits,enum bitset_type type)676 bitset_stats_init (bitset bset, bitset_bindex n_bits, enum bitset_type type)
677 {
678 bset->b.vtable = &bitset_stats_vtable;
679
680 /* Disable cache. */
681 bset->b.cindex = 0;
682 bset->b.csize = 0;
683 bset->b.cdata = 0;
684
685 BITSET_NBITS_ (bset) = n_bits;
686
687 /* Set up the actual bitset implementation that
688 we are a wrapper over. */
689 switch (type)
690 {
691 default:
692 abort ();
693
694 case BITSET_ARRAY:
695 {
696 size_t bytes = abitset_bytes (n_bits);
697 bset->s.bset = xzalloc (bytes);
698 abitset_init (bset->s.bset, n_bits);
699 }
700 break;
701
702 case BITSET_LIST:
703 {
704 size_t bytes = lbitset_bytes (n_bits);
705 bset->s.bset = xzalloc (bytes);
706 lbitset_init (bset->s.bset, n_bits);
707 }
708 break;
709
710 case BITSET_TABLE:
711 {
712 size_t bytes = tbitset_bytes (n_bits);
713 bset->s.bset = xzalloc (bytes);
714 tbitset_init (bset->s.bset, n_bits);
715 }
716 break;
717
718 case BITSET_VECTOR:
719 {
720 size_t bytes = vbitset_bytes (n_bits);
721 bset->s.bset = xzalloc (bytes);
722 vbitset_init (bset->s.bset, n_bits);
723 }
724 break;
725 }
726
727 BITSET_STATS_ALLOCS_INC (type);
728
729 return bset;
730 }
731