stats.c 18 KB

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