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

📄 bmfunc.h

📁 ncbi源码
💻 H
📖 第 1 页 / 共 5 页
字号:
    register const T* pend = pcurr + (*pcurr >> 3);    register unsigned bits_counter = 0;    ++pcurr;    if (*buf & 1)    {        bits_counter += *pcurr + 1;        ++pcurr;    }    ++pcurr;  // set GAP to 1    while (pcurr <= pend)    {        bits_counter += *pcurr - *(pcurr-1);        pcurr += 2; // jump to the next positive GAP    }     return bits_counter;}/*!   \brief Counts 1 bits in GAP buffer in the closed [left, right] diapason.   \param buf - GAP buffer pointer.   \param left - leftmost bit index to start from   \param right- rightmost bit index   \return Number of non-zero bits.*/template<typename T>unsigned gap_bit_count_range(const T* buf, T left, T right){    BM_ASSERT(left <= right);        const T* pcurr = buf;    const T* pend = pcurr + (*pcurr >> 3);        unsigned bits_counter = 0;    unsigned is_set;    unsigned start_pos = gap_bfind(buf, left, &is_set);    pcurr = buf + start_pos;    if (right <= *pcurr) // we are in the target block right now    {        if (is_set)            bits_counter = (right - left + 1);        return bits_counter;    }    if (is_set)        bits_counter += *pcurr - left + 1;    unsigned prev_gap = *pcurr++;    is_set ^= 1;    while (right > *pcurr)    {        if (is_set)            bits_counter += *pcurr - prev_gap;        if (pcurr == pend)             return bits_counter;        prev_gap = *pcurr++;        is_set ^= 1;    }    if (is_set)        bits_counter += right - prev_gap;    return bits_counter;}/*!    \brief Lexicographical comparison of GAP buffers.   \param buf1 - First GAP buffer pointer.   \param buf2 - Second GAP buffer pointer.   \return  <0 - less, =0 - equal,  >0 - greater.   @ingroup gapfunc*/template<typename T> int gapcmp(const T* buf1, const T* buf2){    const T* pcurr1 = buf1;    const T* pend1 = pcurr1 + (*pcurr1 >> 3);    unsigned bitval1 = *buf1 & 1;    ++pcurr1;    const T* pcurr2 = buf2;    unsigned bitval2 = *buf2 & 1;    ++pcurr2;    while (pcurr1 <= pend1)    {        if (*pcurr1 == *pcurr2)        {            if (bitval1 != bitval2)            {                return (bitval1) ? 1 : -1;            }        }        else        {            if (bitval1 == bitval2)            {                if (bitval1)                {                    return (*pcurr1 < *pcurr2) ? -1 : 1;                }                else                {                    return (*pcurr1 < *pcurr2) ? 1 : -1;                }            }            else            {                return (bitval1) ? 1 : -1;            }        }        ++pcurr1; ++pcurr2;        bitval1 ^= 1;        bitval2 ^= 1;    }    return 0;}/*!   \brief Abstract operation for GAP buffers.           Receives functor F as a template argument   \param dest - destination memory buffer.   \param vect1 - operand 1 GAP encoded buffer.   \param vect1_mask - XOR mask for starting bitflag for vector1    can be 0 or 1 (1 inverts the vector)   \param vect2 - operand 2 GAP encoded buffer.   \param vect2_mask - same as vect1_mask   \param f - operation functor.   \note Internal function.   @ingroup gapfunc*/template<typename T, class F> void gap_buff_op(T*         BMRESTRICT dest,                  const T*   BMRESTRICT vect1,                 unsigned   vect1_mask,                  const T*   BMRESTRICT vect2,                 unsigned   vect2_mask,                  F f){    register const T*  cur1 = vect1;    register const T*  cur2 = vect2;    unsigned bitval1 = (*cur1++ & 1) ^ vect1_mask;    unsigned bitval2 = (*cur2++ & 1) ^ vect2_mask;        unsigned bitval = f(bitval1, bitval2);    unsigned bitval_prev = bitval;    register T* res = dest;     *res = bitval;    ++res;    while (1)    {        bitval = f(bitval1, bitval2);        // Check if GAP value changes and we need to         // start the next one.        if (bitval != bitval_prev)        {            ++res;            bitval_prev = bitval;        }        if (*cur1 < *cur2)        {            *res = *cur1;            ++cur1;            bitval1 ^= 1;        }        else // >=        {            *res = *cur2;            if (*cur2 < *cur1)            {                bitval2 ^= 1;                            }            else  // equal            {                if (*cur2 == (bm::gap_max_bits - 1))                {                    break;                }                ++cur1;                bitval1 ^= 1;                bitval2 ^= 1;            }            ++cur2;        }    } // while    unsigned dlen = (unsigned)(res - dest);    *dest = (*dest & 7) + (dlen << 3);}/*!   \brief Abstract distance(similarity) operation for GAP buffers.           Receives functor F as a template argument   \param vect1 - operand 1 GAP encoded buffer.   \param vect2 - operand 2 GAP encoded buffer.   \param f - operation functor.   \note Internal function.   @ingroup gapfunc*//*template<typename T, class F> unsigned gap_buff_count_op(const T*  vect1, const T*  vect2, F f){    register const T* cur1 = vect1;    register const T* cur2 = vect2;    unsigned bitval1 = (*cur1++ & 1);    unsigned bitval2 = (*cur2++ & 1);    unsigned bitval = f(bitval1, bitval2);    unsigned bitval_prev = bitval;    unsigned count = 0;    T res;    T res_prev;    while (1)    {        bitval = f(bitval1, bitval2);        // Check if GAP value changes and we need to         // start the next one.        if (bitval != bitval_prev)        {            bitval_prev = bitval;        }        if (*cur1 < *cur2)        {            if (bitval)                count += *cur1;             ++cur1;            bitval1 ^= 1;        }        else // >=        {            if (bitval)                count += *cur2;             if (*cur2 < *cur1)            {                bitval2 ^= 1;                            }            else  // equal            {                if (*cur2 == (bm::gap_max_bits - 1))                {                    break;                }                ++cur1;                bitval1 ^= 1;                bitval2 ^= 1;            }            ++cur2;        }    } // while    return count;}*//*!   \brief Sets or clears bit in the GAP buffer.   \param val - new bit value   \param buf - GAP buffer.   \param pos - Index of bit to set.   \param is_set - (OUT) flag if bit was actually set.   \return New GAP buffer length.    @ingroup gapfunc*/template<typename T> unsigned gap_set_value(unsigned val,                                             T* BMRESTRICT buf,                                             unsigned pos,                                             unsigned* BMRESTRICT is_set){    BM_ASSERT(pos < bm::gap_max_bits);    unsigned curr = gap_bfind(buf, pos, is_set);    register T end = (*buf >> 3);	if (*is_set == val)	{		*is_set = 0;		return end;	}    *is_set = 1;    register T* pcurr = buf + curr;    register T* pprev = pcurr - 1;    register T* pend = buf + end;    // Special case, first bit GAP operation. There is no platform beside it.    // initial flag must be inverted.    if (pos == 0)    {        *buf ^= 1;        if ( buf[1] ) // We need to insert a 1 bit platform here.        {            ::memmove(&buf[2], &buf[1], (end - 1) * sizeof(gap_word_t));            buf[1] = 0;            ++end;        }        else // Only 1 bit in the GAP. We need to delete the first GAP.        {            pprev = buf + 1;            pcurr = pprev + 1;            do            {                *pprev++ = *pcurr++;            } while (pcurr < pend);            --end;        }    }    else if (curr > 1 && ((unsigned)(*pprev))+1 == pos) // Left border bit	{ 	   ++(*pprev);	   if (*pprev == *pcurr)  // Curr. GAP to be merged with prev.GAP.	   {            --end;            if (pcurr != pend) // GAP merge: 2 GAPS to be deleted             {                --end;                ++pcurr;                do                {                    *pprev++ = *pcurr++;                } while (pcurr < pend);            }	   }        }	else if (*pcurr == pos) // Rightmost bit in the GAP. Border goes left.	{		--(*pcurr);       		if (pcurr == pend)        {		   ++end;        }	}	else  // Worst case we need to split current block.	{        ::memmove(pcurr+2, pcurr,(end - curr + 1)*sizeof(T));        *pcurr++ = pos - 1;        *pcurr = pos;		end+=2;	}    // Set correct length word.    *buf = (*buf & 7) + (end << 3);    buf[end] = bm::gap_max_bits - 1;    return end;}//------------------------------------------------------------------------/**    \brief Searches for the next 1 bit in the GAP block    \param buf - GAP buffer    \param nbit - bit index to start checking from.    \param prev - returns previously checked value    @ingroup gapfunc*/template<typename T> int gap_find_in_block(const T* buf,                                            unsigned nbit,                                            bm::id_t* prev){    BM_ASSERT(nbit < bm::gap_max_bits);    unsigned bitval;    unsigned gap_idx = bm::gap_bfind(buf, nbit, &bitval);    if (bitval) // positive block.    {       return 1;    }    register unsigned val = buf[gap_idx] + 1;    *prev += val - nbit;     return (val != bm::gap_max_bits);  // no bug here.}/*!    \brief Sets bits to 1 in the bitblock.   \param dest - Bitset buffer.   \param bitpos - Offset of the start bit.   \param bitcount - number of bits to set.   @ingroup bitfunc*/  inline void or_bit_block(unsigned* dest,                          unsigned bitpos,                          unsigned bitcount){    unsigned nbit  = unsigned(bitpos & bm::set_block_mask);     unsigned nword = unsigned(nbit >> bm::set_word_shift);     nbit &= bm::set_word_mask;    bm::word_t* word = dest + nword;    if (bitcount == 1)  // special case (only 1 bit to set)    {        *word |= unsigned(1 << nbit);        return;    }    if (nbit) // starting position is not aligned    {        unsigned right_margin = nbit + bitcount;        // here we checking if we setting bits only in the current        // word. Example: 00111000000000000000000000000000 (32 bits word)        if (right_margin < 32)         {            unsigned mask =                 block_set_table<true>::_right[nbit] &                 block_set_table<true>::_left[right_margin-1];            *word |= mask;            return; // we are done        }        else        {            *word |= block_set_table<true>::_right[nbit];            bitcount -= 32 - nbit;        }        ++word;    }    // now we are word aligned, lets find out how many words we     // can now turn ON using loop    for ( ;bitcount >= 32; bitcount -= 32)     {        *word++ = 0xffffffff;    }    if (bitcount)     {        *word |= block_set_table<true>::_left[bitcount-1];    }}/*!    \brief SUB (AND NOT) bit interval to 1 in the bitblock.   \param dest - Bitset buffer.   \param bitpos - Offset of the start bit.   \param bitcount - number of bits to set.   @ingroup bitfunc*/  inline void sub_bit_block(unsigned* dest,                           unsigned bitpos,                           unsigned bitcount){    unsigned nbit  = unsigned(bitpos & bm::set_block_mask);     unsigned nword = unsigned(nbit >> bm::set_word_shift);     nbit &= bm::set_word_mask;    bm::word_t* word = dest + nword;    if (bitcount == 1)  // special case (only 1 bit to set)    {        *word &= ~unsigned(1 << nbit);        return;    }    if (nbit) // starting position is not aligned    {        unsigned right_margin = nbit + bitcount;        // here we checking if we setting bits only in the current        // word. Example: 00111000000000000000000000000000 (32 bits word)        if (right_margin < 32)         {            unsigned mask =                 block_set_table<true>::_right[nbit] &                 block_set_table<true>::_left[right_margin-1];            *word &= ~mask;            return; // we are done        }        else        {            *word &= ~block_set_table<true>::_right[nbit];            bitcount -= 32 - nbit;        }        ++word;    }    // now we are word aligned, lets find out how many words we     // can now turn ON using loop    for ( ;bitcount >= 32; bitcount -= 32)     {        *word++ = 0;    }    if (bitcount)     {        *word &= ~block_set_table<true>::_left[bitcount-1];    }}/*!    \brief XOR bit interval to 1 in the bitblock.   \param dest - Bitset buffer.   \param bitpos - Offset of the start bit.   \param bitcount - number of bits to set.   @ingroup bitfunc*/  inline void xor_bit_block(unsigned* dest,                           unsigned bitpos,                           unsigned bitcount){    unsigned nbit  = unsigned(bitpos & bm::set_block_mask);     unsigned nword = unsigned(nbit >> bm::set_word_shift); 

⌨️ 快捷键说明

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