#ifndef CPC_COMPRESSOR_HPP_
#define CPC_COMPRESSOR_HPP_
#include "cpc_common.hpp"
namespace datasketches {
template<typename A> class cpc_sketch_alloc;
template<typename A> class cpc_compressor;
template<typename A>
inline cpc_compressor<A>& get_compressor();
template<typename A>
void destroy_compressor();
template<typename A>
class cpc_compressor {
public:
using vector_bytes = std::vector<uint8_t, typename std::allocator_traits<A>::template rebind_alloc<uint8_t>>;
using vector_u32 = std::vector<uint32_t, typename std::allocator_traits<A>::template rebind_alloc<uint32_t>>;
void compress(const cpc_sketch_alloc<A>& source, compressed_state<A>& target) const;
void uncompress(const compressed_state<A>& source, uncompressed_state<A>& target, uint8_t lg_k, uint32_t num_coupons) const;
uint32_t low_level_compress_bytes(
const uint8_t* byte_array, uint32_t num_bytes_to_encode,
const uint16_t* encoding_table,
uint32_t* compressed_words ) const;
void low_level_uncompress_bytes(
uint8_t* byte_array, uint32_t num_bytes_to_decode,
const uint16_t* decoding_table,
const uint32_t* compressed_words,
uint32_t num_compressed_words ) const;
uint32_t low_level_compress_pairs(
const uint32_t* pair_array, uint32_t num_pairs_to_encode,
uint8_t num_base_bits,
uint32_t* compressed_words ) const;
void low_level_uncompress_pairs(
uint32_t* pair_array, uint32_t num_pairs_to_decode,
uint8_t num_base_bits,
const uint32_t* compressed_words, uint32_t num_compressed_words ) const;
private:
uint16_t* decoding_tables_for_high_entropy_byte[22] = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL
};
uint16_t* length_limited_unary_decoding_table65;
uint8_t* column_permutations_for_decoding[16] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
cpc_compressor();
friend cpc_compressor& get_compressor<A>();
~cpc_compressor();
friend void destroy_compressor<A>();
void make_decoding_tables(); void free_decoding_tables();
void compress_sparse_flavor(const cpc_sketch_alloc<A>& source, compressed_state<A>& target) const;
void compress_hybrid_flavor(const cpc_sketch_alloc<A>& source, compressed_state<A>& target) const;
void compress_pinned_flavor(const cpc_sketch_alloc<A>& source, compressed_state<A>& target) const;
void compress_sliding_flavor(const cpc_sketch_alloc<A>& source, compressed_state<A>& target) const;
void uncompress_sparse_flavor(const compressed_state<A>& source, uncompressed_state<A>& target, uint8_t lg_k) const;
void uncompress_hybrid_flavor(const compressed_state<A>& source, uncompressed_state<A>& target, uint8_t lg_k) const;
void uncompress_pinned_flavor(const compressed_state<A>& source, uncompressed_state<A>& target, uint8_t lg_k, uint32_t num_coupons) const;
void uncompress_sliding_flavor(const compressed_state<A>& source, uncompressed_state<A>& target, uint8_t lg_k, uint32_t num_coupons) const;
uint8_t* make_inverse_permutation(const uint8_t* permu, unsigned length);
uint16_t* make_decoding_table(const uint16_t* encoding_table, unsigned num_byte_values);
void validate_decoding_table(const uint16_t* decoding_table, const uint16_t* encoding_table) const;
void compress_surprising_values(const vector_u32& pairs, uint8_t lg_k, compressed_state<A>& result) const;
void compress_sliding_window(const uint8_t* window, uint8_t lg_k, uint32_t num_coupons, compressed_state<A>& target) const;
vector_u32 uncompress_surprising_values(const uint32_t* data, uint32_t data_words, uint32_t num_pairs, uint8_t lg_k, const A& allocator) const;
void uncompress_sliding_window(const uint32_t* data, uint32_t data_words, vector_bytes& window, uint8_t lg_k, uint32_t num_coupons) const;
static size_t safe_length_for_compressed_pair_buf(uint32_t k, uint32_t num_pairs, uint8_t num_base_bits);
static size_t safe_length_for_compressed_window_buf(uint32_t k);
static uint8_t determine_pseudo_phase(uint8_t lg_k, uint32_t c);
static inline vector_u32 tricky_get_pairs_from_window(const uint8_t* window, uint32_t k, uint32_t num_pairs_to_get, uint32_t empty_space, const A& allocator);
static inline uint8_t golomb_choose_number_of_base_bits(uint32_t k, uint64_t count);
};
}
#include "cpc_compressor_impl.hpp"
#endif