Pixie
Loading...
Searching...
No Matches
three_star.h
1#pragma once
2
3#ifndef PIXIE_3STAR_SUPPORT
4#error "ThreeStarRankSelectSupport requires PIXIE_THIRD_PARTY_BACKENDS"
5#endif
6
7#include <pixie/rank_select.h>
8
9#include <algorithm>
10#include <bit>
11#include <cstddef>
12#include <cstdint>
13#include <fstream>
14#include <span>
15
16// The upstream header emits unconditional construction diagnostics. Suppress
17// only those diagnostics so benchmark construction measures the index rather
18// than terminal I/O.
19#define printf(...) static_cast<void>(0)
20#include <m3.hpp>
21#undef printf
22
23static void print_overhead_line(const std::string&, int64_t) {}
24
25static void print_separator() {}
26
27namespace pixie {
28
41 : public RankSelectBase<ThreeStarRankSelectSupport> {
42 public:
49 std::span<const std::uint64_t> source_words,
50 std::size_t num_bits)
51 : num_bits_(std::min(num_bits, source_words.size() * kWordBits)) {
52 const std::size_t source_word_count =
53 (num_bits_ + kWordBits - 1) / kWordBits;
54 const std::size_t padded_word_count =
55 ((source_word_count + kWordsPerSuperblock - 1) / kWordsPerSuperblock) *
56 kWordsPerSuperblock;
57 const std::size_t stored_words =
58 padded_word_count + kSentinelSuperblocks * kWordsPerSuperblock;
59 N_bits = num_bits_;
60 // Upstream builds complete superblocks and copies sentinel blocks without
61 // checking the input vector's end. Supply initialized padding for both.
62 N_words = padded_word_count;
63 bits.assign(stored_words, 0);
64 one_count_ = 0;
65 for (std::size_t word_index = 0; word_index < source_word_count;
66 ++word_index) {
67 const std::uint64_t word =
68 logical_word(source_words, word_index, num_bits_);
69 bits[word_index] = word;
70 one_count_ += std::popcount(word);
71 }
72 N_ones = one_count_;
73 N_zeros = num_bits_ - one_count_;
74
75 // Match the paper's uncompressed robust configuration: L0=2048, a*,
76 // alpha=16, and its two-level L0/L1 summary tree.
77 ALPHA = 16;
78 SUMMARY_LEVELS = 1;
79 TREE3_STRATEGY = GET_LIFTED_CUBIC_THEORY_PARAMS;
80 BV_COMPRESSION = 0;
81
82 support_.build_auxiliaries();
83
84 source_copy_bytes_ = stored_words * sizeof(std::uint64_t);
85 }
86
88 std::size_t size_impl() const { return num_bits_; }
89
91 int bit_impl(std::size_t position) const {
92 return (bits[position / kWordBits] >> (position % kWordBits)) & 1;
93 }
94
96 std::uint64_t rank_impl(std::size_t end_position) const {
97 return end_position >= num_bits_ ? one_count_
98 : support_.rank_1(end_position);
99 }
100
102 std::uint64_t select_impl(std::size_t rank) const {
103 if (rank == 0) {
104 return 0;
105 }
106 return rank > one_count_ ? num_bits_ : support_.select_1(rank);
107 }
108
110 bool supports_select1_impl() const { return true; }
111
113 bool supports_select0_impl() const { return false; }
114
116 std::uint64_t select0_impl(std::size_t occurrence) const {
117 return occurrence == 0 ? 0 : size();
118 }
119
121 std::size_t memory_usage_bytes_impl() const {
122 return static_cast<std::size_t>(support_.space_in_bits() / 8);
123 }
124
126 std::size_t source_copy_bytes() const { return source_copy_bytes_; }
127
129 std::size_t index_logical_bytes() const {
130 return memory_usage_bytes() - source_copy_bytes_;
131 }
132
133 private:
134 static constexpr std::size_t kWordBits = 64;
135 static constexpr std::size_t kWordsPerSuperblock = 1024;
136 static constexpr std::size_t kSentinelSuperblocks = 5;
137
138 static std::uint64_t logical_word(std::span<const std::uint64_t> source,
139 std::size_t word_index,
140 std::size_t num_bits) {
141 std::uint64_t word = source[word_index];
142 const std::size_t remaining = num_bits - word_index * kWordBits;
143 if (remaining < kWordBits) {
144 word &= (std::uint64_t{1} << remaining) - 1;
145 }
146 return word;
147 }
148
149 m3 support_;
150 std::size_t num_bits_ = 0;
151 std::size_t one_count_ = 0;
152 std::size_t source_copy_bytes_ = 0;
153};
154
155} // namespace pixie
CRTP facade for immutable rank/select queries and bit access.
Definition rank_select.h:32
std::size_t memory_usage_bytes() const
Definition rank_select.h:135
std::size_t size() const
Definition rank_select.h:39
std::uint64_t rank(std::size_t end_position) const
Definition rank_select.h:66
std::uint64_t select0_impl(std::size_t occurrence) const
Return zero for occurrence zero, otherwise size(): disabled.
Definition three_star.h:116
ThreeStarRankSelectSupport(std::span< const std::uint64_t > source_words, std::size_t num_bits)
Build the upstream uncompressed 3-star configuration.
Definition three_star.h:48
int bit_impl(std::size_t position) const
Read a source bit; position must be below size().
Definition three_star.h:91
std::uint64_t rank_impl(std::size_t end_position) const
Return the one rank in [0, end_position).
Definition three_star.h:96
std::size_t index_logical_bytes() const
Return upstream-reported logical metadata bytes.
Definition three_star.h:129
std::uint64_t select_impl(std::size_t rank) const
Return the zero-based position of a one-based one rank.
Definition three_star.h:102
bool supports_select0_impl() const
3-star's upstream zero-select implementation is incomplete.
Definition three_star.h:113
bool supports_select1_impl() const
3-star implements one-select, but not zero-select.
Definition three_star.h:110
std::size_t memory_usage_bytes_impl() const
Return upstream-reported logical bytes for source and metadata.
Definition three_star.h:121
std::size_t source_copy_bytes() const
Return logical bytes in 3-star's uncompressed source copy.
Definition three_star.h:126
std::size_t size_impl() const
Return the logical source length.
Definition three_star.h:88
Common interface for rank/select support over packed bit sequences.