jbitset.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. #ifndef CCAN_JBITSET_H
  2. #define CCAN_JBITSET_H
  3. #include <Judy.h>
  4. #include <stdbool.h>
  5. #include <ccan/compiler/compiler.h>
  6. #include <assert.h>
  7. /**
  8. * jbit_new - create a new, empty jbitset.
  9. *
  10. * See Also:
  11. * JBIT_DEFINE_TYPE()
  12. *
  13. * Example:
  14. * struct jbitset *set = jbit_new();
  15. * if (!set)
  16. * errx(1, "Failed to allocate jbitset");
  17. */
  18. struct jbitset *jbit_new(void);
  19. /**
  20. * jbit_free - destroy a jbitset.
  21. * @set: the set returned from jbit_new.
  22. *
  23. * Example:
  24. * jbit_free(set);
  25. */
  26. void jbit_free(const struct jbitset *set);
  27. /* This is exposed in the header so we can inline. Treat it as private! */
  28. struct jbitset {
  29. void *judy;
  30. JError_t err;
  31. const char *errstr;
  32. };
  33. const char *COLD_ATTRIBUTE jbit_error_(struct jbitset *set);
  34. /**
  35. * jbit_error - test for an error in the a previous jbit_ operation.
  36. * @set: the set to test.
  37. *
  38. * Under normal circumstances, return NULL to indicate no error has occurred.
  39. * Otherwise, it will return a string containing the error. This string
  40. * can only be freed by jbit_free() on the set.
  41. *
  42. * Other than out-of-memory, errors are caused by memory corruption or
  43. * interface misuse.
  44. *
  45. * Example:
  46. * struct jbitset *set = jbit_new();
  47. * const char *errstr;
  48. *
  49. * if (!set)
  50. * err(1, "allocating jbitset");
  51. * errstr = jbit_error(set);
  52. * if (errstr)
  53. * errx(1, "Woah, error on newly created set?! %s", errstr);
  54. */
  55. static inline const char *jbit_error(struct jbitset *set)
  56. {
  57. if (JU_ERRNO(&set->err) <= JU_ERRNO_NFMAX)
  58. return NULL;
  59. return jbit_error_(set);
  60. }
  61. /**
  62. * jbit_test - test a bit in the bitset.
  63. * @set: bitset from jbit_new
  64. * @index: the index to test
  65. *
  66. * Returns true if jbit_set() has been done on this index, false otherwise.
  67. *
  68. * Example:
  69. * assert(!jbit_test(set, 0));
  70. */
  71. static inline bool jbit_test(const struct jbitset *set, size_t index)
  72. {
  73. return Judy1Test(set->judy, index, (JError_t *)&set->err);
  74. }
  75. /**
  76. * jbit_set - set a bit in the bitset.
  77. * @set: bitset from jbit_new
  78. * @index: the index to set
  79. *
  80. * Returns false if it was already set (ie. nothing changed)
  81. *
  82. * Example:
  83. * if (jbit_set(set, 0))
  84. * err(1, "Bit 0 was already set?!");
  85. */
  86. static inline bool jbit_set(struct jbitset *set, size_t index)
  87. {
  88. return Judy1Set(&set->judy, index, &set->err);
  89. }
  90. /**
  91. * jbit_clear - clear a bit in the bitset.
  92. * @set: bitset from jbit_new
  93. * @index: the index to set
  94. *
  95. * Returns the old bit value (ie. false if nothing changed).
  96. *
  97. * Example:
  98. * if (jbit_clear(set, 0))
  99. * err(1, "Bit 0 was already clear?!");
  100. */
  101. static inline bool jbit_clear(struct jbitset *set, size_t index)
  102. {
  103. return Judy1Unset(&set->judy, index, &set->err);
  104. }
  105. /**
  106. * jbit_popcount - get population of (some part of) bitset.
  107. * @set: bitset from jbit_new
  108. * @start: first index to count
  109. * @end_incl: last index to count (use -1 for end).
  110. *
  111. * Example:
  112. * assert(jbit_popcount(set, 0, 1000) <= jbit_popcount(set, 0, 2000));
  113. */
  114. static inline size_t jbit_popcount(const struct jbitset *set,
  115. size_t start, size_t end_incl)
  116. {
  117. return Judy1Count(set->judy, start, end_incl, (JError_t *)&set->err);
  118. }
  119. /**
  120. * jbit_nth - return the index of the nth bit which is set.
  121. * @set: bitset from jbit_new
  122. * @n: which bit we are interested in (0-based)
  123. * @invalid: what to return if n >= set population
  124. *
  125. * This normally returns the nth bit in the set, and often there is a
  126. * convenient known-invalid value (ie. something which is never in the
  127. * set). Otherwise, and a wrapper function like this can be used:
  128. *
  129. * static bool jbit_nth_index(struct jbitset *set, size_t n, size_t *idx)
  130. * {
  131. * // Zero might be valid, if it's first in set.
  132. * if (n == 0 && jbit_test(set, 0)) {
  133. * *idx = 0;
  134. * return true;
  135. * }
  136. * *idx = jbit_nth(set, n, 0);
  137. * return (*idx != 0);
  138. * }
  139. *
  140. * Example:
  141. * size_t i, val;
  142. *
  143. * // We know 0 isn't in set.
  144. * assert(!jbit_test(set, 0));
  145. * for (i = 0; (val = jbit_nth(set, i, 0)) != 0; i++) {
  146. * assert(jbit_popcount(set, 0, val) == i);
  147. * printf("Value %zu = %zu\n", i, val);
  148. * }
  149. */
  150. static inline size_t jbit_nth(const struct jbitset *set,
  151. size_t n, size_t invalid)
  152. {
  153. Word_t index;
  154. if (!Judy1ByCount(set->judy, n+1, &index, (JError_t *)&set->err))
  155. index = invalid;
  156. return index;
  157. }
  158. /**
  159. * jbit_first - return the first bit which is set.
  160. * @set: bitset from jbit_new
  161. * @invalid: return value if no bits are set at all.
  162. *
  163. * This is equivalent to jbit_nth(set, 0, invalid).
  164. *
  165. * Example:
  166. * assert(!jbit_test(set, 0));
  167. * printf("Set contents (increasing order):");
  168. * for (i = jbit_first(set, 0); i; i = jbit_next(set, i, 0))
  169. * printf(" %zu", i);
  170. * printf("\n");
  171. */
  172. static inline size_t jbit_first(const struct jbitset *set, size_t invalid)
  173. {
  174. Word_t index = 0;
  175. if (!Judy1First(set->judy, &index, (JError_t *)&set->err))
  176. index = invalid;
  177. else
  178. assert(index != invalid);
  179. return index;
  180. }
  181. /**
  182. * jbit_next - return the next bit which is set.
  183. * @set: bitset from jbit_new
  184. * @prev: previous index
  185. * @invalid: return value if no bits are set at all.
  186. *
  187. * This is usually used to find an adjacent bit which is set, after
  188. * jbit_first.
  189. */
  190. static inline size_t jbit_next(const struct jbitset *set, size_t prev,
  191. size_t invalid)
  192. {
  193. if (!Judy1Next(set->judy, (Word_t *)&prev, (JError_t *)&set->err))
  194. prev = invalid;
  195. else
  196. assert(prev != invalid);
  197. return prev;
  198. }
  199. /**
  200. * jbit_last - return the last bit which is set.
  201. * @set: bitset from jbit_new
  202. * @invalid: return value if no bits are set at all.
  203. *
  204. * Example:
  205. * assert(!jbit_test(set, 0));
  206. * printf("Set contents (decreasing order):");
  207. * for (i = jbit_last(set, 0); i; i = jbit_prev(set, i, 0))
  208. * printf(" %zu", i);
  209. * printf("\n");
  210. */
  211. static inline size_t jbit_last(const struct jbitset *set, size_t invalid)
  212. {
  213. Word_t index = -1;
  214. if (!Judy1Last(set->judy, &index, (JError_t *)&set->err))
  215. index = invalid;
  216. else
  217. assert(index != invalid);
  218. return index;
  219. }
  220. /**
  221. * jbit_prev - return the previous bit which is set.
  222. * @set: bitset from jbit_new
  223. * @prev: previous index
  224. * @invalid: return value if no bits are set at all.
  225. *
  226. * This is usually used to find an adjacent bit which is set, after
  227. * jbit_last.
  228. */
  229. static inline size_t jbit_prev(const struct jbitset *set, size_t prev,
  230. size_t invalid)
  231. {
  232. if (!Judy1Prev(set->judy, (Word_t *)&prev, (JError_t *)&set->err))
  233. prev = invalid;
  234. else
  235. assert(prev != invalid);
  236. return prev;
  237. }
  238. /**
  239. * jbit_first_clear - return the first bit which is unset.
  240. * @set: bitset from jbit_new
  241. * @invalid: return value if no bits are clear at all.
  242. *
  243. * This allows for iterating the inverse of the bitmap.
  244. */
  245. static inline size_t jbit_first_clear(const struct jbitset *set,
  246. size_t invalid)
  247. {
  248. Word_t index = 0;
  249. if (!Judy1FirstEmpty(set->judy, &index, (JError_t *)&set->err))
  250. index = invalid;
  251. else
  252. assert(index != invalid);
  253. return index;
  254. }
  255. static inline size_t jbit_next_clear(const struct jbitset *set, size_t prev,
  256. size_t invalid)
  257. {
  258. if (!Judy1NextEmpty(set->judy, (Word_t *)&prev, (JError_t *)&set->err))
  259. prev = invalid;
  260. else
  261. assert(prev != invalid);
  262. return prev;
  263. }
  264. static inline size_t jbit_last_clear(const struct jbitset *set, size_t invalid)
  265. {
  266. Word_t index = -1;
  267. if (!Judy1LastEmpty(set->judy, &index, (JError_t *)&set->err))
  268. index = invalid;
  269. else
  270. assert(index != invalid);
  271. return index;
  272. }
  273. static inline size_t jbit_prev_clear(const struct jbitset *set, size_t prev,
  274. size_t invalid)
  275. {
  276. if (!Judy1PrevEmpty(set->judy, (Word_t *)&prev, (JError_t *)&set->err))
  277. prev = invalid;
  278. else
  279. assert(prev != invalid);
  280. return prev;
  281. }
  282. #endif /* CCAN_JBITSET_H */