Changeset ed4cf588b31c5ebb50b4d502802d243fec2cb338
- Timestamp:
- 04/30/08 12:45:38 (8 months ago)
- Parents:
- 3516e7ae3f4df445e780bee77b2a9a7f6ce7ddb8
- Children:
- 1c4d613e749d9e677b5d4a13214e93bfee485937
- git-committer:
- krayouva <krayouva@gmail.com> / 2008-04-29T22:45:38Z-0400
- Location:
- c
- Files:
-
- 3 modified
-
include/bitvector.h (modified) (8 diffs)
-
include/global.h (modified) (2 diffs)
-
src/bitvector.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
c/include/bitvector.h
rcb8a79 red4cf5 21 21 int capa; 22 22 23 /** count is the running count of bits set. This is kept up to date by 24 *frt_bv_set and frt_bv_unset. You can reset this value by calling frt_bv_recount */ 23 /** count is the running count of bits set. This is kept up to 24 * date by frt_bv_set and frt_bv_unset. You can reset this value 25 * by calling frt_bv_recount */ 25 26 int count; 26 27 … … 33 34 34 35 /** 35 * Create a new FrtBitVector with a capacity of +FRT_BV_INIT_CAPA+. Note that the 36 * FrtBitVector is growable and will adjust it's capacity when you use frt_bv_set. 36 * Create a new FrtBitVector with a capacity of 37 * +FRT_BV_INIT_CAPA+. Note that the FrtBitVector is growable and will 38 * adjust it's capacity when you use frt_bv_set. 37 39 * 38 40 * @return FrtBitVector with a capacity of +FRT_BV_INIT_CAPA+. 39 41 */ 40 extern FrtBitVector *frt_bv_new(); 41 42 /** 43 * Create a new FrtBitVector with a capacity of +capa+. Note that the FrtBitVector 44 * is growable and will adjust it's capacity when you use frt_bv_set. 42 extern FRT_ATTR_MALLOC 43 FrtBitVector *frt_bv_new(); 44 45 /** 46 * Create a new FrtBitVector with a capacity of +capa+. Note that the 47 * FrtBitVector is growable and will adjust it's capacity when you use 48 * frt_bv_set. 45 49 * 46 50 * @param capa the initial capacity of the FrtBitVector 47 51 * @return FrtBitVector with a capacity of +capa+. 48 52 */ 49 extern FrtBitVector *frt_bv_new_capa(int capa); 50 51 /** 52 * Destroy a FrtBitVector, freeing all memory allocated to that FrtBitVector 53 extern FRT_ATTR_MALLOC 54 FrtBitVector *frt_bv_new_capa(int capa); 55 56 /** 57 * Destroy a FrtBitVector, freeing all memory allocated to that 58 * FrtBitVector 53 59 * 54 60 * @param bv FrtBitVector to destroy … … 57 63 58 64 /** 59 * Set the bit at position +index+. If +index+ is outside of the range of the 60 * FrtBitVector, that is >= FrtBitVector.size, FrtBitVector.size will be set to +index+ 61 * + 1. If it is greater than the capacity of the FrtBitVector, the capacity will 62 * be expanded to accomodate. 65 * Set the bit at position +index+ with +value+. If +index+ is outside 66 * of the range of the FrtBitVector, that is >= FrtBitVector.size, 67 * FrtBitVector.size will be set to +index+ + 1. If it is greater than 68 * the capacity of the FrtBitVector, the capacity will be expanded to 69 * accomodate. 63 70 * 64 71 * @param bv the FrtBitVector to set the bit in 65 72 * @param index the index of the bit to set 66 */ 67 extern void frt_bv_set(FrtBitVector *bv, int index); 73 * @param value the boolean value 74 */ 75 76 /* 77 * FIXME: if the top set bit is unset, size is not adjusted. This will not 78 * cause any bugs in this code but could cause problems if users are relying 79 * on the fact that size is accurate. 80 */ 81 extern FRT_ATTR_ALWAYS_INLINE 82 void frt_bv_set_value(FrtBitVector *bv, int bit, bool value) 83 { 84 frt_u32 *word_p; 85 int word = bit >> 5; 86 frt_u32 bitmask = 1 << (bit & 31); 87 88 /* Check to see if we need to grow the BitVector */ 89 if (unlikely(bit >= bv->size)) { 90 bv->size = bit + 1; /* size is max range of bits set */ 91 if (word >= bv->capa) { 92 int capa = bv->capa << 1; 93 while (capa <= word) { 94 capa <<= 1; 95 } 96 FRT_REALLOC_N(bv->bits, frt_u32, capa); 97 memset(bv->bits + bv->capa, (bv->extends_as_ones ? 0xFF : 0), 98 sizeof(frt_u32) * (capa - bv->capa)); 99 bv->capa = capa; 100 } 101 } 102 103 /* Set the required bit */ 104 word_p = &(bv->bits[word]); 105 if ((!!(bitmask & *word_p)) != value) { 106 if (value) { 107 bv->count++; 108 *word_p |= bitmask; 109 } 110 else { 111 bv->count--; 112 *word_p &= ~bitmask; 113 } 114 } 115 } 116 117 /** 118 * Set the bit at position +index+. If +index+ is outside of the range 119 * of the FrtBitVector, that is >= FrtBitVector.size, 120 * FrtBitVector.size will be set to +index+ + 1. If it is greater than 121 * the capacity of the FrtBitVector, the capacity will be expanded to 122 * accomodate. 123 * 124 * @param bv the FrtBitVector to set the bit in 125 * @param index the index of the bit to set 126 */ 127 extern FRT_ATTR_ALWAYS_INLINE 128 void frt_bv_set(FrtBitVector *bv, int bit) 129 { 130 frt_bv_set_value(bv, bit, 1); 131 } 68 132 69 133 /** 70 134 * Unsafely set the bit at position +index+. If you choose to use this 71 * function you must create the FrtBitVector with a large enough capacity to 72 * accomodate all of the frt_bv_set_fast operations. You must also set bits in 73 * order and only one time per bit. Otherwise, use the safe frt_bv_set function. 135 * function you must create the FrtBitVector with a large enough 136 * capacity to accomodate all of the frt_bv_set_fast operations. You 137 * must also set bits in order and only one time per bit. Otherwise, 138 * use the safe frt_bv_set function. 74 139 * 75 140 * So this is ok; … … 93 158 * @param index the index of the bit to set 94 159 */ 95 extern FRT_INLINE void frt_bv_set_fast(FrtBitVector *bv, int bit); 96 97 /** 98 * Return 1 if the bit at +index+ was set or 0 otherwise. If +index+ is out of 99 * range, that is greater then the BitVectors capacity, it will also return 0. 160 extern FRT_ATTR_ALWAYS_INLINE 161 void frt_bv_set_fast(FrtBitVector *bv, int bit) 162 { 163 bv->count++; 164 bv->size = bit + 1; 165 bv->bits[bit >> 5] |= (1 << (bit & 31)); 166 } 167 168 /** 169 * Return 1 if the bit at +index+ was set or 0 otherwise. If +index+ 170 * is out of range, that is greater then the BitVectors capacity, it 171 * will also return 0. 100 172 * 101 173 * @param bv the FrtBitVector to check in … … 103 175 * @return 1 if the bit was set, 0 otherwise 104 176 */ 105 extern int frt_bv_get(FrtBitVector *bv, int index); 106 107 /** 108 * Unset the bit at position +index+. If the +index+ was out of range, that is 109 * greater than the BitVectors capacity then do nothing. (frt_bv_get will return 0 110 * in this case anyway). 177 extern FRT_ATTR_ALWAYS_INLINE 178 int frt_bv_get(FrtBitVector *bv, int bit) 179 { 180 /* out of range so return 0 because it can't have been set */ 181 if (unlikely(bit >= bv->size)) { 182 return bv->extends_as_ones; 183 } 184 return (bv->bits[bit >> 5] >> (bit & 31)) & 0x01; 185 } 186 187 /** 188 * Unset the bit at position +index+. If the +index+ was out of range, 189 * that is greater than the BitVectors capacity then do 190 * nothing. (frt_bv_get will return 0 in this case anyway). 111 191 * 112 192 * @param bv the FrtBitVector to unset the bit in 113 193 * @param index the index of the bit to unset 114 194 */ 115 extern void frt_bv_unset(FrtBitVector *bv, int bit); 195 extern FRT_ATTR_ALWAYS_INLINE 196 void frt_bv_unset(FrtBitVector *bv, int bit) 197 { 198 frt_bv_set_value(bv, bit, 0); 199 } 116 200 117 201 /** … … 123 207 124 208 /** 125 * Resets the set bit count by running through the whole FrtBitVector and 126 * counting all set bits. A running count of the bits is kept by frt_bv_set, 127 *frt_bv_get and frt_bv_set_fast so this function is only necessary if the count could 128 * have been corrupted somehow or if the FrtBitVector has been constructed in a 129 * different way (for example being read from the file_system). 209 * Resets the set bit count by running through the whole FrtBitVector 210 * and counting all set bits. A running count of the bits is kept by 211 * frt_bv_set, *frt_bv_get and frt_bv_set_fast so this function is 212 * only necessary if the count could have been corrupted somehow or if 213 * the FrtBitVector has been constructed in a different way (for 214 * example being read from the file_system). 130 215 * 131 216 * @param bv the FrtBitVector to count the bits in … … 136 221 137 222 /** 138 * Reset the FrtBitVector for scanning. This function should be called before 139 * using frt_bv_scan_next to scan through all set bits in the FrtBitVector. This is 140 * not necessary when using frt_bv_scan_next_from. 223 * Reset the FrtBitVector for scanning. This function should be called 224 * before using frt_bv_scan_next to scan through all set bits in the 225 * FrtBitVector. This is not necessary when using 226 * frt_bv_scan_next_from. 141 227 * 142 228 * @param bv the FrtBitVector to reset for scanning … … 145 231 146 232 /** 147 * Scan the FrtBitVector for the next set bit. Before using this function you 148 * should reset the FrtBitVector for scanning using +frt_bv_scan_reset+. You can the 149 * repeated call frt_bv_scan_next to get each set bit until it finally returns 150 * -1. 233 * Scan the FrtBitVector for the next set bit after +from+. If no more 234 * bits are set then return -1, otherwise return the index of teh next 235 * set bit. 236 * 237 * @param bv the FrtBitVector to scan 238 * @return the next set bit's index or -1 if no more bits are set 239 */ 240 extern FRT_ATTR_ALWAYS_INLINE 241 int frt_bv_scan_next_from(FrtBitVector *bv, const int bit) 242 { 243 frt_u32 pos = bit >> 5; 244 frt_u32 word = bv->bits[pos]; 245 246 if (bit >= bv->size) 247 return -1; 248 249 /* Keep only the bits above this position */ 250 word &= ~0 << (bit & 31); 251 if (word) 252 goto done; 253 254 for (pos++; pos < (frt_u32)bv->size; ++pos) 255 { 256 if ( (word = bv->bits[pos]) ) 257 goto done; 258 } 259 return -1; 260 done: 261 return bv->curr_bit = (pos << 5) + frt_count_trailing_zeros(word); 262 } 263 264 /** 265 * Scan the FrtBitVector for the next set bit. Before using this 266 * function you should reset the FrtBitVector for scanning using 267 * +frt_bv_scan_reset+. You can the repeatedly call frt_bv_scan_next 268 * to get each set bit until it finally returns -1. 151 269 * 152 270 * @param bv the FrtBitVector to scan 153 271 * @return the next set bits index or -1 if no more bits are set 154 272 */ 155 extern int frt_bv_scan_next(FrtBitVector *bv); 156 157 /** 158 * Scan the FrtBitVector for the next set bit after +from+. If no more bits are 159 * set then return -1, otherwise return the index of teh next set bit. 273 extern FRT_ATTR_ALWAYS_INLINE 274 int frt_bv_scan_next(FrtBitVector *bv) 275 { 276 return frt_bv_scan_next_from(bv, bv->curr_bit + 1); 277 } 278 279 /** 280 * Scan the FrtBitVector for the next unset bit after +from+. If no 281 * more bits are unset then return -1, otherwise return the index of 282 * teh next unset bit. 160 283 * 161 284 * @param bv the FrtBitVector to scan 162 * @return the next set bit's index or -1 if no more bits are set 163 */ 164 165 extern int frt_bv_scan_next_from(FrtBitVector *bv, register const int from); 166 /** 167 * Scan the FrtBitVector for the next unset bit. Before using this function you 168 * should reset the FrtBitVector for scanning using +frt_bv_scan_reset+. You can the 169 * repeated call frt_bv_scan_next to get each unset bit until it finally returns 170 * -1. 285 * @return the next unset bit's index or -1 if no more bits are unset 286 */ 287 extern FRT_ATTR_ALWAYS_INLINE 288 int frt_bv_scan_next_unset_from(FrtBitVector *bv, const int bit) 289 { 290 frt_u32 pos = bit >> 5; 291 frt_u32 word = bv->bits[pos]; 292 293 if (bit >= bv->size) 294 return -1; 295 296 /* Set all of the bits below this position */ 297 word |= (1 << (bit & 31)) - 1; 298 if (~word) 299 goto done; 300 301 for (pos++; pos < (frt_u32)bv->size; ++pos) 302 { 303 if ( ~(word = bv->bits[pos]) ) 304 goto done; 305 } 306 return -1; 307 done: 308 return bv->curr_bit = (pos << 5) + frt_count_trailing_ones(word); 309 } 310 311 /** 312 * Scan the FrtBitVector for the next unset bit. Before using this 313 * function you should reset the FrtBitVector for scanning using 314 * +frt_bv_scan_reset+. You can the repeated call frt_bv_scan_next to 315 * get each unset bit until it finally returns -1. 171 316 * 172 317 * @param bv the FrtBitVector to scan 173 318 * @return the next unset bits index or -1 if no more bits are unset 174 319 */ 175 extern int frt_bv_scan_next_unset(FrtBitVector *bv); 176 177 /** 178 * Scan the FrtBitVector for the next unset bit after +from+. If no more bits are 179 * unset then return -1, otherwise return the index of teh next unset bit. 180 * 181 * @param bv the FrtBitVector to scan 182 * @return the next unset bit's index or -1 if no more bits are unset 183 */ 184 extern int frt_bv_scan_next_unset_from(FrtBitVector *bv, register const int from); 320 extern FRT_ATTR_ALWAYS_INLINE 321 int frt_bv_scan_next_unset(FrtBitVector *bv) 322 { 323 return frt_bv_scan_next_unset_from(bv, bv->curr_bit + 1); 324 } 185 325 186 326 /** -
c/include/global.h
r3516e7 red4cf5 26 26 27 27 #if __GNUC__ >= 3 28 # define FRT_ALWAYS_INLINE inline __attribute__ ((always_inline)) 28 # define FRT_ATTR_ALWAYS_INLINE inline __attribute__ ((always_inline)) 29 # define FRT_ATTR_MALLOC __attribute__ ((malloc)) 30 # define FRT_ATTR_PURE __attribute__ ((pure)) 31 # define FRT_ATTR_CONST __attribute__ ((const)) 29 32 # define likely(x) __builtin_expect(!!(x), 1) 30 33 # define unlikely(x) __builtin_expect(!!(x), 0) 31 34 #else 32 # define FRT_ALWAYS_INLINE 35 # define FRT_ATTR_ALWAYS_INLINE 36 # define FRT_ATTR_MALLOC 37 # define FRT_ATTR_PURE 38 # define FRT_ATTR_CONST 33 39 # define likely(x) (x) 34 40 # define unlikely(x) (x) … … 127 133 128 134 /** 135 * Return the count of trailing [LSB] 0 bits in +word+. 136 */ 137 138 extern FRT_ATTR_ALWAYS_INLINE FRT_ATTR_CONST 139 int frt_count_trailing_zeros(frt_u32 word) 140 { 141 #ifdef __GNUC__ 142 return __builtin_ctz(word); 143 #else 144 static const int count_trailing_zeros[] = { 145 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 146 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 147 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 148 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 149 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 150 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 151 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 152 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 153 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 154 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 155 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 156 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 157 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 158 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 159 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 160 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 161 }; 162 if (word & 0xff) return count_trailing_zeros[word & 0xff]; 163 word >>= 8; if (word & 0xff) return count_trailing_zeros[word & 0xff] + 8; 164 word >>= 8; if (word & 0xff) return count_trailing_zeros[word & 0xff] + 16; 165 word >>= 8; return count_trailing_zeros[word & 0xff] + 24; 166 #endif 167 } 168 169 extern FRT_ATTR_ALWAYS_INLINE FRT_ATTR_CONST 170 int frt_count_trailing_ones(frt_u32 word) 171 { 172 return frt_count_trailing_zeros(~word); 173 } 174 175 extern FRT_ATTR_ALWAYS_INLINE FRT_ATTR_CONST 176 int frt_count_ones(frt_u32 word) 177 { 178 #ifdef __GNUC__ 179 return __builtin_popcount(word); 180 #else 181 static const frt_uchar count_ones[] = { 182 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 183 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 184 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 185 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 186 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 187 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 188 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 189 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 190 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 191 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 192 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 193 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 194 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 195 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 196 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 197 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 198 }; 199 return count_ones[(word ) & 0xff] 200 + count_ones[(word >> 8 ) & 0xff] 201 + count_ones[(word >> 16) & 0xff] 202 + count_ones[(word >> 24) & 0xff]; 203 #endif 204 } 205 206 extern FRT_ATTR_ALWAYS_INLINE FRT_ATTR_CONST 207 int frt_count_zeros(frt_u32 word) 208 { 209 return frt_count_ones(~word); 210 } 211 212 /** 129 213 * For coverage, we don't want FRT_XEXIT to actually exit on uncaught 130 214 * exceptions. +frt_x_abort_on_exception+ is +true+ by default, set it to -
c/src/bitvector.c
r48290f red4cf5 5 5 BitVector *bv_new_capa(int capa) 6 6 { 7 BitVector *bv = ALLOC (BitVector);7 BitVector *bv = ALLOC_AND_ZERO(BitVector); 8 8 9 9 /* The capacity passed by the user is number of bits allowed, however we … … 11 11 bv->capa = (capa >> 5) + 1; 12 12 bv->bits = ALLOC_AND_ZERO_N(u32, bv->capa); 13 14 bv->size = 0;15 bv->count = 0;16 13 bv->curr_bit = -1; 17 bv->extends_as_ones = 0;18 14 bv->ref_cnt = 1; 19 15 return bv; … … 33 29 } 34 30 35 void bv_set(BitVector *bv, int bit) 36 { 37 u32 *word_p; 31 void bv_clear(BitVector *bv) 32 { 33 memset(bv->bits, 0, bv->capa * sizeof(u32)); 34 bv->extends_as_ones = 0; 35 bv->count = 0; 36 bv->size = 0; 37 } 38 39 void bv_unset(BitVector *bv, int bit) 40 { 41 frt_u32 *word_p; 38 42 int word = bit >> 5; 39 u32 bitmask = 1 << (bit & 31);40 43 frt_u32 bitmask = 1 << (bit & 31); 44 41 45 /* Check to see if we need to grow the BitVector */ 42 if ( bit >= bv->size) {46 if (unlikely(bit >= bv->size)) { 43 47 bv->size = bit + 1; /* size is max range of bits set */ 44 48 if (word >= bv->capa) { … … 47 51 capa <<= 1; 48 52 } 49 REALLOC_N(bv->bits,u32, capa);53 FRT_REALLOC_N(bv->bits, frt_u32, capa); 50 54 memset(bv->bits + bv->capa, (bv->extends_as_ones ? 0xFF : 0), 51 sizeof( u32) * (capa - bv->capa));55 sizeof(frt_u32) * (capa - bv->capa)); 52 56 bv->capa = capa; 53 57 } 54 58 } 55 59 56 60 /* Set the required bit */ 57 61 word_p = &(bv->bits[word]); 58 if ((bitmask & *word_p) == 0) { 59 bv->count++; /* update count */ 60 *word_p |= bitmask; 61 } 62 } 63 64 /* 65 * This method relies on the fact that enough space has been allocated for the 66 * bits to be set. You need to create the BitVector using bv_new_capa(capa) 67 * with a capacity larger than any bit being set. 68 */ 69 INLINE void bv_set_fast(BitVector *bv, int bit) 70 { 71 bv->count++; 72 bv->size = bit + 1; 73 bv->bits[bit >> 5] |= 1 << (bit & 31); 74 } 75 76 int bv_get(BitVector *bv, int bit) 77 { 78 /* out of range so return 0 because it can't have been set */ 79 if (bit >= bv->size) { 80 return bv->extends_as_ones; 81 } 82 return (bv->bits[bit >> 5] >> (bit & 31)) & 0x01; 83 } 84 85 void bv_clear(BitVector *bv) 86 { 87 memset(bv->bits, 0, bv->capa * sizeof(u32)); 88 bv->extends_as_ones = 0; 89 bv->count = 0; 90 bv->size = 0; 91 } 92 93 /* 94 * FIXME: if the top set bit is unset, size is not adjusted. This will not 95 * cause any bugs in this code but could cause problems if users are relying 96 * on the fact that size is accurate. 97 */ 98 void bv_unset(BitVector *bv, int bit) 99 { 100 u32 *word_p; 101 u32 bitmask; 102 int word = bit >> 5; 103 104 if (bit >= bv->size) { 105 bv->size = bit + 1; /* size is max range of bits set */ 106 if (word >= bv->capa) { 107 int capa = bv->capa << 1; 108 109 while (capa <= word) { 110 capa <<= 1; 111 } 112 REALLOC_N(bv->bits, u32, capa); 113 memset(bv->bits + bv->capa, (bv->extends_as_ones ? 0xFF : 0), 114 sizeof(u32) * (capa - bv->capa)); 115 bv->capa = capa; 116 } 117 } 118 119 word_p = &(bv->bits[word]); 120 bitmask = 1 << (bit & 31); 121 if ((bitmask & *word_p) > 0) { 62 if ((bitmask & *word_p) != 0) { 122 63 bv->count--; /* update count */ 123 64 *word_p &= ~bitmask; … … 125 66 } 126 67 127 /* Table of bits per char. This table is used by the bv_recount method to128 * optimize the counting of bits */129 static const uchar BYTE_COUNTS[] = {130 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,131 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,132 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,133 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,134 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,135 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,136 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,137 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,138 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,139 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,140 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,141 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,142 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,143 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,144 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,145 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8146 };147 148 68 int bv_recount(BitVector *bv) 149 69 { 150 /* if the vector has been modified */151 int i, c = 0;152 u char *bytes = (uchar *)bv->bits; /* count by character */153 const int num_bytes = (((bv->size >> 5) + 1) << 2); 70 unsigned int extra = ((bv->size & 31) >> 3) + 1; 71 unsigned int len = bv->size >> 5; 72 unsigned int idx, count = 0; 73 154 74 if (bv->extends_as_ones) { 155 for (i = 0; i < num_bytes; i++) { 156 c += BYTE_COUNTS[~(bytes[i]) & 0xFF]; /* sum bits per char */ 157 } 158 } 159 else { 160 for (i = 0; i < num_bytes; i++) { 161 c += BYTE_COUNTS[bytes[i]]; /* sum bits per char */ 162 } 163 } 164 bv->count = c; 165 return c; 75 for (idx = 0; idx < len; ++idx) { 76 count += frt_count_zeros(bv->bits[idx]); 77 } 78 switch (extra) { 79 case 4: count += frt_count_zeros(bv->bits[idx] | 0x00ffffff); 80 case 3: count += frt_count_zeros(bv->bits[idx] | 0xff00ffff); 81 case 2: count += frt_count_zeros(bv->bits[idx] | 0xffff00ff); 82 case 1: count += frt_count_zeros(bv->bits[idx] | 0xffffff00); 83 } 84 } 85 else { 86 for (idx = 0; idx < len; ++idx) { 87 count += frt_count_ones(bv->bits[idx]); 88 } 89 switch (extra) { 90 case 4: count += frt_count_ones(bv->bits[idx] & 0xff000000); 91 case 3: count += frt_count_ones(bv->bits[idx] & 0x00ff0000); 92 case 2: count += frt_count_ones(bv->bits[idx] & 0x0000ff00); 93 case 1: count += frt_count_ones(bv->bits[idx] & 0x000000ff); 94 } 95 } 96 return bv->count = count; 166 97 } 167 98 … … 169 100 { 170 101 bv->curr_bit = -1; 171 }172 173 /* Table showing the number of trailing 0s in a char. This is used to optimize174 * the bv_scan_next method. */175 static const int NUM_TRAILING_ZEROS[] = {176 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,177 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,178 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,179 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,180 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,181 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,182 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,183 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,184 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,185 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,186 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,187 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,188 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,189 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,190 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,191 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0192 };193 194 /*195 * This method is highly optimized, hence the loop unrolling196 */197 static INLINE int bv_get_1_offset(u32 word)198 {199 if (word & 0xff) {200 return NUM_TRAILING_ZEROS[word & 0xff];201 }202 else {203 word >>= 8;204 if (word & 0xff) {205 return NUM_TRAILING_ZEROS[word & 0xff] + 8;206 }207 else {208 word >>= 8;209 if (word & 0xff) {210 return NUM_TRAILING_ZEROS[word & 0xff] + 16;211 }212 else {213 word >>= 8;214 return NUM_TRAILING_ZEROS[word & 0xff] + 24;215 }216 }217 }218 }219 /*220 * second fastest;221 *222 * while ((inc = NUM_TRA
