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