bitsvec.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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 __BITS_VEC_RJ_H
  20. #define __BITS_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. /* Useful functions when n_bit > 8 */
  27. static inline void u8byte2bits(uint64_t val, uint8_t *dat, uint64_t offset, uint8_t size){
  28. uint8_t i, *v;
  29. v = (uint8_t*)&val;
  30. #if __BYTE_ORDER == 1234
  31. for(i=0;i<size;i++){
  32. if(v[i >> 3] & (1U << (i & 0x7U))) dat[offset >> 3] |= 1U << (offset & 0x7U);
  33. else dat[offset >> 3] &= ~(1U << (offset & 0x7U));
  34. offset ++;
  35. }
  36. #else
  37. for(i=0;i<size;i++){
  38. if(v[7 - (i >> 3)] & (1U << (i & 0x7U))) dat[offset >> 3] |= 1U << (offset & 0x7U);
  39. else dat[offset >> 3] &= ~(1U << (offset & 0x7U));
  40. offset ++;
  41. }
  42. #endif
  43. }
  44. static inline uint64_t bits2u8byte(uint8_t *dat, uint64_t offset, uint8_t size){
  45. uint64_t ret;
  46. uint8_t i, *v;
  47. ret = 0;
  48. v = (uint8_t*)&ret;
  49. #if __BYTE_ORDER == 1234
  50. for(i=0;i<size;i++){
  51. if(dat[offset >> 3] & (1U << (offset & 0x7U))) v[i >> 3] |= 1U << (i & 0x7U);
  52. offset ++;
  53. }
  54. #else
  55. for(i=0;i<size;i++){
  56. if(dat[offset >> 3] & (1U << (offset & 0x7U))) v[7 - (i >> 3)] |= 1U << (i & 0x7U);
  57. offset ++;
  58. }
  59. #endif
  60. return ret;
  61. }
  62. typedef struct {
  63. uint8_t *bits;
  64. uint64_t size;
  65. uint64_t cap;
  66. uint8_t n_bit;
  67. uint32_t mask;
  68. } BitsVec;
  69. static inline BitsVec* init_bitsvec(uint64_t size, uint32_t n_bit){
  70. BitsVec *vec;
  71. if(n_bit == 0) n_bit = 1;
  72. else if(n_bit > 8) n_bit = 8;
  73. if(size < 8) size = 8;
  74. vec = calloc(1, sizeof(BitsVec));
  75. vec->n_bit = n_bit;
  76. vec->mask = (1U << n_bit) - 1U;
  77. vec->size = 0;
  78. vec->cap = size;
  79. vec->bits = calloc((size * vec->n_bit + 15) / 8, 1);
  80. return vec;
  81. }
  82. static inline size_t bitsvec_obj_desc_cnt(void *obj, int idx){
  83. return (((BitsVec*)obj)->cap * ((BitsVec*)obj)->n_bit + 15) / 8;
  84. idx = idx;
  85. }
  86. static const obj_desc_t bitsvec_obj_desc = {"bitsvec_obj_desc", sizeof(BitsVec), 1, {1}, {offsetof(BitsVec, bits)}, {(obj_desc_t*)&OBJ_DESC_DATA}, bitsvec_obj_desc_cnt, NULL};
  87. static inline void clear_bitsvec(BitsVec *vec){
  88. vec->size = 0;
  89. }
  90. static inline void free_bitsvec(BitsVec *vec){
  91. free(vec->bits);
  92. free(vec);
  93. }
  94. static inline int encap_bitsvec(BitsVec *vec, u8i n){
  95. if(vec->size + n <= vec->cap) return 0;
  96. if(vec->size + n < 0x3FFFFFFFLLU){
  97. vec->cap = roundup_power2(vec->size + n);
  98. } else {
  99. vec->cap = (vec->size + n + 0x3FFFFFFFLLU) & (MAX_U8 << 30);
  100. }
  101. vec->bits = realloc(vec->bits, (vec->cap * vec->n_bit + 15) / 8);
  102. return 1;
  103. }
  104. static inline void set_bitsvec(BitsVec *vec, u8i idx, u1i dat){
  105. register u8i off;
  106. register u2i x, d;
  107. off = (idx * vec->n_bit);
  108. d = off & 0x07;
  109. off >>= 3;
  110. x = (((u2i)vec->bits[off + 1]) << 8) | vec->bits[off + 0];
  111. x = (x & (~(vec->mask << d))) | ((UInt(dat) & vec->mask) << d);
  112. vec->bits[off] = x;
  113. vec->bits[off + 1] = x >> 8;
  114. }
  115. static inline void push_bitsvec(BitsVec *vec, u1i dat){
  116. encap_bitsvec(vec, 1);
  117. set_bitsvec(vec, vec->size, dat);
  118. vec->size ++;
  119. }
  120. // TODO: need to be optimized
  121. static inline void pushs_bitsvec(BitsVec *vec, u1i dat, u8i len){
  122. u8i i;
  123. encap_bitsvec(vec, len);
  124. for(i=0;i<len;i++){
  125. set_bitsvec(vec, vec->size + i, dat);
  126. }
  127. vec->size += len;
  128. }
  129. static inline u2i gets_bitsvec(BitsVec *vec, u8i idx){
  130. u8i off;
  131. off = (idx * vec->n_bit);
  132. return ((((u2i)vec->bits[(off >> 3) + 1]) << 8) | vec->bits[(off >> 3) + 0]) >> (off & 0x07);
  133. }
  134. static inline uint8_t get_bitsvec(BitsVec *vec, u8i idx){
  135. return gets_bitsvec(vec, idx) & vec->mask;
  136. }
  137. static inline void append_bitsvec(BitsVec *dst, BitsVec *src, u8i off, u8i len){
  138. u8i i, di, si, se;
  139. u2i x;
  140. u1i p, n, sd;
  141. if(0){ // Assume dst->n_bit == src->n_bit
  142. if(dst->n_bit != src->n_bit){
  143. fprintf(stderr, " -- something wrong in %s -- %s:%d --\n", __FUNCTION__, __FILE__, __LINE__); fflush(stderr);
  144. abort();
  145. }
  146. }
  147. encap_bitsvec(dst, len);
  148. p = (dst->n_bit & 0x01)? 8 : (8 / dst->n_bit);
  149. n = dst->size % p;
  150. if(n) n = p - n;
  151. if(len <= n){
  152. for(i=0;i<len;i++){
  153. set_bitsvec(dst, dst->size + i, get_bitsvec(src, off + i));
  154. }
  155. dst->size += len;
  156. return;
  157. } else {
  158. for(i=0;i<n;i++){
  159. set_bitsvec(dst, dst->size + i, get_bitsvec(src, off + i));
  160. }
  161. dst->size += n;
  162. }
  163. di = (dst->size * dst->n_bit) >> 3;
  164. si = ((off + i) * src->n_bit);
  165. sd = si & 0x07;
  166. si >>= 3;
  167. se = ((off + len) * src->n_bit + 7) >> 3;
  168. while(si < se){
  169. x = ((src->bits[si + 1] << 8) | src->bits[si]) >> sd;
  170. dst->bits[di++] = x;
  171. si ++;
  172. }
  173. dst->size += len - i;
  174. }
  175. static inline int pop_bitsvec(BitsVec *vec){
  176. if(vec->size == 0) return -1;
  177. vec->size --;
  178. return get_bitsvec(vec, vec->size);
  179. }
  180. #endif