⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmfunc.h

📁 ncbi源码
💻 H
📖 第 1 页 / 共 5 页
字号:
}/*!   \brief Checks if GAP block is all-one.   \param buf - GAP buffer pointer.   \param set_max - max possible bitset length   \returns true if all-one.   @ingroup gapfunc*/template<typename T>          bool gap_is_all_one(const T* buf, unsigned set_max){    return ((*buf & 1)  && (*(++buf) == set_max - 1));}/*!   \brief Returs GAP block length.   \param buf - GAP buffer pointer.   \returns GAP block length.   @ingroup gapfunc*/template<typename T> unsigned gap_length(const T* buf){    return (*buf >> 3) + 1;}/*!   \brief Returs GAP block capacity.   \param buf - GAP buffer pointer.   \returns GAP block capacity.   @ingroup gapfunc*/template<typename T> unsigned gap_capacity(const T* buf, const T* glevel_len){    return glevel_len[(*buf >> 1) & 3];}/*!   \brief Returs GAP block capacity limit.   \param buf - GAP buffer pointer.   \param glevel_len - GAP lengths table (gap_len_table)   \returns GAP block limit.   @ingroup gapfunc*/template<typename T> unsigned gap_limit(const T* buf, const T* glevel_len){    return glevel_len[(*buf >> 1) & 3]-4;}/*!   \brief Returs GAP blocks capacity level.   \param buf - GAP buffer pointer.   \returns GAP block capacity level.   @ingroup gapfunc*/template<typename T> unsigned gap_level(const T* buf){    return (*buf >> 1) & 3;}/*!   \brief Sets GAP block capacity level.   \param buf - GAP buffer pointer.   \param level new GAP block capacity level.   @ingroup gapfunc*/template<typename T> void set_gap_level(T* buf,                                         unsigned level){    BM_ASSERT(level < bm::gap_levels);    *buf = ((level & 3) << 1) | (*buf & 1) | (*buf & ~7); }/*!   \brief Calculates GAP block capacity level.   \param len - GAP buffer length.   \param glevel_len - GAP lengths table   \return GAP block capacity level.             -1 if block does not fit any level.   @ingroup gapfunc*/template<typename T>inline int gap_calc_level(int len, const T* glevel_len){    if (len <= (glevel_len[0]-4)) return 0;    if (len <= (glevel_len[1]-4)) return 1;    if (len <= (glevel_len[2]-4)) return 2;    if (len <= (glevel_len[3]-4)) return 3;    BM_ASSERT(bm::gap_levels == 4);    return -1;}/*! @brief Returns number of free elements in GAP block array.     Difference between GAP block capacity on this level and actual GAP length.        @param buf - GAP buffer pointer    @parma glevel_len - GAP lengths table        @return Number of free GAP elements    @ingroup gapfunc*/template<typename T>inline unsigned gap_free_elements(const T* buf, const T* glevel_len){    unsigned len = gap_length(buf);    unsigned capacity = gap_capacity(buf, glevel_len);    return capacity - len;}/*!    \brief Lexicographical comparison of BIT buffers.   \param buf1 - First buffer pointer.   \param buf2 - Second buffer pointer.   \param len - Buffer length in elements (T).   \return  <0 - less, =0 - equal,  >0 - greater.   @ingroup bitfunc */template<typename T> int bitcmp(const T* buf1, const T* buf2, unsigned len){    BM_ASSERT(len);    const T* pend1 = buf1 + len;     do    {        T w1 = *buf1++;        T w2 = *buf2++;        T diff = w1 ^ w2;            if (diff)        {             return (w1 & diff & -diff) ? 1 : -1;        }    } while (buf1 < pend1);    return 0;}/*!    \brief Converts bit block to GAP.    \param dest - Destinatio GAP buffer.   \param src - Source bitblock buffer.   \param bits - Number of bits to convert.   \param dest_len - length of the dest. buffer.   \return  New ength of GAP block or 0 if conversion failed    (insufficicent space).   @ingroup gapfunc*/template<typename T>     unsigned bit_convert_to_gap(T* BMRESTRICT dest,                                 const unsigned* BMRESTRICT src,                                 bm::id_t bits,                                 unsigned dest_len){    register T* BMRESTRICT pcurr = dest;    T* BMRESTRICT end = dest + dest_len;     register int bitval = (*src) & 1;    *pcurr |= bitval;    ++pcurr;    *pcurr = 0;    register unsigned bit_idx = 0;    register int bitval_next;    unsigned val = *src;    do    {        // We can fast pace if *src == 0 or *src = 0xffffffff        while (val == 0 || val == 0xffffffff)        {           bitval_next = val ? 1 : 0;           if (bitval != bitval_next)           {               *pcurr++ = bit_idx-1;                BM_ASSERT((pcurr-1) == (dest+1) || *(pcurr-1) > *(pcurr-2));               if (pcurr >= end)               {                   return 0; // OUT of memory               }               bitval = bitval_next;           }           bit_idx += sizeof(*src) * 8;           if (bit_idx >= bits)           {               goto complete;           }           ++src;           val = *src;        }        register unsigned mask = 1;        while (mask)        {            // Now plain bitshifting. Optimization wanted.            bitval_next = val & mask ? 1 : 0;            if (bitval != bitval_next)            {                *pcurr++ = bit_idx-1;                BM_ASSERT((pcurr-1) == (dest+1) || *(pcurr-1) > *(pcurr-2));                bitval = bitval_next;                if (pcurr >= end)                {                    return 0; // OUT of memory                }            }            mask <<= 1;            ++bit_idx;        } // while mask        if (bit_idx >= bits)        {            goto complete;        }        ++src;        val = *src;    } while(1);complete:    *pcurr = bit_idx-1;    unsigned len = (unsigned)(pcurr - dest);    *dest = (*dest & 7) + (len << 3);    return len;}/*!    @ingroup bitfunc */template<typename T> T bit_convert_to_arr(T* BMRESTRICT dest,                                           const unsigned* BMRESTRICT src,                                           bm::id_t bits,                                           unsigned dest_len){    register T* BMRESTRICT pcurr = dest;    T* BMRESTRICT end = dest + dest_len;     register unsigned bit_idx = 0;    do    {        register unsigned val = *src;        // We can skip if *src == 0         while (val == 0)        {            bit_idx += sizeof(*src) * 8;            if (bit_idx >= bits)            {               return (T)(pcurr - dest);            }            val = *(++src);        }        if (pcurr + sizeof(val)*8 > end) // insufficient space        {            return 0;        }        for (int i = 0; i < 32; i+=4)        {            if (val & 1)                *pcurr++ = bit_idx;            val >>= 1; ++bit_idx;            if (val & 1)                *pcurr++ = bit_idx;            val >>= 1; ++bit_idx;            if (val & 1)                *pcurr++ = bit_idx;            val >>= 1; ++bit_idx;            if (val & 1)                *pcurr++ = bit_idx;            val >>= 1; ++bit_idx;        }        if (bits <= bit_idx)            break;        val = *(++src);    } while (1);    return (T)(pcurr - dest);}/*!     @brief Bitcount for bit string    	Function calculates number of 1 bits in the given array of words.    Make sure the addresses are aligned.    @ingroup bitfunc */inline bm::id_t bit_block_calc_count(const bm::word_t* block, 							  const bm::word_t* block_end){    BM_ASSERT(block < block_end);	bm::id_t count = 0;#ifdef BM64OPT    // 64-bit optimized algorithm.    const bm::id64_t* b1 = (bm::id64_t*) block;    const bm::id64_t* b2 = (bm::id64_t*) block_end;    bm::id64_t  acc = *b1++;  // accumulator (sparse vectors optimization)    do    {        bm::id64_t in = *b1++;        bm::id64_t acc_prev = acc;        acc |= in;        if (acc_prev &= in)  // counting bits in accumulator        {            acc = (acc & 0x5555555555555555LU) + (acc >> 1 & 0x5555555555555555LU);            acc = (acc & 0x3333333333333333LU) + (acc >> 2 & 0x3333333333333333LU);            acc = acc + (acc >> 4) & 0x0F0F0F0F0F0F0F0FLU;            acc = acc + (acc >> 8);            acc = acc + (acc >> 16);            acc = acc + (acc >> 32) & 0x0000007F;            count += (unsigned)acc;            acc = acc_prev;        }    } while (b1 < b2);    count += word_bitcount64(acc);  // count-in remaining accumulator #else    // For 32 bit code the fastest method is    // to use bitcount table for each byte in the block.    // As optimization for sparse bitsets used bits accumulator    // to collect ON bits using bitwise OR.     bm::word_t  acc = *block++;    do    {        bm::word_t in = *block++;        bm::word_t acc_prev = acc;        acc |= in;        if (acc_prev &= in)  // accumulator miss: counting bits        {            BM_INCWORD_BITCOUNT(count, acc);            acc = acc_prev;        }    } while (block < block_end);    BM_INCWORD_BITCOUNT(count, acc); // count-in remaining accumulator #endif	    return count;}/*!    Function calculates number of times when bit value changed     (1-0 or 0-1).        For 001 result is 2        010 - 3        011 - 2        111 - 1        @ingroup bitfunc */inline bm::id_t bit_count_change(bm::word_t w){    unsigned count = 1;    w ^= (w >> 1);    BM_INCWORD_BITCOUNT(count, w);    count -= (w >> ((sizeof(w) * 8) - 1));    return count;}/*!    Function calculates number of times when bit value changed     (1-0 or 0-1) in the bit block.            @ingroup bitfunc */inline bm::id_t bit_block_calc_count_change(const bm::word_t* block, 							         const bm::word_t* block_end){    BM_ASSERT(block < block_end);    bm::id_t count = 1;    #ifdef BM64OPT    // 64-bit optimized algorithm.    const bm::id64_t* b1 = (bm::id64_t*) block;    const bm::id64_t* b2 = (bm::id64_t*) block_end;    bm::id64_t w, w0, w_prev, w_l;    w = w0 = *b1;    const int w_shift = sizeof(w) * 8 - 1;    w ^= (w >> 1);    count += word_bitcount64(w);    count -= (w_prev = (w0 >> w_shift)); // negative value correction        for (++b1 ;b1 < b2; ++b1)    {        w = w0 = *b1;        ++count;                if (!w)        {            count -= !w_prev;            w_prev = 0;        }        else        {            w ^= (w >> 1);            count += word_bitcount64(w);                        w_l = w0 & 1;            count -= (w0 >> w_shift);  // negative value correction            count -= !(w_prev ^ w_l);  // word border correction                        w_prev = (w0 >> w_shift);        }    } // for#else        bm::word_t  w, w0, w_prev, w_l;         w = w0 = *block;    const int w_shift = sizeof(w) * 8 - 1;        w ^= (w >> 1);    BM_INCWORD_BITCOUNT(count, w);    count -= (w_prev = (w0 >> w_shift)); // negative value correction    for (++block ;block < block_end; ++block)    {        w = w0 = *block;        ++count;        if (!w)        {                   count -= !w_prev;            w_prev = 0;        }        else        {            w ^= (w >> 1);            BM_INCWORD_BITCOUNT(count, w);                        w_l = w0 & 1;            count -= (w0 >> w_shift);  // negative value correction            count -= !(w_prev ^ w_l);  // word border correction                        w_prev = (w0 >> w_shift);        }    } // for#endif    return count;}/*!	Function calculates number of 1 bits in the given array of words in    the range between left anf right bits (borders included)    Make sure the addresses are aligned.    @ingroup bitfunc*/inline bm::id_t bit_block_calc_count_range(const bm::word_t* block,                                    bm::word_t left,                                    bm::word_t right){    BM_ASSERT(left <= right);    	bm::id_t count = 0;    unsigned nbit  = left; // unsigned(left & bm::set_block_mask);    unsigned nword = unsigned(nbit >> bm::set_word_shift);    nbit &= bm::set_word_mask;    const bm::word_t* word = block + nword;    if (left == right)  // special case (only 1 bit to check)    {        return (*word >> nbit) & 1;    }    unsigned acc;    unsigned bitcount = right - left + 1;    if (nbit) // starting position is not aligned    {        unsigned right_margin = nbit + (right - left);        if (right_margin < 32)        {            unsigned mask =                block_set_table<true>::_right[nbit] &                block_set_table<true>::_left[right_margin];            acc = *word & mask;                        BM_INCWORD_BITCOUNT(count, acc);            return count;        }        else        {            acc = *word & block_set_table<true>::_right[nbit];            BM_INCWORD_BITCOUNT(count, acc);            bitcount -= 32 - nbit;        }        ++word;    }    // now when we are word aligned, we can count bits the usual way    for ( ;bitcount >= 32; bitcount -= 32)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -