1 #ifndef BMENCODING_H__INCLUDED__
2 #define BMENCODING_H__INCLUDED__
31 #pragma warning (push)
32 #pragma warning (disable : 4702)
66 unsigned char c8,
unsigned char c16,
unsigned char c32)
BMNOEXCEPT;
169 bool get_32_OR(
bm::word_t* w,
unsigned count);
170 void get_32_AND(
bm::word_t* w,
unsigned count);
181 template<
class TEncoder>
186 : dest_(dest), used_bits_(0), accum_(0)
201 void put_zero_bits(
unsigned count)
BMNOEXCEPT;
210 bic_encode_u16_cm(
arr, sz, lo, hi);
235 dest_.put_32(accum_);
236 used_bits_ = accum_ = 0;
255 template<
class TDecoder>
261 used_bits_(
unsigned(
sizeof(accum_) * 8)),
279 bic_decode_u16_cm(
arr, sz, lo, hi);
286 bic_decode_u16_cm_bitset(block, sz, lo, hi);
292 bic_decode_u16_cm_dry(sz, lo, hi);
309 void bic_decode_u16_rg_bitset(
bm::word_t* block,
unsigned sz,
313 void bic_decode_u16_rg_dry(
unsigned sz,
317 void bic_decode_u16_cm_bitset(
bm::word_t* block,
unsigned sz,
322 void bic_decode_u16_cm_dry(
unsigned sz,
339 template<
typename T,
typename TBitIO>
360 template<
typename T,
typename TBitIO>
446 #if (BM_UNALIGNED_ACCESS_OK == 1)
450 *
buf_++ = (
unsigned char) s;
452 *
buf_++ = (
unsigned char) s;
462 #if (BM_UNALIGNED_ACCESS_OK == 1)
471 unsigned char a = (
unsigned char) w16;
472 unsigned char b = (
unsigned char) (w16 >> 8);
495 put_8((
unsigned char)w);
502 put_16((
unsigned short) w);
559 buf_[0] = (
unsigned char)w;
560 buf_[1] = (
unsigned char)(w >> 8);
561 buf_[2] = (
unsigned char)(w >> 16);
573 #if (BM_UNALIGNED_ACCESS_OK == 1)
577 *
buf_++ = (
unsigned char) w;
578 *
buf_++ = (
unsigned char) (w >> 8);
579 *
buf_++ = (
unsigned char) (w >> 16);
580 *
buf_++ = (
unsigned char) (w >> 24);
591 BM_ASSERT((w & ~(0xFFFFFFFFFFFFUL)) == 0);
592 *
buf_++ = (
unsigned char)w;
593 *
buf_++ = (
unsigned char)(w >> 8);
594 *
buf_++ = (
unsigned char)(w >> 16);
595 *
buf_++ = (
unsigned char)(w >> 24);
596 *
buf_++ = (
unsigned char)(w >> 32);
597 *
buf_++ = (
unsigned char)(w >> 40);
608 #if (BM_UNALIGNED_ACCESS_OK == 1)
612 *
buf_++ = (
unsigned char) w;
613 *
buf_++ = (
unsigned char) (w >> 8);
614 *
buf_++ = (
unsigned char) (w >> 16);
615 *
buf_++ = (
unsigned char) (w >> 24);
616 *
buf_++ = (
unsigned char) (w >> 32);
617 *
buf_++ = (
unsigned char) (w >> 40);
618 *
buf_++ = (
unsigned char) (w >> 48);
619 *
buf_++ = (
unsigned char) (w >> 56);
631 put_8((
unsigned char) h_mask);
632 for (
unsigned i = 0; w && (i < 8); ++i, w >>= 8)
634 if ((
unsigned char) w)
635 put_8((
unsigned char) w);
646 #if (BM_UNALIGNED_ACCESS_OK == 1)
656 unsigned char a = (
unsigned char) w32;
657 unsigned char b = (
unsigned char) (w32 >> 8);
658 unsigned char c = (
unsigned char) (w32 >> 16);
659 unsigned char d = (
unsigned char) (w32 >> 24);
694 unsigned h_mask = (
unsigned char) *
buf_++;
695 for (
unsigned i = 0; h_mask && (
i < 8); ++
i)
697 if (h_mask & (1u<<
i))
700 unsigned char a = (
unsigned char) *
buf_++;
724 #if (BM_UNALIGNED_ACCESS_OK == 1)
741 ((unsigned)
buf_[2] << 16);
753 #if (BM_UNALIGNED_ACCESS_OK == 1)
758 ((unsigned)
buf_[2] << 16) + ((unsigned)
buf_[3] << 24);
788 #if (BM_UNALIGNED_ACCESS_OK == 1)
819 #if (BM_UNALIGNED_ACCESS_OK == 1)
824 const unsigned char*
buf =
buf_;
829 ((unsigned)
buf[2] << 16) + ((unsigned)
buf[3] << 24);
851 #if defined(BMAVX2OPT)
852 __m256i* buf_start = (__m256i*)
buf_;
854 __m256i* buf_end = (__m256i*)
buf_;
857 #elif defined(BMSSE42OPT) || defined(BMSSE2OPT)
867 for (
unsigned i = 0;
i < count;
i+=4)
869 acc &= (w[
i+0] |= get_32());
870 acc &= (w[
i+1] |= get_32());
871 acc &= (w[
i+2] |= get_32());
872 acc &= (w[
i+3] |= get_32());
874 return acc == not_acc;
892 #if defined(BMAVX2OPT)
893 __m256i* buf_start = (__m256i*)
buf_;
895 __m256i* buf_end = (__m256i*)
buf_;
898 #elif defined(BMSSE42OPT) || defined(BMSSE2OPT)
905 for (
unsigned i = 0;
i < count;
i+=4)
931 #if (BM_UNALIGNED_ACCESS_OK == 1)
935 const unsigned char*
buf =
buf_;
971 ((unsigned)
buf_[2] << 16);
980 ((unsigned)
buf_[2] << 8) + ((unsigned)
buf_[3]);
1022 const unsigned char*
buf =
buf_;
1027 ((unsigned)
buf[2] << 8) + ((unsigned)
buf[3]);
1030 }
while (w < w_end);
1046 for (
unsigned i = 0;
i < count;
i+=4)
1053 return acc == not_acc;
1059 for (
unsigned i = 0;
i < count;
i+=4)
1078 const unsigned char*
buf =
buf_;
1087 }
while (s < s_end);
1094 template<
typename TEncoder>
1098 accum_ |= (
value << used_bits_);
1099 if (++used_bits_ == (
sizeof(accum_) * 8))
1105 template<
typename TEncoder>
1108 unsigned used = used_bits_;
1109 unsigned acc = accum_;
1112 unsigned mask = ~0u;
1113 mask >>= (
sizeof(accum_) * 8) - count;
1118 unsigned free_bits = unsigned(
sizeof(accum_) * 8) - used;
1120 acc |=
value << used;
1122 if (count <= free_bits)
1129 value >>= free_bits;
1136 if (used == (
sizeof(accum_) * 8))
1147 template<
typename TEncoder>
1150 if (++used_bits_ == (
sizeof(accum_) * 8))
1156 template<
typename TEncoder>
1159 unsigned used = used_bits_;
1160 unsigned free_bits = (
sizeof(accum_) * 8) - used;
1161 if (count >= free_bits)
1167 for ( ;count >=
sizeof(accum_) * 8; count -=
sizeof(accum_) * 8)
1177 accum_ |= (1u << used);
1178 if (++used == (
sizeof(accum_) * 8))
1186 template<
typename TEncoder>
1195 unsigned used = used_bits_;
1196 unsigned acc = accum_;
1197 const unsigned acc_bits = (
sizeof(acc) * 8);
1198 unsigned free_bits = acc_bits - used;
1201 unsigned count = logv;
1202 if (count >= free_bits)
1208 for ( ;count >= acc_bits; count -= acc_bits)
1219 if (++used == acc_bits)
1229 unsigned mask = (~0u);
1230 mask >>= acc_bits - logv;
1235 acc |=
value << used;
1236 free_bits = acc_bits - used;
1237 if (logv <= free_bits)
1244 value >>= free_bits;
1258 template<
typename TEncoder>
1267 unsigned mid_idx = sz >> 1;
1273 unsigned r = hi - lo - sz + 1;
1276 unsigned value =
val - lo - mid_idx;
1278 put_bits(
value, logv+1);
1293 template<
typename TEncoder>
1302 unsigned mid_idx = sz >> 1;
1308 unsigned r = hi - lo - sz + 1;
1311 unsigned value =
val - lo - mid_idx;
1315 unsigned c = (unsigned)(1ull << (logv + 1)) -
n;
1318 int64_t lo1 = half_r - half_c;
1319 int64_t hi1 = half_r + half_c + 1;
1321 logv += (value <= lo1 || value >= hi1);
1323 put_bits(
value, logv);
1327 bic_encode_u32_cm(
arr, mid_idx, lo,
val-1);
1343 template<
unsigned N>
1344 struct bic_encode_stack_u16
1351 unsigned stack_size_ = 0;
1361 unsigned r = hi - lo - sz + 1;
1364 unsigned s = stack_size_++;
1381 template<
typename TEncoder>
1389 bic_encode_stack_u16<bm::bie_cut_off> u16_stack;
1393 BM_ASSERT(sz_i == u16_stack.stack_size_);
1394 for (
unsigned i = 0;
i < sz_i; ++
i)
1399 unsigned r = u16_stack.r_[
i];
1401 unsigned value =
val - lo - mid_idx;
1404 unsigned c = (unsigned)(1ull << (logv + 1)) -
n;
1408 int64_t lo1 = half_r - half_c;
1409 int64_t hi1 = half_r + half_c + 1;
1411 logv += (value <= lo1 || value >= hi1);
1413 put_bits(
value, logv);
1419 template<
typename TEncoder>
1428 unsigned mid_idx = sz >> 1;
1434 unsigned r = hi - lo - sz + 1;
1437 unsigned value =
val - lo - mid_idx;
1441 unsigned c = (unsigned)(1ull << (logv + 1)) -
n;
1442 unsigned half_c = c >> 1;
1443 unsigned half_r =
r >> 1;
1445 unsigned hi1 = (half_r + half_c);
1446 logv += (value <= lo1 || value > hi1);
1448 put_bits(
value, logv);
1471 template<
class TDecoder>
1484 unsigned r = hi - lo - sz + 1;
1488 val = get_bits(logv);
1496 unsigned mid_idx = sz >> 1;
1497 val += lo + mid_idx;
1515 template<
class TDecoder>
1526 unsigned val = hi - lo - sz + 1;
1531 unsigned c = unsigned((1ull << (logv + 1)) -
val - 1);
1534 int64_t lo1 = half_r - half_c - ((
val + 1) & 1);
1535 int64_t hi1 = half_r + half_c + 1;
1537 val = get_bits(logv);
1538 if (val <= lo1 || val >= hi1)
1539 val += (get_bit() << logv);
1542 unsigned mid_idx = sz >> 1;
1543 val += lo + mid_idx;
1549 bic_decode_u32_cm(
arr, mid_idx, lo,
val-1);
1560 template<
class TDecoder>
1571 unsigned val = hi - lo - sz + 1;
1576 unsigned c = unsigned((1ull << (logv + 1)) -
val - 1);
1579 int64_t lo1 = half_r - half_c - ((
val + 1) & 1);
1580 int64_t hi1 = half_r + half_c + 1;
1581 val = get_bits(logv);
1582 if (val <= lo1 || val >= hi1)
1583 val += (get_bit() << logv);
1586 unsigned mid_idx = sz >> 1;
1587 val += lo + mid_idx;
1604 template<
class TDecoder>
1615 unsigned val = hi - lo - sz + 1;
1620 unsigned c = unsigned((1ull << (logv + 1)) -
val - 1);
1623 int64_t lo1 = half_r - half_c - ((
val + 1) & 1);
1624 int64_t hi1 = half_r + half_c + 1;
1626 val = get_bits(logv);
1627 if (val <= lo1 || val >= hi1)
1628 val += (get_bit() << logv);
1631 unsigned mid_idx = sz >> 1;
1632 val += lo + mid_idx;
1653 template<
class TDecoder>
1668 unsigned r = hi - lo - sz + 1;
1673 unsigned c = unsigned((1ull << (logv + 1)) -
r - 1);
1676 int64_t lo1 = half_r - half_c - ((
r + 1) & 1);
1677 int64_t hi1 = half_r + half_c + 1;
1679 if (r <= lo1 || r >= hi1)
1680 r += (get_bit() << logv);
1685 unsigned mid_idx = sz >> 1;
1686 val += lo + mid_idx;
1702 template<
class TDecoder>
1715 unsigned r = hi - lo - sz + 1;
1719 val = get_bits(logv);
1727 unsigned mid_idx = sz >> 1;
1728 val += lo + mid_idx;
1750 template<
class TDecoder>
1762 unsigned r = hi - lo - sz + 1;
1766 val = get_bits(logv);
1774 unsigned mid_idx = sz >> 1;
1775 val += lo + mid_idx;
1791 template<
class TDecoder>
1794 unsigned acc = accum_;
1795 unsigned used = used_bits_;
1797 if (used == (
sizeof(acc) * 8))
1799 acc = src_.get_32();
1802 unsigned zero_bits = 0;
1807 zero_bits = unsigned(zero_bits +(
sizeof(acc) * 8) - used);
1809 acc = src_.get_32();
1812 unsigned first_bit_idx =
1813 #if defined(BM_x86) && (defined(__GNUG__) || defined(_MSC_VER)) && !(defined(__arm64__) || defined(__arm__))
1818 acc >>= first_bit_idx;
1819 zero_bits += first_bit_idx;
1820 used += first_bit_idx;
1826 if (used == (
sizeof(acc) * 8))
1828 acc = src_.get_32();
1840 unsigned free_bits = unsigned((
sizeof(acc) * 8) - used);
1841 if (zero_bits <= free_bits)
1851 if (used == (
sizeof(acc) * 8))
1853 acc = src_.get_32();
1861 acc = src_.get_32();
1862 used = zero_bits - free_bits;
1876 template<
class TDecoder>
1880 const unsigned maskFF = ~0u;
1881 unsigned acc = accum_;
1882 unsigned used = used_bits_;
1885 unsigned free_bits = unsigned((
sizeof(acc) * 8) - used);
1886 if (count <= free_bits)
1889 value = acc & (maskFF >> (32 - count));
1894 if (used == (
sizeof(acc) * 8))
1896 acc = src_.get_32();
1901 acc = src_.get_32();
1902 used = count - free_bits;
1903 value |= ((acc & (maskFF >> (32 - used))) << free_bits);
1913 template<
class TDecoder>
1916 const unsigned mask = (~0u) >> (32 - 1);
1918 if (
unsigned free_bits =
unsigned(32u - used_bits_); free_bits)
1920 accum_ >>= 1; ++used_bits_;
1924 BM_ASSERT(used_bits_ == (
sizeof(accum_) * 8));
1925 unsigned a = src_.get_32();
1938 #pragma warning(pop)
Bit manipulation primitives (internal)
Byte based reader for un-aligned bit streaming.
unsigned used_bits_
Bits used in the accumulator.
bit_in & operator=(const bit_in &)
unsigned gamma() noexcept
decode unsigned value using Elias Gamma coding
void bic_decode_u32_cm(bm::word_t *arr, unsigned sz, bm::word_t lo, bm::word_t hi) noexcept
Binary Interpolative array decode (32-bit)
unsigned accum_
read bit accumulator
void bic_decode_u16_rg_dry(unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
Binary Interpolative array decode into /dev/null.
void bic_decode_u16_rg(bm::gap_word_t *arr, unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
Binary Interpolative array decode.
void bic_decode_u16_dry(unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
TDecoder & src_
Source of bytes.
void bic_decode_u16_cm(bm::gap_word_t *arr, unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
Binary Interpolative array decode.
unsigned get_bit() noexcept
read 1 bit
void bic_decode_u16_cm_dry(unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
Binary Interpolative array decode into /dev/null.
void bic_decode_u16_cm_bitset(bm::word_t *block, unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
Binary Interpolative array decode into bitset (32-bit based)
void bic_decode_u16_bitset(bm::word_t *block, unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
void bic_decode_u16_rg_bitset(bm::word_t *block, unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
Binary Interpolative array decode into bitset (32-bit based)
bit_in(TDecoder &decoder) noexcept
unsigned get_bits(unsigned count) noexcept
read number of bits out of the stream
Byte based writer for un-aligned bit streaming.
void bic_encode_u16_rg(const bm::gap_word_t *arr, unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
Binary Interpolative encoding (array of 16-bit ints)
TEncoder & dest_
Bit stream target.
bit_out & operator=(const bit_out &)
void put_zero_bits(unsigned count) noexcept
issue specified number of 0s
void bic_encode_u16_cm(const bm::gap_word_t *arr, unsigned sz, bm::gap_word_t lo, bm::gap_word_t hi) noexcept
Binary Interpolative encoding (array of 16-bit ints) cm - "center-minimal".
void gamma(unsigned value) noexcept
Elias Gamma encode the specified value.
unsigned accum_
write bit accumulator
void bic_encode_u32_cm(const bm::word_t *arr, unsigned sz, bm::word_t lo, bm::word_t hi) noexcept
Binary Interpolative encoding (array of 32-bit ints) cm - "center-minimal".
void flush() noexcept
Flush the incomplete 32-bit accumulator word.
unsigned used_bits_
Bits used in the accumulator.
void put_zero_bit() noexcept
issue 0 into output stream
void put_bit(unsigned value) noexcept
issue single bit into encode bit-stream
void put_bits(unsigned value, unsigned count) noexcept
issue count bits out of value
void flush_accum() noexcept
Base class for all decoding functionality.
const unsigned char * get_pos() const noexcept
Return current buffer pointer.
size_t size() const noexcept
Returns size of the current decoding stream.
bm::id64_t get_h64() noexcept
Read h-64-bit.
unsigned char get_8() noexcept
Reads character from the decoding buffer.
decoder_base(const unsigned char *buf) noexcept
void memcpy(unsigned char *dst, size_t count) noexcept
read bytes from the decode buffer
void set_pos(const unsigned char *pos) noexcept
Set current buffer pointer.
void seek(int delta) noexcept
change current position
const unsigned char * buf_
Class for decoding data from memory buffer.
decoder_little_endian(const unsigned char *buf)
bool get_32_OR(bm::word_t *w, unsigned count)
void get_32_AND(bm::word_t *w, unsigned count)
Class for decoding data from memory buffer.
void get_32_AND(bm::word_t *w, unsigned count) noexcept
Reads block of 32-bit words from the decoding buffer and ANDs to the destination.
decoder(const unsigned char *buf) noexcept
Construction.
bm::id64_t get_48() noexcept
Reads 64-bit word from the decoding buffer.
bool get_32_OR(bm::word_t *w, unsigned count) noexcept
Reads block of 32-bit words from the decoding buffer and ORs to the destination.
bm::id64_t get_64() noexcept
Reads 64-bit word from the decoding buffer.
bm::word_t get_24() noexcept
Reads 32-bit word from the decoding buffer.
bm::short_t get_16() noexcept
Reads 16-bit word from the decoding buffer.
bm::word_t get_32() noexcept
Reads 32-bit word from the decoding buffer.
unsigned char * position_type
void put_prefixed_array_32(unsigned char c, const bm::word_t *w, unsigned count) noexcept
Encode 8-bit prefix + an array.
void put_16(bm::short_t s) noexcept
Puts short word (16 bits) into the encoding buffer.
void put_24(bm::word_t w) noexcept
Puts 24 bits word into encoding buffer.
void put_32(bm::word_t w) noexcept
Puts 32 bits word into encoding buffer.
void put_64(bm::id64_t w) noexcept
Puts 64 bits word into encoding buffer.
void put_48(bm::id64_t w) noexcept
Puts 48 bits word into encoding buffer.
size_t size() const noexcept
Returns size of the current encoding stream.
void put_8(unsigned char c) noexcept
Puts one character into the encoding buffer.
void set_pos(unsigned char *buf_pos) noexcept
Set current memory stream position.
void put_h64(bm::id64_t w) noexcept
Puts 64 bits word into encoding buffer with h-compression.
encoder(unsigned char *buf, size_t size) noexcept
Construction.
void memcpy(const unsigned char *src, size_t count) noexcept
copy bytes into target buffer or just rewind if src is NULL
void put_prefixed_array_16(unsigned char c, const bm::short_t *s, unsigned count, bool encode_count) noexcept
Encode 8-bit prefix + an array.
unsigned char * get_pos() const noexcept
Get current memory stream position.
void put_8_16_32(unsigned w, unsigned char c8, unsigned char c16, unsigned char c32) noexcept
but gat plus value based on its VBR evaluation
gamma_decoder & operator=(const gamma_decoder &)
void stop()
Stop decoding sequence.
void start()
Start encoding sequence.
T operator()(void)
Decode word.
gamma_decoder(TBitIO &bin)
gamma_decoder(const gamma_decoder &)
Functor for Elias Gamma encoding.
gamma_encoder(TBitIO &bout)
gamma_encoder(const gamma_encoder &)
void operator()(T value)
Encode word.
gamma_encoder & operator=(const gamma_encoder &)
static vector< string > arr
bool avx2_or_arr_unal(__m256i *dst, const __m256i *src, const __m256i *src_end)
OR array elements against another unaligned array dst |= *src.
unsigned avx2_and_arr_unal(__m256i *dst, const __m256i *src, const __m256i *src_end)
AND array elements against another array (unaligned) dst &= *src.
bool sse2_or_arr_unal(__m128i *BMRESTRICT dst, const __m128i *BMRESTRICT src, const __m128i *BMRESTRICT src_end) BMNOEXCEPT
OR array elements against another array (unaligned) dst |= *src.
unsigned sse2_and_arr_unal(__m128i *BMRESTRICT dst, const __m128i *BMRESTRICT src, const __m128i *BMRESTRICT src_end) BMNOEXCEPT
AND array elements against another array (unaligned) dst &= *src.
decoder decoder_big_endian
Class for decoding data from memory buffer.
const unsigned set_word_shift
unsigned long long int id64_t
T bit_scan_fwd(T v) noexcept
unsigned compute_h64_mask(unsigned long long w) noexcept
Сompute mask of bytes presense in 64-bit word.
unsigned short gap_word_t
const unsigned set_word_mask
unsigned bit_scan_reverse32(unsigned w) noexcept
Int4 delta(size_t dimension_, const Int4 *score_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
Structure keeps all-left/right ON bits masks.