• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Bitset statistics.
2    Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3    Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software Foundation,
17    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
18 
19 /* This file is a wrapper bitset implementation for the other bitset
20    implementations.  It provides bitset compatibility checking and
21    statistics gathering without having to instrument the bitset
22    implementations.  When statistics gathering is enabled, the bitset
23    operations get vectored through here and we then call the appropriate
24    routines.  */
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #include "bbitset.h"
31 #include "abitset.h"
32 #include "ebitset.h"
33 #include "lbitset.h"
34 #include "vbitset.h"
35 #include "bitset_stats.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 (_("Could not read stats file."));
260 	  else
261 	    fprintf (stderr, _("Bad stats file size.\n"));
262 	}
263       if (fclose (file) != 0)
264 	perror (_("Could not 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 (_("Could not write stats file."));
288       if (fclose (file) != 0)
289 	perror (_("Could not write stats file."));
290     }
291   else
292     perror (_("Could not 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   enum bitset_type type;
580 
581   count = BITSET_LIST_ (bset->s.bset, list, num, next);
582 
583   type = BITSET_TYPE_ (bset->s.bset);
584   BITSET_STATS_LISTS_INC (bset->s.bset);
585 
586   /* Log histogram of number of set bits.  */
587   for (i = 0, tmp = count; tmp; tmp >>= 1, i++)
588      continue;
589   if (i >= BITSET_LOG_COUNT_BINS)
590      i = BITSET_LOG_COUNT_BINS - 1;
591   BITSET_STATS_LIST_COUNTS_INC (bset->s.bset, i);
592 
593   /* Log histogram of number of bits in set.  */
594   size = BITSET_SIZE_ (bset->s.bset);
595   for (i = 0, tmp = size; tmp; tmp >>= 1, i++)
596      continue;
597   if (i >= BITSET_LOG_SIZE_BINS)
598      i = BITSET_LOG_SIZE_BINS - 1;
599   BITSET_STATS_LIST_SIZES_INC (bset->s.bset, i);
600 
601   /* Histogram of fraction of bits set.  */
602   i = size ? (count * BITSET_DENSITY_BINS) / size : 0;
603   if (i >= BITSET_DENSITY_BINS)
604      i = BITSET_DENSITY_BINS - 1;
605   BITSET_STATS_LIST_DENSITY_INC (bset->s.bset, i);
606   return count;
607 }
608 
609 
610 static bitset_bindex
bitset_stats_list_reverse(bitset bset,bitset_bindex * list,bitset_bindex num,bitset_bindex * next)611 bitset_stats_list_reverse (bitset bset, bitset_bindex *list,
612 			   bitset_bindex num, bitset_bindex *next)
613 {
614   return BITSET_LIST_REVERSE_ (bset->s.bset, list, num, next);
615 }
616 
617 
618 static void
bitset_stats_free(bitset bset)619 bitset_stats_free (bitset bset)
620 {
621   BITSET_STATS_FREES_INC (bset->s.bset);
622   BITSET_FREE_ (bset->s.bset);
623 }
624 
625 
626 struct bitset_vtable bitset_stats_vtable = {
627   bitset_stats_set,
628   bitset_stats_reset,
629   bitset_stats_toggle,
630   bitset_stats_test,
631   bitset_stats_resize,
632   bitset_stats_size,
633   bitset_stats_count,
634   bitset_stats_empty_p,
635   bitset_stats_ones,
636   bitset_stats_zero,
637   bitset_stats_copy,
638   bitset_stats_disjoint_p,
639   bitset_stats_equal_p,
640   bitset_stats_not,
641   bitset_stats_subset_p,
642   bitset_stats_and,
643   bitset_stats_and_cmp,
644   bitset_stats_andn,
645   bitset_stats_andn_cmp,
646   bitset_stats_or,
647   bitset_stats_or_cmp,
648   bitset_stats_xor,
649   bitset_stats_xor_cmp,
650   bitset_stats_and_or,
651   bitset_stats_and_or_cmp,
652   bitset_stats_andn_or,
653   bitset_stats_andn_or_cmp,
654   bitset_stats_or_and,
655   bitset_stats_or_and_cmp,
656   bitset_stats_list,
657   bitset_stats_list_reverse,
658   bitset_stats_free,
659   BITSET_STATS
660 };
661 
662 
663 /* Return enclosed bitset type.  */
664 enum bitset_type
bitset_stats_type_get(bitset bset)665 bitset_stats_type_get (bitset bset)
666 {
667    return BITSET_TYPE_ (bset->s.bset);
668 }
669 
670 
671 size_t
bitset_stats_bytes(void)672 bitset_stats_bytes (void)
673 {
674   return sizeof (struct bitset_stats_struct);
675 }
676 
677 
678 bitset
bitset_stats_init(bitset bset,bitset_bindex n_bits,enum bitset_type type)679 bitset_stats_init (bitset bset, bitset_bindex n_bits, enum bitset_type type)
680 {
681   size_t bytes;
682   bitset sbset;
683 
684   bset->b.vtable = &bitset_stats_vtable;
685 
686   /* Disable cache.  */
687   bset->b.cindex = 0;
688   bset->b.csize = 0;
689   bset->b.cdata = 0;
690 
691   BITSET_NBITS_ (bset) = n_bits;
692 
693   /* Set up the actual bitset implementation that
694      we are a wrapper over.  */
695   switch (type)
696     {
697     default:
698       abort ();
699 
700     case BITSET_ARRAY:
701       bytes = abitset_bytes (n_bits);
702       sbset = xcalloc (1, bytes);
703       abitset_init (sbset, n_bits);
704       break;
705 
706     case BITSET_LIST:
707       bytes = lbitset_bytes (n_bits);
708       sbset = xcalloc (1, bytes);
709       lbitset_init (sbset, n_bits);
710       break;
711 
712     case BITSET_TABLE:
713       bytes = ebitset_bytes (n_bits);
714       sbset = xcalloc (1, bytes);
715       ebitset_init (sbset, n_bits);
716       break;
717 
718     case BITSET_VARRAY:
719       bytes = vbitset_bytes (n_bits);
720       sbset = xcalloc (1, bytes);
721       vbitset_init (sbset, n_bits);
722       break;
723     }
724 
725   bset->s.bset = sbset;
726 
727   BITSET_STATS_ALLOCS_INC (type);
728 
729   return bset;
730 }
731