bitset.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /* General bitsets.
  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. #include <config.h>
  15. #include "bitset.h"
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "obstack.h"
  19. #include "bitset/array.h"
  20. #include "bitset/list.h"
  21. #include "bitset/stats.h"
  22. #include "bitset/table.h"
  23. #include "bitset/vector.h"
  24. const char * const bitset_type_names[] = BITSET_TYPE_NAMES;
  25. /* Return number of bytes required to create a N_BIT bitset
  26. of TYPE. The bitset may grow to require more bytes than this. */
  27. size_t
  28. bitset_bytes (enum bitset_type type, bitset_bindex n_bits)
  29. {
  30. if (bitset_stats_enabled)
  31. return bitset_stats_bytes ();
  32. switch (type)
  33. {
  34. default:
  35. abort ();
  36. case BITSET_ARRAY:
  37. return abitset_bytes (n_bits);
  38. case BITSET_LIST:
  39. return lbitset_bytes (n_bits);
  40. case BITSET_TABLE:
  41. return tbitset_bytes (n_bits);
  42. case BITSET_VECTOR:
  43. return vbitset_bytes (n_bits);
  44. }
  45. }
  46. /* Initialise bitset BSET of TYPE for N_BITS. */
  47. bitset
  48. bitset_init (bitset bset, bitset_bindex n_bits, enum bitset_type type)
  49. {
  50. if (bitset_stats_enabled)
  51. return bitset_stats_init (bset, n_bits, type);
  52. switch (type)
  53. {
  54. default:
  55. abort ();
  56. case BITSET_ARRAY:
  57. return abitset_init (bset, n_bits);
  58. case BITSET_LIST:
  59. return lbitset_init (bset, n_bits);
  60. case BITSET_TABLE:
  61. return tbitset_init (bset, n_bits);
  62. case BITSET_VECTOR:
  63. return vbitset_init (bset, n_bits);
  64. }
  65. }
  66. /* Select a bitset type for a set of N_BITS and with attribute hints
  67. specified by ATTR. For variable size bitsets, N_BITS is only a
  68. hint and may be zero. */
  69. enum bitset_type
  70. bitset_type_choose (bitset_bindex n_bits MAYBE_UNUSED, unsigned attr)
  71. {
  72. /* Check attributes. */
  73. if (attr & BITSET_FIXED && attr & BITSET_VARIABLE)
  74. abort ();
  75. if (attr & BITSET_SPARSE && attr & BITSET_DENSE)
  76. abort ();
  77. /* Choose the type of bitset. Note that sometimes we will be asked
  78. for a zero length fixed size bitset. */
  79. /* If no attributes selected, choose a good compromise. */
  80. if (!attr)
  81. return BITSET_VECTOR;
  82. if (attr & BITSET_SPARSE)
  83. return BITSET_LIST;
  84. if (attr & BITSET_FIXED)
  85. return BITSET_ARRAY;
  86. if (attr & BITSET_GREEDY)
  87. return BITSET_TABLE;
  88. return BITSET_VECTOR;
  89. }
  90. /* Create a bitset of N_BITS of type TYPE. */
  91. bitset
  92. bitset_alloc (bitset_bindex n_bits, enum bitset_type type)
  93. {
  94. size_t bytes = bitset_bytes (type, n_bits);
  95. bitset bset = xzalloc (bytes);
  96. /* The cache is disabled until some elements are allocated. If we
  97. have variable length arrays, then we may need to allocate a dummy
  98. element. */
  99. return bitset_init (bset, n_bits, type);
  100. }
  101. /* Create a bitset of N_BITS of type TYPE. */
  102. bitset
  103. bitset_obstack_alloc (struct obstack *bobstack,
  104. bitset_bindex n_bits, enum bitset_type type)
  105. {
  106. size_t bytes = bitset_bytes (type, n_bits);
  107. bitset bset = obstack_alloc (bobstack, bytes);
  108. memset (bset, 0, bytes);
  109. return bitset_init (bset, n_bits, type);
  110. }
  111. /* Create a bitset of N_BITS and with attribute hints specified by
  112. ATTR. */
  113. bitset
  114. bitset_create (bitset_bindex n_bits, unsigned attr)
  115. {
  116. enum bitset_type type = bitset_type_choose (n_bits, attr);
  117. return bitset_alloc (n_bits, type);
  118. }
  119. /* Free bitset BSET. */
  120. void
  121. bitset_free (bitset bset)
  122. {
  123. if (bset)
  124. {
  125. BITSET_FREE_ (bset);
  126. free (bset);
  127. }
  128. }
  129. /* Free bitset BSET allocated on obstack. */
  130. void
  131. bitset_obstack_free (bitset bset)
  132. {
  133. if (bset)
  134. BITSET_FREE_ (bset);
  135. }
  136. /* Return bitset type. */
  137. enum bitset_type
  138. bitset_type_get (bitset bset)
  139. {
  140. enum bitset_type type = BITSET_TYPE_ (bset);
  141. if (type != BITSET_STATS)
  142. return type;
  143. return bitset_stats_type_get (bset);
  144. }
  145. /* Return name of bitset type. */
  146. const char *
  147. bitset_type_name_get (bitset bset)
  148. {
  149. enum bitset_type type = bitset_type_get (bset);
  150. return bitset_type_names[type];
  151. }
  152. /* Find next bit set in SRC starting from and including BITNO.
  153. Return BITSET_BINDEX_MAX if SRC empty. */
  154. bitset_bindex
  155. bitset_next (bitset src, bitset_bindex bitno)
  156. {
  157. bitset_bindex next = bitno;
  158. bitset_bindex val;
  159. if (!bitset_list (src, &val, 1, &next))
  160. return BITSET_BINDEX_MAX;
  161. return val;
  162. }
  163. /* Return true if both bitsets are of the same type and size. */
  164. extern bool
  165. bitset_compatible_p (bitset bset1, bitset bset2)
  166. {
  167. return BITSET_COMPATIBLE_ (bset1, bset2);
  168. }
  169. /* Find previous bit set in SRC starting from and including BITNO.
  170. Return BITSET_BINDEX_MAX if SRC empty. */
  171. bitset_bindex
  172. bitset_prev (bitset src, bitset_bindex bitno)
  173. {
  174. bitset_bindex next = bitno;
  175. bitset_bindex val;
  176. if (!bitset_list_reverse (src, &val, 1, &next))
  177. return BITSET_BINDEX_MAX;
  178. return val;
  179. }
  180. /* Find first set bit. */
  181. bitset_bindex
  182. bitset_first (bitset src)
  183. {
  184. return bitset_next (src, 0);
  185. }
  186. /* Find last set bit. */
  187. bitset_bindex
  188. bitset_last (bitset src)
  189. {
  190. return bitset_prev (src, 0);
  191. }
  192. /* Is BITNO in SRC the only set bit? */
  193. bool
  194. bitset_only_set_p (bitset src, bitset_bindex bitno)
  195. {
  196. bitset_bindex val[2];
  197. bitset_bindex next = 0;
  198. if (bitset_list (src, val, 2, &next) != 1)
  199. return false;
  200. return val[0] == bitno;
  201. }
  202. /* Print contents of bitset BSET to FILE. */
  203. static void
  204. bitset_print (FILE *file, bitset bset, bool verbose)
  205. {
  206. if (verbose)
  207. fprintf (file, "n_bits = %lu, set = {",
  208. (unsigned long) bitset_size (bset));
  209. unsigned pos = 30;
  210. bitset_bindex i;
  211. bitset_iterator iter;
  212. BITSET_FOR_EACH (iter, bset, i, 0)
  213. {
  214. if (pos > 70)
  215. {
  216. fprintf (file, "\n");
  217. pos = 0;
  218. }
  219. fprintf (file, "%lu ", (unsigned long) i);
  220. pos += 1 + (i >= 10) + (i >= 100);
  221. }
  222. if (verbose)
  223. fprintf (file, "}\n");
  224. }
  225. /* Dump bitset BSET to FILE. */
  226. void
  227. bitset_dump (FILE *file, bitset bset)
  228. {
  229. bitset_print (file, bset, false);
  230. }
  231. /* Release memory associated with bitsets. */
  232. void
  233. bitset_release_memory (void)
  234. {
  235. lbitset_release_memory ();
  236. tbitset_release_memory ();
  237. }
  238. /* Toggle bit BITNO in bitset BSET and the new value of the bit. */
  239. bool
  240. bitset_toggle_ (bitset bset, bitset_bindex bitno)
  241. {
  242. /* This routine is for completeness. It could be optimized if
  243. required. */
  244. if (bitset_test (bset, bitno))
  245. {
  246. bitset_reset (bset, bitno);
  247. return false;
  248. }
  249. else
  250. {
  251. bitset_set (bset, bitno);
  252. return true;
  253. }
  254. }
  255. /* Return number of bits in bitset SRC. */
  256. bitset_bindex
  257. bitset_size_ (bitset src)
  258. {
  259. return BITSET_NBITS_ (src);
  260. }
  261. /* Return number of bits set in bitset SRC. */
  262. bitset_bindex
  263. bitset_count_ (bitset src)
  264. {
  265. bitset_bindex list[BITSET_LIST_SIZE];
  266. bitset_bindex count = 0;
  267. /* This could be greatly sped up by adding a count method for each
  268. bitset implementation that uses a direct technique (based on
  269. masks) for counting the number of bits set in a word. */
  270. {
  271. bitset_bindex next = 0;
  272. bitset_bindex num;
  273. while ((num = bitset_list (src, list, BITSET_LIST_SIZE, &next)))
  274. count += num;
  275. }
  276. return count;
  277. }
  278. /* DST = SRC. Return true if DST != SRC.
  279. This is a fallback for the case where SRC and DST are different
  280. bitset types. */
  281. bool
  282. bitset_copy_ (bitset dst, bitset src)
  283. {
  284. bitset_bindex i;
  285. bitset_iterator iter;
  286. /* Convert bitset types. We assume that the DST bitset
  287. is large enough to hold the SRC bitset. */
  288. bitset_zero (dst);
  289. BITSET_FOR_EACH (iter, src, i, 0)
  290. bitset_set (dst, i);
  291. return true;
  292. }
  293. /* This is a fallback for implementations that do not support
  294. four operand operations. */
  295. static inline bool
  296. bitset_op4_cmp (bitset dst, bitset src1, bitset src2, bitset src3,
  297. enum bitset_ops op)
  298. {
  299. bool changed = false;
  300. /* Create temporary bitset. */
  301. bool stats_enabled_save = bitset_stats_enabled;
  302. bitset_stats_enabled = false;
  303. bitset tmp = bitset_alloc (0, bitset_type_get (dst));
  304. bitset_stats_enabled = stats_enabled_save;
  305. switch (op)
  306. {
  307. default:
  308. abort ();
  309. case BITSET_OP_OR_AND:
  310. bitset_or (tmp, src1, src2);
  311. changed = bitset_and_cmp (dst, src3, tmp);
  312. break;
  313. case BITSET_OP_AND_OR:
  314. bitset_and (tmp, src1, src2);
  315. changed = bitset_or_cmp (dst, src3, tmp);
  316. break;
  317. case BITSET_OP_ANDN_OR:
  318. bitset_andn (tmp, src1, src2);
  319. changed = bitset_or_cmp (dst, src3, tmp);
  320. break;
  321. }
  322. bitset_free (tmp);
  323. return changed;
  324. }
  325. /* DST = (SRC1 & SRC2) | SRC3. */
  326. void
  327. bitset_and_or_ (bitset dst, bitset src1, bitset src2, bitset src3)
  328. {
  329. bitset_and_or_cmp_ (dst, src1, src2, src3);
  330. }
  331. /* DST = (SRC1 & SRC2) | SRC3. Return non-zero if
  332. DST != (SRC1 & SRC2) | SRC3. */
  333. bool
  334. bitset_and_or_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
  335. {
  336. return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_AND_OR);
  337. }
  338. /* DST = (SRC1 & ~SRC2) | SRC3. */
  339. void
  340. bitset_andn_or_ (bitset dst, bitset src1, bitset src2, bitset src3)
  341. {
  342. bitset_andn_or_cmp_ (dst, src1, src2, src3);
  343. }
  344. /* DST = (SRC1 & ~SRC2) | SRC3. Return non-zero if
  345. DST != (SRC1 & ~SRC2) | SRC3. */
  346. bool
  347. bitset_andn_or_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
  348. {
  349. return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_ANDN_OR);
  350. }
  351. /* DST = (SRC1 | SRC2) & SRC3. */
  352. void
  353. bitset_or_and_ (bitset dst, bitset src1, bitset src2, bitset src3)
  354. {
  355. bitset_or_and_cmp_ (dst, src1, src2, src3);
  356. }
  357. /* DST = (SRC1 | SRC2) & SRC3. Return non-zero if
  358. DST != (SRC1 | SRC2) & SRC3. */
  359. bool
  360. bitset_or_and_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
  361. {
  362. return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_OR_AND);
  363. }
  364. /* Function to be called from debugger to print bitset. */
  365. void
  366. debug_bitset (bitset bset)
  367. {
  368. if (bset)
  369. bitset_print (stderr, bset, true);
  370. }