OLD | NEW |
(Empty) | |
| 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 3 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, see <http://www.gnu.org/licenses/>. */ |
| 17 |
| 18 /* This file is a wrapper bitset implementation for the other bitset |
| 19 implementations. It provides bitset compatibility checking and |
| 20 statistics gathering without having to instrument the bitset |
| 21 implementations. When statistics gathering is enabled, the bitset |
| 22 operations get vectored through here and we then call the appropriate |
| 23 routines. */ |
| 24 |
| 25 #include <config.h> |
| 26 |
| 27 #include "bitset_stats.h" |
| 28 |
| 29 #include "bbitset.h" |
| 30 #include "abitset.h" |
| 31 #include "ebitset.h" |
| 32 #include "lbitset.h" |
| 33 #include "vbitset.h" |
| 34 #include <stdlib.h> |
| 35 #include <string.h> |
| 36 #include <stdio.h> |
| 37 |
| 38 #include "gettext.h" |
| 39 #define _(Msgid) gettext (Msgid) |
| 40 |
| 41 /* Configuration macros. */ |
| 42 #define BITSET_STATS_FILE "bitset.dat" |
| 43 #define BITSET_LOG_COUNT_BINS 10 |
| 44 #define BITSET_LOG_SIZE_BINS 16 |
| 45 #define BITSET_DENSITY_BINS 20 |
| 46 |
| 47 |
| 48 /* Accessor macros. */ |
| 49 #define BITSET_STATS_ALLOCS_INC(TYPE) \ |
| 50 bitset_stats_info->types[(TYPE)].allocs++ |
| 51 #define BITSET_STATS_FREES_INC(BSET) \ |
| 52 bitset_stats_info->types[BITSET_TYPE_ (BSET)].frees++ |
| 53 #define BITSET_STATS_SETS_INC(BSET) \ |
| 54 bitset_stats_info->types[BITSET_TYPE_ (BSET)].sets++ |
| 55 #define BITSET_STATS_CACHE_SETS_INC(BSET) \ |
| 56 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_sets++ |
| 57 #define BITSET_STATS_RESETS_INC(BSET) \ |
| 58 bitset_stats_info->types[BITSET_TYPE_ (BSET)].resets++ |
| 59 #define BITSET_STATS_CACHE_RESETS_INC(BSET) \ |
| 60 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_resets++ |
| 61 #define BITSET_STATS_TESTS_INC(BSET) \ |
| 62 bitset_stats_info->types[BITSET_TYPE_ (BSET)].tests++ |
| 63 #define BITSET_STATS_CACHE_TESTS_INC(BSET) \ |
| 64 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_tests++ |
| 65 #define BITSET_STATS_LISTS_INC(BSET) \ |
| 66 bitset_stats_info->types[BITSET_TYPE_ (BSET)].lists++ |
| 67 #define BITSET_STATS_LIST_COUNTS_INC(BSET, I) \ |
| 68 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_counts[(I)]++ |
| 69 #define BITSET_STATS_LIST_SIZES_INC(BSET, I) \ |
| 70 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_sizes[(I)]++ |
| 71 #define BITSET_STATS_LIST_DENSITY_INC(BSET, I) \ |
| 72 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_density[(I)]++ |
| 73 |
| 74 |
| 75 struct bitset_type_info_struct |
| 76 { |
| 77 unsigned int allocs; |
| 78 unsigned int frees; |
| 79 unsigned int lists; |
| 80 unsigned int sets; |
| 81 unsigned int cache_sets; |
| 82 unsigned int resets; |
| 83 unsigned int cache_resets; |
| 84 unsigned int tests; |
| 85 unsigned int cache_tests; |
| 86 unsigned int list_counts[BITSET_LOG_COUNT_BINS]; |
| 87 unsigned int list_sizes[BITSET_LOG_SIZE_BINS]; |
| 88 unsigned int list_density[BITSET_DENSITY_BINS]; |
| 89 }; |
| 90 |
| 91 struct bitset_stats_info_struct |
| 92 { |
| 93 unsigned int runs; |
| 94 struct bitset_type_info_struct types[BITSET_TYPE_NUM]; |
| 95 }; |
| 96 |
| 97 |
| 98 struct bitset_stats_info_struct bitset_stats_info_data; |
| 99 struct bitset_stats_info_struct *bitset_stats_info; |
| 100 bool bitset_stats_enabled = false; |
| 101 |
| 102 |
| 103 /* Print a percentage histogram with message MSG to FILE. */ |
| 104 static void |
| 105 bitset_percent_histogram_print (FILE *file, const char *name, const char *msg, |
| 106 unsigned int n_bins, unsigned int *bins) |
| 107 { |
| 108 unsigned int i; |
| 109 unsigned int total; |
| 110 |
| 111 total = 0; |
| 112 for (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 (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 |
| 129 bitset_log_histogram_print (FILE *file, const char *name, const char *msg, |
| 130 unsigned int n_bins, unsigned int *bins) |
| 131 { |
| 132 unsigned int i; |
| 133 unsigned int total; |
| 134 unsigned int max_width; |
| 135 |
| 136 total = 0; |
| 137 for (i = 0; i < n_bins; i++) |
| 138 total += bins[i]; |
| 139 |
| 140 if (!total) |
| 141 return; |
| 142 |
| 143 /* Determine number of useful bins. */ |
| 144 for (i = n_bins; i > 3 && ! bins[i - 1]; i--) |
| 145 continue; |
| 146 n_bins = i; |
| 147 |
| 148 /* 2 * ceil (log10 (2) * (N - 1)) + 1. */ |
| 149 max_width = 2 * (unsigned int) (0.30103 * (n_bins - 1) + 0.9999) + 1; |
| 150 |
| 151 fprintf (file, "%s %s", name, msg); |
| 152 for (i = 0; i < 2; i++) |
| 153 fprintf (file, "%*d\t%8u (%5.1f%%)\n", |
| 154 max_width, i, bins[i], 100.0 * bins[i] / total); |
| 155 |
| 156 for (; i < n_bins; i++) |
| 157 fprintf (file, "%*lu-%lu\t%8u (%5.1f%%)\n", |
| 158 max_width - ((unsigned int) (0.30103 * (i) + 0.9999) + 1), |
| 159 1UL << (i - 1), |
| 160 (1UL << i) - 1, |
| 161 bins[i], |
| 162 (100.0 * bins[i]) / total); |
| 163 } |
| 164 |
| 165 |
| 166 /* Print bitset statistics to FILE. */ |
| 167 static void |
| 168 bitset_stats_print_1 (FILE *file, const char *name, |
| 169 struct bitset_type_info_struct *stats) |
| 170 { |
| 171 if (!stats) |
| 172 return; |
| 173 |
| 174 fprintf (file, "%s:\n", name); |
| 175 fprintf (file, _("%u bitset_allocs, %u freed (%.2f%%).\n"), |
| 176 stats->allocs, stats->frees, |
| 177 stats->allocs ? 100.0 * stats->frees / stats->allocs : 0); |
| 178 fprintf (file, _("%u bitset_sets, %u cached (%.2f%%)\n"), |
| 179 stats->sets, stats->cache_sets, |
| 180 stats->sets ? 100.0 * stats->cache_sets / stats->sets : 0); |
| 181 fprintf (file, _("%u bitset_resets, %u cached (%.2f%%)\n"), |
| 182 stats->resets, stats->cache_resets, |
| 183 stats->resets ? 100.0 * stats->cache_resets / stats->resets : 0); |
| 184 fprintf (file, _("%u bitset_tests, %u cached (%.2f%%)\n"), |
| 185 stats->tests, stats->cache_tests, |
| 186 stats->tests ? 100.0 * stats->cache_tests / stats->tests : 0); |
| 187 |
| 188 fprintf (file, _("%u bitset_lists\n"), stats->lists); |
| 189 |
| 190 bitset_log_histogram_print (file, name, _("count log histogram\n"), |
| 191 BITSET_LOG_COUNT_BINS, stats->list_counts); |
| 192 |
| 193 bitset_log_histogram_print (file, name, _("size log histogram\n"), |
| 194 BITSET_LOG_SIZE_BINS, stats->list_sizes); |
| 195 |
| 196 bitset_percent_histogram_print (file, name, _("density histogram\n"), |
| 197 BITSET_DENSITY_BINS, stats->list_density); |
| 198 } |
| 199 |
| 200 |
| 201 /* Print all bitset statistics to FILE. */ |
| 202 static void |
| 203 bitset_stats_print (FILE *file, bool verbose ATTRIBUTE_UNUSED) |
| 204 { |
| 205 int i; |
| 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 (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 |
| 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 |
| 232 bitset_stats_disable (void) |
| 233 { |
| 234 bitset_stats_enabled = false; |
| 235 } |
| 236 |
| 237 |
| 238 /* Read bitset statistics file. */ |
| 239 void |
| 240 bitset_stats_read (const char *file_name) |
| 241 { |
| 242 FILE *file; |
| 243 |
| 244 if (!bitset_stats_info) |
| 245 return; |
| 246 |
| 247 if (!file_name) |
| 248 file_name = BITSET_STATS_FILE; |
| 249 |
| 250 file = fopen (file_name, "r"); |
| 251 if (file) |
| 252 { |
| 253 if (fread (&bitset_stats_info_data, sizeof (bitset_stats_info_data), |
| 254 1, file) != 1) |
| 255 { |
| 256 if (ferror (file)) |
| 257 perror (_("Could not read stats file.")); |
| 258 else |
| 259 fprintf (stderr, _("Bad stats file size.\n")); |
| 260 } |
| 261 if (fclose (file) != 0) |
| 262 perror (_("Could not read stats file.")); |
| 263 } |
| 264 bitset_stats_info_data.runs++; |
| 265 } |
| 266 |
| 267 |
| 268 /* Write bitset statistics file. */ |
| 269 void |
| 270 bitset_stats_write (const char *file_name) |
| 271 { |
| 272 FILE *file; |
| 273 |
| 274 if (!bitset_stats_info) |
| 275 return; |
| 276 |
| 277 if (!file_name) |
| 278 file_name = BITSET_STATS_FILE; |
| 279 |
| 280 file = fopen (file_name, "w"); |
| 281 if (file) |
| 282 { |
| 283 if (fwrite (&bitset_stats_info_data, sizeof (bitset_stats_info_data), |
| 284 1, file) != 1) |
| 285 perror (_("Could not write stats file.")); |
| 286 if (fclose (file) != 0) |
| 287 perror (_("Could not write stats file.")); |
| 288 } |
| 289 else |
| 290 perror (_("Could not open stats file for writing.")); |
| 291 } |
| 292 |
| 293 |
| 294 /* Dump bitset statistics to FILE. */ |
| 295 void |
| 296 bitset_stats_dump (FILE *file) |
| 297 { |
| 298 bitset_stats_print (file, false); |
| 299 } |
| 300 |
| 301 |
| 302 /* Function to be called from debugger to print bitset stats. */ |
| 303 void |
| 304 debug_bitset_stats (void) |
| 305 { |
| 306 bitset_stats_print (stderr, true); |
| 307 } |
| 308 |
| 309 |
| 310 static void |
| 311 bitset_stats_set (bitset dst, bitset_bindex bitno) |
| 312 { |
| 313 bitset bset = dst->s.bset; |
| 314 bitset_windex wordno = bitno / BITSET_WORD_BITS; |
| 315 bitset_windex offset = wordno - bset->b.cindex; |
| 316 |
| 317 BITSET_STATS_SETS_INC (bset); |
| 318 |
| 319 if (offset < bset->b.csize) |
| 320 { |
| 321 bset->b.cdata[offset] |= (bitset_word) 1 << (bitno % BITSET_WORD_BITS); |
| 322 BITSET_STATS_CACHE_SETS_INC (bset); |
| 323 } |
| 324 else |
| 325 BITSET_SET_ (bset, bitno); |
| 326 } |
| 327 |
| 328 |
| 329 static void |
| 330 bitset_stats_reset (bitset dst, bitset_bindex bitno) |
| 331 { |
| 332 bitset bset = dst->s.bset; |
| 333 bitset_windex wordno = bitno / BITSET_WORD_BITS; |
| 334 bitset_windex offset = wordno - bset->b.cindex; |
| 335 |
| 336 BITSET_STATS_RESETS_INC (bset); |
| 337 |
| 338 if (offset < bset->b.csize) |
| 339 { |
| 340 bset->b.cdata[offset] &= |
| 341 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS)); |
| 342 BITSET_STATS_CACHE_RESETS_INC (bset); |
| 343 } |
| 344 else |
| 345 BITSET_RESET_ (bset, bitno); |
| 346 } |
| 347 |
| 348 |
| 349 static bool |
| 350 bitset_stats_toggle (bitset src, bitset_bindex bitno) |
| 351 { |
| 352 return BITSET_TOGGLE_ (src->s.bset, bitno); |
| 353 } |
| 354 |
| 355 |
| 356 static bool |
| 357 bitset_stats_test (bitset src, bitset_bindex bitno) |
| 358 { |
| 359 bitset bset = src->s.bset; |
| 360 bitset_windex wordno = bitno / BITSET_WORD_BITS; |
| 361 bitset_windex offset = wordno - bset->b.cindex; |
| 362 |
| 363 BITSET_STATS_TESTS_INC (bset); |
| 364 |
| 365 if (offset < bset->b.csize) |
| 366 { |
| 367 BITSET_STATS_CACHE_TESTS_INC (bset); |
| 368 return (bset->b.cdata[offset] >> (bitno % BITSET_WORD_BITS)) & 1; |
| 369 } |
| 370 else |
| 371 return BITSET_TEST_ (bset, bitno); |
| 372 } |
| 373 |
| 374 |
| 375 static bitset_bindex |
| 376 bitset_stats_resize (bitset src, bitset_bindex size) |
| 377 { |
| 378 return BITSET_RESIZE_ (src->s.bset, size); |
| 379 } |
| 380 |
| 381 |
| 382 static bitset_bindex |
| 383 bitset_stats_size (bitset src) |
| 384 { |
| 385 return BITSET_SIZE_ (src->s.bset); |
| 386 } |
| 387 |
| 388 |
| 389 static bitset_bindex |
| 390 bitset_stats_count (bitset src) |
| 391 { |
| 392 return BITSET_COUNT_ (src->s.bset); |
| 393 } |
| 394 |
| 395 |
| 396 static bool |
| 397 bitset_stats_empty_p (bitset dst) |
| 398 { |
| 399 return BITSET_EMPTY_P_ (dst->s.bset); |
| 400 } |
| 401 |
| 402 |
| 403 static void |
| 404 bitset_stats_ones (bitset dst) |
| 405 { |
| 406 BITSET_ONES_ (dst->s.bset); |
| 407 } |
| 408 |
| 409 |
| 410 static void |
| 411 bitset_stats_zero (bitset dst) |
| 412 { |
| 413 BITSET_ZERO_ (dst->s.bset); |
| 414 } |
| 415 |
| 416 |
| 417 static void |
| 418 bitset_stats_copy (bitset dst, bitset src) |
| 419 { |
| 420 BITSET_CHECK2_ (dst, src); |
| 421 BITSET_COPY_ (dst->s.bset, src->s.bset); |
| 422 } |
| 423 |
| 424 |
| 425 static bool |
| 426 bitset_stats_disjoint_p (bitset dst, bitset src) |
| 427 { |
| 428 BITSET_CHECK2_ (dst, src); |
| 429 return BITSET_DISJOINT_P_ (dst->s.bset, src->s.bset); |
| 430 } |
| 431 |
| 432 |
| 433 static bool |
| 434 bitset_stats_equal_p (bitset dst, bitset src) |
| 435 { |
| 436 BITSET_CHECK2_ (dst, src); |
| 437 return BITSET_EQUAL_P_ (dst->s.bset, src->s.bset); |
| 438 } |
| 439 |
| 440 |
| 441 static void |
| 442 bitset_stats_not (bitset dst, bitset src) |
| 443 { |
| 444 BITSET_CHECK2_ (dst, src); |
| 445 BITSET_NOT_ (dst->s.bset, src->s.bset); |
| 446 } |
| 447 |
| 448 |
| 449 static bool |
| 450 bitset_stats_subset_p (bitset dst, bitset src) |
| 451 { |
| 452 BITSET_CHECK2_ (dst, src); |
| 453 return BITSET_SUBSET_P_ (dst->s.bset, src->s.bset); |
| 454 } |
| 455 |
| 456 |
| 457 static void |
| 458 bitset_stats_and (bitset dst, bitset src1, bitset src2) |
| 459 { |
| 460 BITSET_CHECK3_ (dst, src1, src2); |
| 461 BITSET_AND_ (dst->s.bset, src1->s.bset, src2->s.bset); |
| 462 } |
| 463 |
| 464 |
| 465 static bool |
| 466 bitset_stats_and_cmp (bitset dst, bitset src1, bitset src2) |
| 467 { |
| 468 BITSET_CHECK3_ (dst, src1, src2); |
| 469 return BITSET_AND_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset); |
| 470 } |
| 471 |
| 472 |
| 473 static void |
| 474 bitset_stats_andn (bitset dst, bitset src1, bitset src2) |
| 475 { |
| 476 BITSET_CHECK3_ (dst, src1, src2); |
| 477 BITSET_ANDN_ (dst->s.bset, src1->s.bset, src2->s.bset); |
| 478 } |
| 479 |
| 480 |
| 481 static bool |
| 482 bitset_stats_andn_cmp (bitset dst, bitset src1, bitset src2) |
| 483 { |
| 484 BITSET_CHECK3_ (dst, src1, src2); |
| 485 return BITSET_ANDN_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset); |
| 486 } |
| 487 |
| 488 |
| 489 static void |
| 490 bitset_stats_or (bitset dst, bitset src1, bitset src2) |
| 491 { |
| 492 BITSET_CHECK3_ (dst, src1, src2); |
| 493 BITSET_OR_ (dst->s.bset, src1->s.bset, src2->s.bset); |
| 494 } |
| 495 |
| 496 |
| 497 static bool |
| 498 bitset_stats_or_cmp (bitset dst, bitset src1, bitset src2) |
| 499 { |
| 500 BITSET_CHECK3_ (dst, src1, src2); |
| 501 return BITSET_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset); |
| 502 } |
| 503 |
| 504 |
| 505 static void |
| 506 bitset_stats_xor (bitset dst, bitset src1, bitset src2) |
| 507 { |
| 508 BITSET_CHECK3_ (dst, src1, src2); |
| 509 BITSET_XOR_ (dst->s.bset, src1->s.bset, src2->s.bset); |
| 510 } |
| 511 |
| 512 |
| 513 static bool |
| 514 bitset_stats_xor_cmp (bitset dst, bitset src1, bitset src2) |
| 515 { |
| 516 BITSET_CHECK3_ (dst, src1, src2); |
| 517 return BITSET_XOR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset); |
| 518 } |
| 519 |
| 520 |
| 521 static void |
| 522 bitset_stats_and_or (bitset dst, bitset src1, bitset src2, bitset src3) |
| 523 { |
| 524 BITSET_CHECK4_ (dst, src1, src2, src3); |
| 525 BITSET_AND_OR_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset); |
| 526 } |
| 527 |
| 528 |
| 529 static bool |
| 530 bitset_stats_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3) |
| 531 { |
| 532 BITSET_CHECK4_ (dst, src1, src2, src3); |
| 533 return BITSET_AND_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bs
et); |
| 534 } |
| 535 |
| 536 |
| 537 static void |
| 538 bitset_stats_andn_or (bitset dst, bitset src1, bitset src2, bitset src3) |
| 539 { |
| 540 BITSET_CHECK4_ (dst, src1, src2, src3); |
| 541 BITSET_ANDN_OR_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset); |
| 542 } |
| 543 |
| 544 |
| 545 static bool |
| 546 bitset_stats_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3) |
| 547 { |
| 548 BITSET_CHECK4_ (dst, src1, src2, src3); |
| 549 return BITSET_ANDN_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.b
set); |
| 550 } |
| 551 |
| 552 |
| 553 static void |
| 554 bitset_stats_or_and (bitset dst, bitset src1, bitset src2, bitset src3) |
| 555 { |
| 556 BITSET_CHECK4_ (dst, src1, src2, src3); |
| 557 BITSET_OR_AND_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset); |
| 558 } |
| 559 |
| 560 |
| 561 static bool |
| 562 bitset_stats_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3) |
| 563 { |
| 564 BITSET_CHECK4_ (dst, src1, src2, src3); |
| 565 return BITSET_OR_AND_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bs
et); |
| 566 } |
| 567 |
| 568 |
| 569 static bitset_bindex |
| 570 bitset_stats_list (bitset bset, bitset_bindex *list, |
| 571 bitset_bindex num, bitset_bindex *next) |
| 572 { |
| 573 bitset_bindex count; |
| 574 bitset_bindex tmp; |
| 575 bitset_bindex size; |
| 576 bitset_bindex i; |
| 577 enum bitset_type type; |
| 578 |
| 579 count = BITSET_LIST_ (bset->s.bset, list, num, next); |
| 580 |
| 581 type = BITSET_TYPE_ (bset->s.bset); |
| 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 |
| 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 |
| 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 |
| 663 bitset_stats_type_get (bitset bset) |
| 664 { |
| 665 return BITSET_TYPE_ (bset->s.bset); |
| 666 } |
| 667 |
| 668 |
| 669 size_t |
| 670 bitset_stats_bytes (void) |
| 671 { |
| 672 return sizeof (struct bitset_stats_struct); |
| 673 } |
| 674 |
| 675 |
| 676 bitset |
| 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 } |
OLD | NEW |