diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/compproto/compressor.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/compproto/compressor.h')
-rw-r--r-- | library/cpp/compproto/compressor.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/library/cpp/compproto/compressor.h b/library/cpp/compproto/compressor.h new file mode 100644 index 00000000000..14b335e13ca --- /dev/null +++ b/library/cpp/compproto/compressor.h @@ -0,0 +1,74 @@ +#pragma once + +#include <util/system/defaults.h> + +namespace NCompProto { + struct TEmpty { + }; + + struct TTable { + TTable() { + for (size_t i = 0; i < 64; ++i) { + CodeBase[i] = 0; + CodeMask[i] = 0; + Length[i] = 0; + PrefLength[i] = 0; + Id[i] = 0; + } + } + ui32 CodeBase[64]; + ui32 CodeMask[64]; + ui8 Length[64]; + ui8 PrefLength[64]; + ui8 Id[64]; + enum { + PAGE_BOUND = 4096, +#ifdef WITH_VALGRIND + SAFE_MODE = 1, +#else +#if defined(__has_feature) +#if __has_feature(address_sanitizer) + SAFE_MODE = 1, +#else + SAFE_MODE = 0, +#endif +#else + SAFE_MODE = 0, +#endif +#endif + }; + ui32 inline Decompress(const ui8* codes, ui64& offset) const { + codes += (offset >> 3); + size_t pageOff = size_t(codes) % PAGE_BOUND; + size_t readOff = offset & 7; + if (pageOff > PAGE_BOUND - 8 || SAFE_MODE) { + size_t off = 8; + ui64 res = codes[0]; + ++codes; + ui64 indexCur = ((res + 0x0000) >> readOff) & 63; + ui64 indexAlt = ((res + 0xff00) >> readOff) & 63; + if (Id[indexCur] != Id[indexAlt]) { + res += (ui64(codes[0]) << off); + ++codes; + off += 8; + indexCur = (res >> readOff) & 63; + } + ui64 index = indexCur; + ui64 length = Length[index]; + while (off < readOff + length) { + res += (ui64(codes[0]) << off); + ++codes; + off += 8; + } + offset += length; + ui64 code = res >> readOff; + return (((ui32)(code >> PrefLength[index])) & CodeMask[index]) + CodeBase[index]; + } + ui64 code = ((const ui64*)(codes))[0] >> readOff; + ui64 index = code & 63; + offset += Length[index]; + return (((ui32)(code >> PrefLength[index])) & CodeMask[index]) + CodeBase[index]; + } + }; + +} |