Changeset ed4cf588b31c5ebb50b4d502802d243fec2cb338

Show
Ignore:
Timestamp:
04/30/08 12:45:38 (8 months ago)
Author:
krayouva <krayouva@…>
Parents:
3516e7ae3f4df445e780bee77b2a9a7f6ce7ddb8
Children:
1c4d613e749d9e677b5d4a13214e93bfee485937
git-committer:
krayouva <krayouva@gmail.com> / 2008-04-29T22:45:38Z-0400
Message:

* Optimized bitvector

- Wrapped bitvector.h descriptions to fit 80 char width
- Added malloc/inline/const/pure attributes where possible to improve

compiler optimizations

- Inlined most important functions [at least, the ones that are benched]
- Refactored bv_set/unset by having a set_value they call to
- Implemented optimized bicount routines that use gcc builtins where

possible

- Improved bv_recount to count by word

Location:
c
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • c/include/bitvector.h

    rcb8a79 red4cf5  
    2121    int capa; 
    2222 
    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 */ 
    2526    int count; 
    2627 
     
    3334 
    3435/** 
    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. 
    3739 * 
    3840 * @return FrtBitVector with a capacity of +FRT_BV_INIT_CAPA+. 
    3941 */ 
    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. 
     42extern FRT_ATTR_MALLOC 
     43FrtBitVector *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. 
    4549 * 
    4650 * @param capa the initial capacity of the FrtBitVector 
    4751 * @return FrtBitVector with a capacity of +capa+. 
    4852 */ 
    49 extern FrtBitVector *frt_bv_new_capa(int capa); 
    50  
    51 /** 
    52  * Destroy a FrtBitVector, freeing all memory allocated to that FrtBitVector 
     53extern FRT_ATTR_MALLOC 
     54FrtBitVector *frt_bv_new_capa(int capa); 
     55 
     56/** 
     57 * Destroy a FrtBitVector, freeing all memory allocated to that 
     58 * FrtBitVector 
    5359 * 
    5460 * @param bv FrtBitVector to destroy 
     
    5763 
    5864/** 
    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. 
    6370 * 
    6471 * @param bv the FrtBitVector to set the bit in 
    6572 * @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 */ 
     81extern FRT_ATTR_ALWAYS_INLINE 
     82void 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 */ 
     127extern FRT_ATTR_ALWAYS_INLINE 
     128void frt_bv_set(FrtBitVector *bv, int bit) 
     129{ 
     130    frt_bv_set_value(bv, bit, 1); 
     131} 
    68132 
    69133/** 
    70134 * 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. 
    74139 * 
    75140 * So this is ok; 
     
    93158 * @param index the index of the bit to set 
    94159 */ 
    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. 
     160extern FRT_ATTR_ALWAYS_INLINE 
     161void 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. 
    100172 * 
    101173 * @param bv the FrtBitVector to check in 
     
    103175 * @return 1 if the bit was set, 0 otherwise 
    104176 */ 
    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). 
     177extern FRT_ATTR_ALWAYS_INLINE 
     178int 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). 
    111191 * 
    112192 * @param bv the FrtBitVector to unset the bit in 
    113193 * @param index the index of the bit to unset 
    114194 */ 
    115 extern void frt_bv_unset(FrtBitVector *bv, int bit); 
     195extern FRT_ATTR_ALWAYS_INLINE 
     196void frt_bv_unset(FrtBitVector *bv, int bit) 
     197{ 
     198    frt_bv_set_value(bv, bit, 0); 
     199} 
    116200 
    117201/** 
     
    123207 
    124208/** 
    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). 
    130215 * 
    131216 * @param bv the FrtBitVector to count the bits in 
     
    136221 
    137222/** 
    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. 
    141227 * 
    142228 * @param bv the FrtBitVector to reset for scanning 
     
    145231 
    146232/** 
    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 */ 
     240extern FRT_ATTR_ALWAYS_INLINE 
     241int 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. 
    151269 * 
    152270 * @param bv the FrtBitVector to scan 
    153271 * @return the next set bits index or -1 if no more bits are set 
    154272 */ 
    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. 
     273extern FRT_ATTR_ALWAYS_INLINE 
     274int 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. 
    160283 * 
    161284 * @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 */ 
     287extern FRT_ATTR_ALWAYS_INLINE 
     288int 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. 
    171316 * 
    172317 * @param bv the FrtBitVector to scan 
    173318 * @return the next unset bits index or -1 if no more bits are unset 
    174319 */ 
    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); 
     320extern FRT_ATTR_ALWAYS_INLINE 
     321int frt_bv_scan_next_unset(FrtBitVector *bv) 
     322{ 
     323    return frt_bv_scan_next_unset_from(bv, bv->curr_bit + 1); 
     324} 
    185325 
    186326/** 
  • c/include/global.h

    r3516e7 red4cf5  
    2626 
    2727#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)) 
    2932#  define likely(x)   __builtin_expect(!!(x), 1) 
    3033#  define unlikely(x) __builtin_expect(!!(x), 0) 
    3134#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 
    3339#  define likely(x)   (x) 
    3440#  define unlikely(x) (x) 
     
    127133 
    128134/** 
     135 * Return the count of trailing [LSB] 0 bits in +word+. 
     136 */ 
     137 
     138extern FRT_ATTR_ALWAYS_INLINE FRT_ATTR_CONST 
     139int 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 
     169extern FRT_ATTR_ALWAYS_INLINE FRT_ATTR_CONST 
     170int frt_count_trailing_ones(frt_u32 word) 
     171{ 
     172    return frt_count_trailing_zeros(~word); 
     173} 
     174 
     175extern FRT_ATTR_ALWAYS_INLINE FRT_ATTR_CONST 
     176int 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 
     206extern FRT_ATTR_ALWAYS_INLINE FRT_ATTR_CONST 
     207int frt_count_zeros(frt_u32 word) 
     208{ 
     209    return frt_count_ones(~word); 
     210} 
     211 
     212/** 
    129213 * For coverage, we don't want FRT_XEXIT to actually exit on uncaught 
    130214 * exceptions.  +frt_x_abort_on_exception+ is +true+ by default, set it to 
  • c/src/bitvector.c

    r48290f red4cf5  
    55BitVector *bv_new_capa(int capa) 
    66{ 
    7     BitVector *bv = ALLOC(BitVector); 
     7    BitVector *bv = ALLOC_AND_ZERO(BitVector); 
    88 
    99    /* The capacity passed by the user is number of bits allowed, however we 
     
    1111    bv->capa = (capa >> 5) + 1; 
    1212    bv->bits = ALLOC_AND_ZERO_N(u32, bv->capa); 
    13  
    14     bv->size = 0; 
    15     bv->count = 0; 
    1613    bv->curr_bit = -1; 
    17     bv->extends_as_ones = 0; 
    1814    bv->ref_cnt = 1; 
    1915    return bv; 
     
    3329} 
    3430 
    35 void bv_set(BitVector *bv, int bit) 
    36 { 
    37     u32 *word_p; 
     31void 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 
     39void bv_unset(BitVector *bv, int bit) 
     40{ 
     41    frt_u32 *word_p; 
    3842    int word = bit >> 5; 
    39     u32 bitmask = 1 << (bit & 31); 
    40      
     43    frt_u32 bitmask = 1 << (bit & 31); 
     44 
    4145    /* Check to see if we need to grow the BitVector */ 
    42     if (bit >= bv->size) { 
     46    if (unlikely(bit >= bv->size)) { 
    4347        bv->size = bit + 1; /* size is max range of bits set */ 
    4448        if (word >= bv->capa) { 
     
    4751                capa <<= 1; 
    4852            } 
    49             REALLOC_N(bv->bits, u32, capa); 
     53            FRT_REALLOC_N(bv->bits, frt_u32, capa); 
    5054            memset(bv->bits + bv->capa, (bv->extends_as_ones ? 0xFF : 0), 
    51                    sizeof(u32) * (capa - bv->capa)); 
     55                   sizeof(frt_u32) * (capa - bv->capa)); 
    5256            bv->capa = capa; 
    5357        } 
    5458    } 
    55      
     59 
    5660    /* Set the required bit */ 
    5761    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) { 
    12263        bv->count--; /* update count */ 
    12364        *word_p &= ~bitmask; 
     
    12566} 
    12667 
    127 /* Table of bits per char. This table is used by the bv_recount method to 
    128  * 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, 8 
    146 }; 
    147  
    14868int bv_recount(BitVector *bv) 
    14969{ 
    150     /* if the vector has been modified */ 
    151     int i, c = 0; 
    152     uchar *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 
    15474    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; 
    16697} 
    16798 
     
    169100{ 
    170101    bv->curr_bit = -1; 
    171 } 
    172  
    173 /* Table showing the number of trailing 0s in a char. This is used to optimize 
    174  * 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, 0 
    192 }; 
    193  
    194 /* 
    195  * This method is highly optimized, hence the loop unrolling 
    196  */ 
    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