Skip to content
Draft
30 changes: 29 additions & 1 deletion CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -256,6 +256,15 @@ if (PIXIE_TESTS)
PRIVATE ${sdsl_lite_SOURCE_DIR}/include)
endif ()

add_executable(pivco_huffman_tests
src/tests/pivco_huffman_tests.cpp)
target_include_directories(pivco_huffman_tests
PUBLIC include)
target_link_libraries(pivco_huffman_tests
gtest
gtest_main
${PIXIE_DIAGNOSTICS_LIBS})

set(PIXIE_TEST_TARGETS
bit_algorithms_unittests
rank_select_unittests
Expand All@@ -267,7 +276,8 @@ if (PIXIE_TESTS)
storage_tests
excess_positions_tests
excess_record_lows_tests
rmq_tests)
rmq_tests
pivco_huffman_tests)
foreach (test_target IN LISTS PIXIE_TEST_TARGETS)
gtest_discover_tests(${test_target}
DISCOVERY_MODE PRE_TEST
Expand DownExpand Up@@ -399,6 +409,24 @@ if (PIXIE_BENCHMARKS)
benchmark
benchmark_main
${PIXIE_DIAGNOSTICS_LIBS})

add_executable(pivco_huffman_benchmarks
src/benchmarks/pivco_huffman_benchmarks.cpp)
target_include_directories(pivco_huffman_benchmarks
PUBLIC include)
target_link_libraries(pivco_huffman_benchmarks
benchmark
benchmark_main
${PIXIE_DIAGNOSTICS_LIBS})

add_executable(pivco_huffman_file_benchmarks
src/benchmarks/pivco_huffman_file_benchmarks.cpp)
target_include_directories(pivco_huffman_file_benchmarks
PUBLIC include)
target_link_libraries(pivco_huffman_file_benchmarks
benchmark
benchmark_main
${PIXIE_DIAGNOSTICS_LIBS})
endif ()

# ---------------------------------------------------------------------------
Expand Down
89 changes: 89 additions & 0 deletions include/pixie/huffman.h
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
#pragma once

/**
* @file huffman.h
* @brief Common CRTP contract for Huffman entropy codecs.
*
* PivCo-Huffman ("Pivot-Coded Huffman") reuses the wavelet-tree "tree of
* bitmaps" layout to turn sequential, bit-by-bit Huffman-tree traversals into
* vectorizable operations. A codec encodes a byte sequence into a compressed
* stream by building a Huffman-shaped tree of per-node bitmaps, and decodes it
* back by traversing that tree. Concrete implementations live under
* `<pixie/huffman/implementations.h>`.
*
* @see Marcin Zukowski, "PivCo-Huffman", v1.0 (2026).
*/

#include <cstddef>
#include <cstdint>
#include <span>
#include <vector>

namespace pixie {

/**
* @brief CRTP facade for Huffman entropy codecs.
*
* The contract is the source of truth for observable codec semantics. Each
* concrete implementation inherits `HuffmanBase<Impl>` and supplies the
* required `*_impl()` extension points. There is no virtual dispatch: the
* facade delegates statically through CRTP, mirroring the other Pixie families.
*
* Range and ownership conventions:
* - Symbol sequences are zero-based byte streams (`symbol_type`).
* - Compressed streams are byte-oriented views (`std::byte`).
* - The caller keeps any non-owning view alive for the codec lifetime.
*
* @tparam Impl Concrete codec type implementing the `*_impl()` contract.
*
* @see `<pixie/huffman/implementations.h>` for the available concrete
* implementations.
*/
template <class Impl>
class HuffmanBase {
public:
/** @brief Symbol type handled by the codec: one byte per symbol. */
using symbol_type = std::uint8_t;

/**
* @brief Number of symbols in the original (uncompressed) stream.
* @return Logical uncompressed symbol count.
*/
std::size_t uncompressed_size() const {
return impl().uncompressed_size_impl();
}

/**
* @brief Number of bytes in the compressed representation.
* @return Compressed stream size in bytes.
*/
std::size_t compressed_size() const { return impl().compressed_size_impl(); }

/**
* @brief Check whether the codec holds no data.
* @return `true` when `uncompressed_size() == 0`.
*/
bool empty() const { return uncompressed_size() == 0; }

/**
* @brief Read-only view of the compressed byte stream.
* @return Span over the serialized representation.
*
* @note The returned view is invalidated by codec destruction.
*/
std::span<const std::byte> compressed_data() const {
return impl().compressed_data_impl();
}

/**
* @brief Reconstruct the original symbol sequence.
* @return Decoded symbols of length `uncompressed_size()`.
*/
std::vector<symbol_type> decode() const { return impl().decode_impl(); }

private:
/** @brief Return this facade as its concrete CRTP implementation. */
const Impl& impl() const { return static_cast<const Impl&>(*this); }
};

} // namespace pixie
12 changes: 12 additions & 0 deletions include/pixie/huffman/implementations.h
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
#pragma once

/**
* @file implementations.h
* @brief All Huffman codec implementations provided by Pixie.
*
* - `PivCoHuffman`: simple scalar reference codec storing a Huffman-shaped
* tree of per-node routing bitmaps as packed 64-bit words.
*/

#include <pixie/huffman.h>
#include <pixie/huffman/pivco_huffman.h>
Loading
Loading