bitvec.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /*
  2. *
  3. * Copyright (c) 2011, Jue Ruan <ruanjue@gmail.com>
  4. *
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef __BIT_VEC_RJ_H
  20. #define __BIT_VEC_RJ_H
  21. #include <stdio.h>
  22. #include <stdint.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include "mem_share.h"
  26. static const u1i byte_ones_table[256] = {
  27. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
  28. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  29. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  30. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  31. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  32. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  33. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  34. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  35. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  36. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  37. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  38. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  39. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  40. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  41. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  42. 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
  43. };
  44. static inline unsigned int _bitvec_roundup_power2(unsigned int v){
  45. if(v == 0) return 0;
  46. v--;
  47. v |= v >> 1;
  48. v |= v >> 2;
  49. v |= v >> 4;
  50. v |= v >> 8;
  51. v |= v >> 16;
  52. return v + 1;
  53. }
  54. typedef struct {
  55. u8i *bits;
  56. u8i n_bit;
  57. u8i n_cap;
  58. u8i *sums;
  59. u8i sum_size;
  60. u8i n_ones;
  61. u8i *hash;
  62. u8i hash_size;
  63. u8i hash_mod;
  64. int64_t iter_idx;
  65. } BitVec;
  66. #if 0
  67. static inline u4i count_ones_bit32(u4i v){
  68. v = v - ((v >> 1) & 0x55555555U); // reuse input as temporary
  69. v = (v & 0x33333333U) + ((v >> 2) & 0x33333333U); // temp
  70. return (((v + (v >> 4)) & 0xF0F0F0FU) * 0x1010101U) >> 24; // count
  71. }
  72. #define ONES_STEP_4 0x1111111111111111ULL
  73. #define ONES_STEP_8 0x0101010101010101ULL
  74. static inline int count_ones_bit64(const u8i x){
  75. register u8i byte_sums = x - ((x & 0xa * ONES_STEP_4) >> 1);
  76. byte_sums = (byte_sums & 3 * ONES_STEP_4) + ((byte_sums >> 2) & 3 * ONES_STEP_4);
  77. byte_sums = (byte_sums + (byte_sums >> 4)) & 0x0f * ONES_STEP_8;
  78. return byte_sums * ONES_STEP_8 >> 56;
  79. }
  80. #else
  81. #define count_ones_bit32(v) __builtin_popcount(v)
  82. #define count_ones_bit64(v) __builtin_popcountll(v)
  83. #endif
  84. #define reverse_u1i(v) (((((u1i)v) * 0x0202020202ULL) & 0x010884422010ULL) % 1023)
  85. static inline size_t bitvec_obj_desc_cnt(void *bitv, int idx){
  86. switch(idx){
  87. case 0: return ((BitVec*)bitv)->n_cap / 64 * 8;
  88. case 1: return ((BitVec*)bitv)->sums? (((BitVec*)bitv)->sum_size * 2 + 1) * 8 : 0;
  89. case 2: return ((BitVec*)bitv)->hash? (((BitVec*)bitv)->hash_size) * 8 : 0;
  90. default: return 0;
  91. }
  92. }
  93. static const obj_desc_t bitvec_obj_desc = {"bitvec_obj_desc", sizeof(BitVec), 3, {1, 1, 1}, {offsetof(BitVec, bits), offsetof(BitVec, sums), offsetof(BitVec, hash)}, {(obj_desc_t*)&OBJ_DESC_DATA, (obj_desc_t*)&OBJ_DESC_DATA, (obj_desc_t*)&OBJ_DESC_DATA}, bitvec_obj_desc_cnt, NULL};
  94. static inline BitVec* init_bitvec(u8i n_bit){
  95. BitVec *bitv;
  96. if(n_bit == 0) n_bit = 64 * 8;
  97. bitv = (BitVec*)malloc(sizeof(BitVec));
  98. bitv->n_bit = 0;
  99. bitv->n_cap = (((n_bit + 63) / 64) + 7) / 8 * 64 * 8;
  100. bitv->bits = (u8i*)calloc((bitv->n_cap / 64) + 1, 8);
  101. bitv->bits[bitv->n_cap / 64] = 0x0000000000000001LLU;
  102. //memset(bitv->bits, 0, bitv->n_cap / 8);
  103. bitv->sums = NULL;
  104. bitv->hash = NULL;
  105. bitv->sum_size = 0;
  106. bitv->n_ones = 0;
  107. bitv->hash_size = 0;
  108. bitv->hash_mod = 0;
  109. bitv->iter_idx = 0;
  110. return bitv;
  111. }
  112. static inline size_t dump_bitvec(BitVec *bitv, FILE *out){
  113. fwrite(&bitv->n_bit, sizeof(u8i), 1, out);
  114. fwrite(&bitv->n_cap, sizeof(u8i), 1, out);
  115. fwrite(bitv->bits, sizeof(u8i), bitv->n_cap / 64, out);
  116. return sizeof(u8i) * (2 + bitv->n_cap / 64);
  117. }
  118. static inline BitVec* load_bitvec(FILE *inp){
  119. BitVec *bitv;
  120. size_t n;
  121. bitv = (BitVec*)malloc(sizeof(BitVec));
  122. if((n = fread(&bitv->n_bit, sizeof(u8i), 1, inp)) != 1){
  123. free(bitv); return NULL;
  124. }
  125. if((n = fread(&bitv->n_cap, sizeof(u8i), 1, inp)) != 1){
  126. free(bitv); return NULL;
  127. }
  128. bitv->bits = (u8i*)malloc(bitv->n_cap / 8);
  129. if(bitv->bits == NULL){
  130. fprintf(stderr, " Out of memeory in load_bitvec\n "); fflush(stderr); exit(1);
  131. }
  132. if((n = fread(bitv->bits, sizeof(u8i), bitv->n_cap / 64, inp)) != bitv->n_cap / 64){
  133. free(bitv); free(bitv->bits); return NULL;
  134. }
  135. bitv->sums = NULL;
  136. bitv->hash = NULL;
  137. bitv->hash_size = 0;
  138. return bitv;
  139. }
  140. #if 0
  141. static inline BitVec* mem_load_bitvec(void *mem, FILE *inp){
  142. BitVec *bitv;
  143. size_t off, n;
  144. bitv = mem;
  145. off = ((sizeof(BitVec) + 7) / 8) * 8;
  146. if((n = fread(&bitv->n_bit, sizeof(u8i), 1, inp)) != 1) return NULL;
  147. if((n = fread(&bitv->n_cap, sizeof(u8i), 1, inp)) != 1) return NULL;
  148. bitv->sums = NULL;
  149. bitv->hash = NULL;
  150. bitv->hash_size = 0;
  151. bitv->bits = mem + off;
  152. off += (bitv->n_cap / 64) * 8;
  153. if((n = fread(bitv->bits, sizeof(u8i), bitv->n_cap / 64, inp)) != bitv->n_cap / 64) return NULL;
  154. return bitv;
  155. }
  156. #endif
  157. static inline void clear_bitvec(BitVec *bitv){ bitv->n_bit = 0; }
  158. static inline void zeros_bitvec(BitVec *bitv){ memset(bitv->bits, 0, bitv->n_cap / 8); }
  159. // exclusive end
  160. static inline void reg_zeros_bitvec(BitVec *bitv, u8i beg, u8i end){
  161. u8i b, e;
  162. if(beg >= end) return;
  163. b = beg >> 6;
  164. e = end >> 6;
  165. if(b == e){
  166. bitv->bits[b] &= (MAX_U8 << (beg & 0x3FU)) ^ (MAX_U8 >> (64 - (end & 0x3FU)));
  167. } else {
  168. bitv->bits[b] &= ~(MAX_U8 << (beg & 0x3FU));
  169. while(++b < e){ bitv->bits[b] = 0; }
  170. bitv->bits[b] &= MAX_U8 << (end & 0x3FU);
  171. }
  172. }
  173. static inline void ones_bitvec(BitVec *bitv){ memset(bitv->bits, 0xFFU, bitv->n_cap / 8); }
  174. // exclusive end
  175. static inline void reg_ones_bitvec(BitVec *bitv, u8i beg, u8i end){
  176. u8i b, e;
  177. if(beg >= end) return;
  178. b = beg >> 6;
  179. e = end >> 6;
  180. if(b == e){
  181. bitv->bits[b] |= (MAX_U8 << (beg & 0x3FU)) & (MAX_U8 >> (64 - (end & 0x3FU)));
  182. } else {
  183. bitv->bits[b] |= MAX_U8 << (beg & 0x3FU);
  184. while(++b < e){ bitv->bits[b] = MAX_U8; }
  185. bitv->bits[b] |= ~(MAX_U8 << (end & 0x3FU));
  186. }
  187. }
  188. static inline void flip_bitvec(BitVec *bitv, u8i idx){ bitv->bits[idx>>6] ^= 1LLU << (idx&0x3FU); }
  189. static inline void one_bitvec(BitVec *bitv, u8i idx){ bitv->bits[idx>>6] |= 1LLU << (idx&0x3FU); }
  190. static inline void zero_bitvec(BitVec *bitv, u8i idx){ bitv->bits[idx>>6] &= ~(1LLU << (idx&0x3FU)); }
  191. static inline void set_bitvec(BitVec *bitv, u8i idx, int v){
  192. if(v){
  193. one_bitvec(bitv, idx);
  194. } else {
  195. zero_bitvec(bitv, idx);
  196. }
  197. }
  198. static inline u8i get_bitvec(BitVec *bitv, u8i idx){ return (bitv->bits[idx>>6] >> (idx&0x3FU)) & 0x01LLU; }
  199. static inline u8i get64_bitvec(BitVec *bitv, u8i off){
  200. u8i m, n;
  201. m = off >> 6;
  202. n = off & 0x3F;
  203. if(n){
  204. return (bitv->bits[m] >> (64 - n)) | (bitv->bits[m + 1] << n);
  205. } else {
  206. return bitv->bits[m];
  207. }
  208. }
  209. static inline void set64_bitvec(BitVec *bitv, u8i off, u8i val){
  210. u8i m, n;
  211. m = off >> 6;
  212. n = off & 0x3F;
  213. if(n){
  214. bitv->bits[m] = ((bitv->bits[m] << (64 - n)) >> (64 - n)) | (val << (64 - n));
  215. m ++;
  216. bitv->bits[m] = ((bitv->bits[m] >> n) << n) | (val >> (64 - n));
  217. } else {
  218. bitv->bits[m] = val;
  219. }
  220. }
  221. static inline void encap_bitvec(BitVec *bitv, u8i num){
  222. u8i cap;
  223. if(bitv->n_bit + num < bitv->n_cap) return;
  224. cap = bitv->n_cap;
  225. while(bitv->n_bit + num >= bitv->n_cap){
  226. if(bitv->n_cap < 1024 * 1024 * 8){
  227. bitv->n_cap <<= 1;
  228. } else bitv->n_cap += 1024 * 1024 * 8;
  229. }
  230. bitv->bits = (u8i*)realloc(bitv->bits, bitv->n_cap / 8 + 8);
  231. memset(((void*)bitv->bits) + cap / 8, 0, (bitv->n_cap - cap) / 8 + 8);
  232. bitv->bits[cap / 64] = 0x0000000000000001LLU;
  233. }
  234. static inline void recap_bitvec(BitVec *bitv, u8i new_cap){
  235. if(new_cap & 0x3FU) new_cap = (new_cap & 0xFFFFFFFFFFFFFFC0LLU) + 0x40U;
  236. if(bitv->n_cap == new_cap) return;
  237. bitv->bits = (u8i*)realloc(bitv->bits, new_cap / 8 + 8);
  238. if(new_cap > bitv->n_cap){
  239. memset(((void*)bitv->bits) + bitv->n_cap / 8, 0, (new_cap - bitv->n_cap) / 8 + 8);
  240. }
  241. bitv->bits[new_cap / 64] = 0x0000000000000001LLU;
  242. bitv->n_cap = new_cap;
  243. }
  244. static inline void one2bitvec(BitVec *bitv){ encap_bitvec(bitv, 1); one_bitvec(bitv, bitv->n_bit); bitv->n_bit ++; }
  245. static inline void zero2bitvec(BitVec *bitv){ encap_bitvec(bitv, 1); zero_bitvec(bitv, bitv->n_bit); bitv->n_bit ++; }
  246. static inline u8i get_2bitvec(BitVec *bitv, u8i idx){ return (bitv->bits[idx>>5] >> ((idx&0x1FU) << 1)) & 0x03LLU; }
  247. static inline void set_2bitvec(BitVec *bitv, u8i idx, u8i v){
  248. bitv->bits[idx>>5] = (bitv->bits[idx>>5] & (~(0x03LLU << ((idx&0x1FU) << 1)))) | ((v&0x03LLU) << ((idx&0x1FU) << 1));
  249. }
  250. static inline void push_2bitvec(BitVec *bitv, u8i v){
  251. encap_bitvec(bitv, 2);
  252. set_2bitvec(bitv, bitv->n_bit >> 1, v);
  253. bitv->n_bit = ((bitv->n_bit >> 1) + 1) << 1;
  254. }
  255. static inline void end_bitvec(BitVec *bitv){ encap_bitvec(bitv, 1); one_bitvec(bitv, bitv->n_bit); }
  256. static inline u8i next_one_bitvec(BitVec *bitv, u8i idx){
  257. register u8i p, v;
  258. register u4i s;
  259. p = idx >> 6;
  260. s = idx & 0x3F;
  261. while(!(bitv->bits[p] >> s)){ p ++; s = 0; }
  262. v = bitv->bits[p] >> s;
  263. s += __builtin_ctzll(v);
  264. return (p << 6) + s;
  265. }
  266. static inline u8i reg_count_bitvec(BitVec *bitv, u8i beg, u8i end){
  267. u8i cnt, b, e, t;
  268. if(beg >= end) return 0;
  269. b = beg >> 6;
  270. e = end >> 6;
  271. if(b == e){
  272. t = (bitv->bits[b] & (MAX_U8 >> (64 - (end & 0x3F)))) >> (beg & 0x3F);
  273. cnt = count_ones_bit64(t);
  274. } else {
  275. cnt = count_ones_bit64(bitv->bits[b] >> (beg & 0x3F));
  276. while(++b < e){
  277. cnt += count_ones_bit64(bitv->bits[b]);
  278. }
  279. if(end & 0x3F){
  280. cnt += count_ones_bit64(bitv->bits[b] & (MAX_U8 >> (64 - (end & 0x3F))));
  281. }
  282. }
  283. return cnt;
  284. }
  285. static const int Mod37BitPosition[] = // map a bit value mod 37 to its position
  286. {
  287. 32, 0, 1, 26, 2, 23, 27, 0, 3, 16,
  288. 24, 30, 28, 11, 0, 13, 4, 7, 17, 0,
  289. 25, 22, 31, 15, 29, 10, 12, 6, 0, 21,
  290. 14, 9, 5, 20, 8, 19, 18
  291. };
  292. static inline u8i next_one_bitvec2(BitVec *bitv, u8i idx){
  293. register u8i p;
  294. register u4i s, v;
  295. p = idx >> 6;
  296. s = idx & 0x3F;
  297. while(!(bitv->bits[p] >> s)){ p ++; s = 0; }
  298. if(!((bitv->bits[p] >> s) & 0xFFFFFFFFU)) s += 32;
  299. v = bitv->bits[p] >> s;
  300. s += Mod37BitPosition[(-v & v) % 37];
  301. return (p << 6) + s;
  302. }
  303. static inline u8i next_one_bitvec3(BitVec *bitv, u8i idx){
  304. register u8i p;
  305. register u4i s;
  306. p = idx >> 6;
  307. s = idx & 0x3F;
  308. while(!(bitv->bits[p] >> s)){ p ++; s = 0; }
  309. while(!((bitv->bits[p] >> s) & 0xFFU)) s += 8;
  310. while(!((bitv->bits[p] >> s) & 0x01U)) s ++;
  311. return (p << 6) + s;
  312. }
  313. //n_cap MUST be times of 64 * 8
  314. static inline void index_bitvec_core(BitVec *bitv, size_t n_cap){
  315. u8i i, k, s, t, m;
  316. m = ((n_cap + 63) / 64 + 7) / 8;
  317. if(bitv->sums) free(bitv->sums);
  318. bitv->sums = (u8i*)calloc((m * 2 + 1), 8);
  319. t = 0;
  320. for(i=0;i<n_cap;i+=64*8){
  321. k = ((i>>6) >> 3) << 1;
  322. bitv->sums[k] = t;
  323. s = 0;
  324. s += count_ones_bit64(bitv->bits[(i>>6)+0]);
  325. bitv->sums[k+1] |= s << 0;
  326. s += count_ones_bit64(bitv->bits[(i>>6)+1]);
  327. bitv->sums[k+1] |= s << 9;
  328. s += count_ones_bit64(bitv->bits[(i>>6)+2]);
  329. bitv->sums[k+1] |= s << 18;
  330. s += count_ones_bit64(bitv->bits[(i>>6)+3]);
  331. bitv->sums[k+1] |= s << 27;
  332. s += count_ones_bit64(bitv->bits[(i>>6)+4]);
  333. bitv->sums[k+1] |= s << 36;
  334. s += count_ones_bit64(bitv->bits[(i>>6)+5]);
  335. bitv->sums[k+1] |= s << 45;
  336. s += count_ones_bit64(bitv->bits[(i>>6)+6]);
  337. bitv->sums[k+1] |= s << 54;
  338. s += count_ones_bit64(bitv->bits[(i>>6)+7]);
  339. t += s;
  340. }
  341. bitv->sums[((i>>6) >> 3) << 1] = t;
  342. bitv->n_ones = t;
  343. bitv->sum_size = m;
  344. bitv->hash_size = (n_cap / 64 / 8) / 2;
  345. if(bitv->hash_size == 0) bitv->hash_size = 1;
  346. bitv->hash_mod = (t + bitv->hash_size) / bitv->hash_size;
  347. if(bitv->hash_mod == 0) bitv->hash_mod = 1;
  348. if(bitv->hash) free(bitv->hash);
  349. bitv->hash = (u8i*)malloc(sizeof(u8i) * bitv->hash_size);
  350. s = 0;
  351. t = 0;
  352. for(i=0;i<=m;i++){
  353. k = bitv->sums[i*2] / bitv->hash_mod;
  354. if(s < k){
  355. while(s < k){ bitv->hash[s] = t; s ++; }
  356. t = i? i - 1 : 0;
  357. }
  358. }
  359. bitv->hash[bitv->sums[m*2] / bitv->hash_mod] = t;
  360. }
  361. static inline void index_bitvec(BitVec *bitv){
  362. index_bitvec_core(bitv, bitv->n_cap);
  363. }
  364. static inline u8i rank_bitvec(BitVec *bitv, u8i idx){
  365. u8i p, s, sum;
  366. p = (idx>>6)>>3;
  367. s = (idx >> 6) & 0x07U;
  368. sum = bitv->sums[p<<1];
  369. if(s) sum += (bitv->sums[(p<<1)+1] >> (9 * (s - 1))) & 0x1FFU;
  370. if(idx & 0x3FU) sum += count_ones_bit64(bitv->bits[idx>>6]<<(64-(idx&0x3FU)));
  371. return sum;
  372. }
  373. static inline u1i select_8bytes(u8i word, u1i n_one){
  374. u1i idx, n, m;
  375. n = count_ones_bit32((u4i)word);
  376. if(n >= n_one){
  377. n = 0;
  378. idx = 0;
  379. word = word & 0xFFFFFFFFU;
  380. } else {
  381. idx = 32;
  382. word = word >> 32;
  383. }
  384. while(1){
  385. m = byte_ones_table[(u1i)word];
  386. if(n + m >= n_one) break;
  387. n += m;
  388. idx += 8;
  389. word >>= 8;
  390. }
  391. m = byte_ones_table[(u1i)(word & 0xF)];
  392. if(n + m < n_one){
  393. idx += 4;
  394. word >>= 4;
  395. n += m;
  396. }
  397. while(word){
  398. idx ++;
  399. if(word & 0x01){
  400. n ++;
  401. if(n == n_one) break;
  402. }
  403. word >>= 1;
  404. }
  405. return idx;
  406. }
  407. /*
  408. * To select the 1'st one, use select_bitvec(bitv, 1) - 1
  409. * */
  410. static inline u8i select_bitvec(BitVec *bitv, u8i idx){
  411. u8i i, p, s, sum, t;
  412. p = bitv->hash[idx / bitv->hash_mod];
  413. while(p + 1 < bitv->sum_size && bitv->sums[(p + 1) << 1] < idx) p ++;
  414. sum = bitv->sums[p << 1];
  415. i = 0;
  416. t = sum;
  417. while(i < 7){
  418. s = (bitv->sums[(p << 1) + 1] >> (9 * i)) & 0x1FFU;
  419. if(sum + s >= idx) break;
  420. t = sum + s;
  421. i ++;
  422. }
  423. p = p * 8 + i;
  424. s = idx - t;
  425. return p * 64 + select_8bytes(bitv->bits[p], s);
  426. }
  427. static inline void begin_iter_bitvec(BitVec *bitv){ bitv->iter_idx = -1; }
  428. static inline u8i iter_bitvec(BitVec *bitv){
  429. if((u8i)(bitv->iter_idx + 1) > bitv->n_cap) return 0xFFFFFFFFFFFFFFFFLLU;
  430. bitv->iter_idx = next_one_bitvec(bitv, bitv->iter_idx + 1);
  431. return (u8i)bitv->iter_idx;
  432. }
  433. static inline void free_bitvec(BitVec *bitv){
  434. free(bitv->bits);
  435. if(bitv->sums) free(bitv->sums);
  436. if(bitv->hash) free(bitv->hash);
  437. free(bitv);
  438. }
  439. #if 0
  440. static inline size_t mem_size_bitvec(BitVec *bitv){
  441. size_t m;
  442. m = (sizeof(BitVec) + 7) / 8 * 8 + ((bitv->n_cap / 64) * 8);
  443. if(bitv->sums){
  444. m += (bitv->sum_size * 2 + 1) * 8;
  445. }
  446. if(bitv->hash){
  447. m += bitv->hash_size * 8;
  448. }
  449. return m;
  450. }
  451. static inline size_t mem_dump_bitvec(BitVec *bitv, void *mem){
  452. BitVec *clone;
  453. size_t off;
  454. clone = mem;
  455. memcpy(clone, bitv, sizeof(BitVec));
  456. off = ((sizeof(BitVec) + 7) / 8) * 8;
  457. clone->bits = mem + off;
  458. memcpy(clone->bits, bitv->bits, (bitv->n_cap / 64) * 8);
  459. off += (bitv->n_cap / 64) * 8;
  460. if(bitv->sums){
  461. clone->sums = mem + off;
  462. memcpy(clone->sums, bitv->sums, (bitv->sum_size * 2 + 1) * 8);
  463. off += (bitv->sum_size * 2 + 1) * 8;
  464. }
  465. if(bitv->hash){
  466. clone->hash = mem + off;
  467. memcpy(clone->hash, bitv->hash, bitv->hash_size * 8);
  468. off += bitv->hash_size * 8;
  469. }
  470. return off;
  471. }
  472. #endif
  473. #endif