2 #ifndef BV_QUERY_SUPPORT_HPP
3 #define BV_QUERY_SUPPORT_HPP
14 template <
class dtype,
class leaf_type>
19 dtype internal_offset;
22 r_elem(dtype size, dtype sum, dtype offset, leaf_type* l) {
27 internal_offset = offset;
48 template <
class dtype,
class leaf_type, dtype block_size>
53 std::vector<r_elem<dtype, leaf_type>> elems_ =
54 std::vector<r_elem<dtype, leaf_type>>();
67 dtype i = elems_.size();
69 while (size_ + a_size > i * block_size) {
70 dtype i_rank =
leaf->
rank(i * block_size - size_);
89 if (sum_ <= elems_.size()) {
90 for (
size_t i = 0; i < sum_; i++) {
93 [[unlikely]] (void(0));
95 for (
size_t i = 0; i < elems_.size(); i++) {
96 elems_[i].select_index =
97 s_select(1 + (i * sum_) / elems_.size());
107 dtype
size()
const {
return size_; }
113 dtype
p_sum()
const {
return sum_; }
124 bool at(dtype i)
const {
125 dtype idx = i / block_size;
127 if (e.p_size + e.leaf->size() <= i) {
128 [[unlikely]] e = elems_[idx + 1];
130 return e.leaf->at(i - e.p_size);
147 dtype idx = block_size;
150 if (e.p_size + e.leaf->size() < i) {
152 [[unlikely]]
return e.p_sum + e.leaf->rank(i - e.p_size);
154 dtype offs = idx * block_size - e.p_size;
155 return e.p_sum + e.internal_offset + e.leaf->rank(i - e.p_size, offs);
179 if (i == 0) [[unlikely]]
181 if (sum_ <= elems_.size()) {
182 [[unlikely]]
return elems_[i - 1].select_index;
184 dtype idx = elems_.size() * i / (sum_ + 1);
185 if (idx == elems_.size()) {
188 dtype a_idx = elems_[idx].select_index;
190 idx < elems_.size() - 1 ? elems_[idx + 1].select_index : a_idx;
191 if (b_idx - a_idx > 1) {
195 if (e.p_sum + e.leaf->p_sum() < i) {
196 e = elems_[a_idx + 1];
197 [[unlikely]]
return e.p_size + e.leaf->select(i - e.p_sum);
199 dtype s_pos = a_idx * block_size - e.p_size;
201 [[unlikely]]
return e.p_size + e.leaf->select(i - e.p_sum);
203 return e.p_size + e.leaf->select(i - e.p_sum,
204 a_idx * block_size - e.p_size,
227 void print(
bool internal_only)
const {
228 std::cout <<
"{\n\"type\": \"rank_support\",\n"
229 <<
"\"size\": " << size_ <<
",\n"
230 <<
"\"sum\": " << sum_ <<
",\n"
231 <<
"\"number of elems\": " << elems_.size() <<
",\n"
233 for (
size_t i = 0; i < elems_.size(); i++) {
234 std::cout << elems_[i].p_size;
235 if (i != elems_.size() - 1) {
241 for (
size_t i = 0; i < elems_.size(); i++) {
242 std::cout << elems_[i].p_sum;
243 if (i != elems_.size() - 1) {
248 <<
"\"internal_offsets\": [";
249 for (
size_t i = 0; i < elems_.size(); i++) {
250 std::cout << elems_[i].internal_offset;
251 if (i != elems_.size() - 1) {
256 <<
"\"select_index\": [";
257 for (
size_t i = 0; i < elems_.size(); i++) {
258 std::cout << elems_[i].select_index;
259 if (i != elems_.size() - 1) {
265 for (uint8_t i = 0; i < elems_.size(); i++) {
266 elems_[i].leaf->print(internal_only);
267 if (i != elems_.size() - 1) {
272 std::cout <<
"]}" << std::endl;
287 dtype b = elems_.size() - 1;
289 dtype m = (idx + b + 1) / 2;
290 if (elems_[m].
p_sum + elems_[m].internal_offset >= i) {
297 while (e.p_sum + e.leaf->p_sum() < i) {
299 [[unlikely]] e = elems_[idx];
317 dtype b = elems_.size() - 1;
319 dtype m = (idx + b + 1) / 2;
320 if (elems_[m].
p_sum >= i) {
327 while (e.p_sum + e.leaf->p_sum() < i) {
329 [[unlikely]] e = elems_[idx];
331 return e.p_size + e.leaf->select(i - e.p_sum);