6 #ifndef TURI_SFRAME_INTEGER_PACK_HPP 7 #define TURI_SFRAME_INTEGER_PACK_HPP 12 #include <core/logging/assertions.hpp> 13 #include <core/storage/sframe_data/integer_pack_impl.hpp> 14 #include <core/util/bitops.hpp> 29 namespace integer_pack {
69 template <
typename OutArcType>
71 if ((s >> (8-1)) == 0) {
73 unsigned char trunc_s = s << 1;
74 oarc.direct_assign(trunc_s);
76 else if ((s >> (16-2)) == 0) {
80 trunc_s = (trunc_s << 2) | 1;
81 oarc.direct_assign(trunc_s);
83 else if ((s >> (24-3)) == 0) {
86 uint32_t trunc_s =
static_cast<uint32_t
>(s);
87 trunc_s = (trunc_s << 3) | 3;
88 oarc.write((
char*)(&trunc_s), 3);
90 else if ((s >> (32-4)) == 0) {
93 uint32_t trunc_s =
static_cast<uint32_t
>(s);
94 trunc_s = (trunc_s << 4) | 7;
95 oarc.direct_assign(trunc_s);
97 else if ((s >> (40-5)) == 0) {
100 uint64_t trunc_s = s;
101 trunc_s = (trunc_s << 5) | 15;
102 oarc.write((
char*)(&trunc_s), 5);
104 else if ((s >> (48-6)) == 0) {
107 uint64_t trunc_s = s;
108 trunc_s = (trunc_s << 6) | 31;
109 oarc.write((
char*)(&trunc_s), 6);
111 else if ((s >> (56-7)) == 0) {
114 uint64_t trunc_s = s;
115 trunc_s = (trunc_s << 7) | 63;
116 oarc.write((
char*)(&trunc_s), 7);
120 unsigned char c = 127;
121 oarc.direct_assign(c);
122 oarc.direct_assign(s);
130 template <
typename InArcType>
137 iarc.read(c.chars, 1);
138 if ((c.intval & 1) == 0) {
140 }
else if ((c.intval & 3) == 1) {
142 iarc.read(c.chars + 1, 1);
144 }
else if ((c.intval & 7) == 3) {
146 iarc.read(c.chars + 1, 2);
148 }
else if ((c.intval & 15) == 7) {
149 iarc.read(c.chars + 1, 3);
151 }
else if ((c.intval & 31) == 15) {
152 iarc.read(c.chars + 1, 4);
154 }
else if ((c.intval & 63) == 31) {
155 iarc.read(c.chars + 1, 5);
157 }
else if ((c.intval & 127) == 63) {
158 iarc.read(c.chars + 1, 6);
162 iarc.read(c.chars, 8);
179 int64_t sign = (val >> 63);
181 uint64_t absval = (val + sign) ^ sign;
182 return (absval << 1) + sign;
191 int64_t sign = -(int64_t)(val & 1);
192 uint64_t absval = (val >> 1) - sign;
194 return (absval + sign) ^ sign;
280 template <
typename OutArcType>
285 if (len == 0)
return;
286 DASSERT_LE(len, 128);
300 uint64_t minvalue = input[0];
303 uint64_t delta_negative[128];
304 unsigned char nbits = 0;
305 unsigned char nbits_frame = 0, nbits_delta = 255, nbits_delta_negative = 255;
306 bool is_incremental =
true;
307 for (
size_t i = 0;i < len; ++i) {
308 minvalue = std::min(minvalue, input[i]);
309 if (i > 0 && input[i] < input[i-1]) {is_incremental =
false;
break;}
313 frame[0] = input[0] - minvalue;
314 uint64_t all_or_frame = frame[0];
316 if (is_incremental) {
321 for (
size_t i = 1; i < len; ++i) {
322 delta[i] = input[i] - input[i-1];
324 frame[i] = input[i] - minvalue;
325 all_or_frame |= frame[i];
330 nbits_delta_negative = 0;
331 delta_negative[0] = input[0];
334 for (
size_t i = 1;i < len; ++i) {
336 all_or |= delta_negative[i];
337 frame[i] = input[i] - minvalue;
338 all_or_frame |= frame[i];
346 unsigned char coding_technique = 0;
347 if (nbits_frame <= nbits_delta && nbits_frame <= nbits_delta_negative) {
351 }
else if (nbits_delta <= nbits_frame && nbits_delta <= nbits_delta_negative) {
356 nbits = nbits_delta_negative;
358 input = delta_negative;
363 nbits = nbits| (nbits >> 1);
364 nbits = nbits| (nbits >> 2);
365 nbits = nbits| (nbits >> 4);
367 unsigned char header = coding_technique;
370 header = header + (shiftpos << 2);
372 oarc.direct_assign(header);
374 if (coding_technique == FRAME_OF_REFERENCE) {
376 }
else if (coding_technique == FRAME_OF_REFERENCE_DELTA ||
377 coding_technique == FRAME_OF_REFERENCE_DELTA_NEGATIVE) {
382 if (nbits == 0)
return;
385 size_t bytes_used = 0;
388 bytes_used =
pack_1(input, len, pack);
389 oarc.write((
char*)pack, bytes_used);
392 bytes_used =
pack_2(input, len, pack);
393 oarc.write((
char*)pack, bytes_used);
396 bytes_used =
pack_4(input, len, pack);
397 oarc.write((
char*)pack, bytes_used);
400 bytes_used =
pack_8(input, len, pack);
401 oarc.write((
char*)pack, bytes_used);
404 bytes_used =
pack_16(input, len, (uint16_t*)pack);
405 oarc.write((
char*)pack, bytes_used);
408 bytes_used =
pack_32(input, len, (uint32_t*)pack);
409 oarc.write((
char*)pack, bytes_used);
412 oarc.write((
char*)input,
sizeof(uint64_t)*len);
416 __builtin_unreachable();
426 template <
typename InArcType>
430 if (len == 0)
return;
431 DASSERT_LE(len, 128);
432 unsigned char header;
433 iarc.read_into(header);
434 unsigned char nbits = 0;
438 if (shiftpos > 0) nbits = 1 << (shiftpos - 1);
443 for (
size_t i = 0;i < len; ++i) output[i] = minvalue;
447 if (coding_technique == FRAME_OF_REFERENCE) {
449 }
else if (coding_technique == FRAME_OF_REFERENCE_DELTA ||
450 coding_technique == FRAME_OF_REFERENCE_DELTA_NEGATIVE) {
457 size_t nbits_to_read = (size_t)(nbits) * len;
458 size_t nbytes_to_read = (nbits_to_read + 7) / 8;
461 iarc.read((
char*)pack, nbytes_to_read);
465 iarc.read((
char*)pack, nbytes_to_read);
469 iarc.read((
char*)pack, nbytes_to_read);
473 iarc.read((
char*)pack, nbytes_to_read);
477 iarc.read((
char*)pack, nbytes_to_read);
481 iarc.read((
char*)pack, nbytes_to_read);
485 iarc.read((
char*)output,
sizeof(uint64_t)*len);
489 __builtin_unreachable();
493 if (coding_technique == FRAME_OF_REFERENCE) {
494 for (
size_t i = 0;i < len; ++i) {
495 output[i] += minvalue;
497 }
else if (coding_technique == FRAME_OF_REFERENCE_DELTA) {
498 for (
int i = 0;i < (int)len; ++i) {
500 output[i] += output[i-1];
502 }
else if (coding_technique == FRAME_OF_REFERENCE_DELTA_NEGATIVE) {
503 for (
int i = 0;i < (int)len; ++i) {
506 output[i] += output[i-1];
uint64_t shifted_integer_encode(int64_t val)
static void variable_decode(InArcType &iarc, uint64_t &s)
static void unpack_16(const uint16_t *src, size_t nout_values, uint64_t *out)
static size_t pack_32(const uint64_t *src, size_t srclen, uint32_t *out)
static unsigned int n_leading_zeros(T v, _ENABLE_IF_UINT(T))
static constexpr unsigned char FRAME_OF_REFERENCE_HEADER_NUM_BITS
static size_t pack_4(const uint64_t *src, size_t srclen, uint8_t *out)
static size_t pack_8(const uint64_t *src, size_t srclen, uint8_t *out)
void frame_of_reference_decode_128(InArcType &iarc, size_t len, uint64_t *output)
static constexpr unsigned char FRAME_OF_REFERENCE_HEADER_MASK
static void variable_encode(OutArcType &oarc, uint64_t s)
static size_t pack_16(const uint64_t *src, size_t srclen, uint16_t *out)
static size_t pack_2(const uint64_t *src, size_t srclen, uint8_t *out)
static void unpack_1(const uint8_t *src, size_t nout_values, uint64_t *out)
static void unpack_2(const uint8_t *src, size_t nout_values, uint64_t *out)
static void unpack_32(const uint32_t *src, size_t nout_values, uint64_t *out)
static void unpack_8(const uint8_t *src, size_t nout_values, uint64_t *out)
static size_t pack_1(const uint64_t *src, size_t srclen, uint8_t *out)
#define ASSERT_TRUE(cond)
GL_HOT void frame_of_reference_encode_128(const uint64_t *input, size_t len, OutArcType &oarc)
static constexpr unsigned char FRAME_OF_REFERENCE_DELTA
static void unpack_4(const uint8_t *src, size_t nout_values, uint64_t *out)
static constexpr unsigned char FRAME_OF_REFERENCE_DELTA_NEGATIVE
int64_t shifted_integer_decode(uint64_t val)
static constexpr unsigned char FRAME_OF_REFERENCE