Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff 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 Down Expand Up @@ -399,6 +409,15 @@ 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})
endif ()

# ---------------------------------------------------------------------------
Expand Down
89 changes: 89 additions & 0 deletions include/pixie/huffman.h
Original file line number Diff line number Diff 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 number Diff line number Diff 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