23#include <unordered_set>
27 template <
class P,
class Selector>
struct sort_profile_view;
28 template <
class P,
class Blob = cola_index<P>>
struct cola_query_cursor;
44 requires std::is_same_v<Blob, cola_index<P>> {
48 if (!source || source->virtual_size() > P::group_size)
49 error_detail::raise<std::invalid_argument>(
"COLA query root needs one bounded head group");
50 std::unordered_set<Blob const *> seen;
51 for (
auto current = source; current; current = current->main_target()) {
52 if (!seen.insert(current.get()).second) error_detail::raise<std::invalid_argument>(
"cyclic COLA main chain");
53 auto view = current->view();
54 auto main = current->main_target();
55 auto secondary = current->secondary_target();
57 if (view.borrowed(0).size() != (
main ?
main->group_count() : 0) ||
58 view.borrowed(1).size() != secondary_count / P::group_size + (secondary_count % P::group_size != 0))
59 error_detail::raise<std::invalid_argument>(
"COLA query target sample count mismatch");
73 namespace cola_detail {
83 std::array<std::optional<profile_blob_borrowed_predecessor<P>>, 2>
predecessors;
91 using view = std::remove_cvref_t<decltype(std::declval<Blob const &>().view())>;
92 using secondary = std::remove_cvref_t<decltype(std::declval<Blob const &>().secondary_target()->view())>;
102 return view.template search_window_with<first_window_result<P>>(group, context,
103 std::forward<Capture>(capture));
108 void operator()(
auto const &, std::uint64_t)
const noexcept {}
114 template <
class P,
class Blob,
class Query,
class Decode,
class Inspect = ignore_match_position>
115 requires std::same_as<std::remove_cvref_t<Query>,
bit_string> &&
116 (!std::is_reference_v<std::invoke_result_t<Decode &, bit_view>>) &&
121 -> std::optional<std::invoke_result_t<Decode &, bit_view>> {
122 using value_type = std::invoke_result_t<Decode &, bit_view>;
123 auto current = root.
head();
129 if constexpr (query_access::scoped_views<Blob>)
return query_access::borrow_query<P>(query);
132 if (!current) error_detail::raise<std::invalid_argument>(
"COLA query root has no head");
133 if (!current->virtual_size())
return std::nullopt;
134 std::uint64_t group = 0;
136 std::optional<value_type> value;
137 auto view = current->
view();
139 [&](std::uint64_t ordinal, bit_view encoded) {
140 std::invoke(inspect, view.native(), ordinal);
141 value.emplace(std::invoke(decode, encoded));
144 auto main = current->main_target();
145 auto secondary = current->secondary_target();
146 if (
auto const & next = result.predecessors[0])
147 if (!
main || next->target_ordinal % P::group_size || next->target_ordinal >=
main->virtual_size())
148 error_detail::raise<std::invalid_argument>(
"COLA query main route has no target");
149 if (
auto const & next = result.predecessors[1]) {
150 if (!
secondary) error_detail::raise<std::invalid_argument>(
"COLA query secondary route has no target");
152 visit_secondary<P>(side, *next, [&](std::uint64_t ordinal, bit_view encoded) {
154 std::invoke(inspect, side, ordinal);
155 value.emplace(std::invoke(decode, encoded));
159 if (value)
return value;
160 if (
auto & next = result.predecessors[0]) {
161 group = next->target_ordinal / P::group_size;
162 context = std::move(next->comparison);
163 current = std::move(
main);
164 }
else current.reset();
186 pending_(std::move(other.pending_)),
failed_(other.failed_) { other.pending_ = {}; }
188 if (
this != &other) {
190 pending_ = std::move(other.pending_);
failed_ = other.failed_; other.pending_ = {};
197 std::uint64_t
step(std::uint64_t main_budget = 1) {
198 if (
failed_) error_detail::raise<std::logic_error>(
"COLA query cursor has failed");
200 std::uint64_t visited = 0;
202 while (
current_ && visited < main_budget) {
206 if (
auto const & next = result.predecessors[0])
207 if (!
main || next->target_ordinal % P::group_size || next->target_ordinal >=
main->virtual_size())
208 error_detail::raise<std::invalid_argument>(
"COLA query main route has no target");
209 std::optional<profile_blob_native_match<P>> side;
210 if (
auto const & next = result.predecessors[1]) {
211 if (!
secondary) error_detail::raise<std::invalid_argument>(
"COLA query secondary route has no target");
212 side = cola_search_secondary<P>(
secondary->view(), *next);
215 result.native->
ordinal, std::move(result.native->value)});
217 if (
auto & next = result.predecessors[0]) {
218 group_ = next->target_ordinal / P::group_size;
219 context_ = std::move(next->comparison);
225 }
catch (...) {
failed_ =
true;
throw; }
229 if (
failed_) error_detail::raise<std::logic_error>(
"COLA query cursor has failed");
231 if (!slot) error_detail::raise<std::logic_error>(
"COLA query cursor has no match");
232 auto result = std::move(*slot);
240 if (!
current_) error_detail::raise<std::invalid_argument>(
"COLA query root has no head");
Declares dual-target main/secondary fractional indexes for COLA.
auto first_value(cola_query_root< P, Blob > const &root, Query &&query, Decode &&decode, Inspect inspect={}) -> std::optional< std::invoke_result_t< Decode &, bit_view > >
Definition cola_query.h:120
bit_string value(arrow_t< S > const &value)
Definition typed_world.h:99
Definition active_engine.h:18
stream_role
Definition policy.h:25
bit_view view() const &
Definition profile.h:178
Definition cola_query.h:81
bool native
Definition cola_query.h:82
std::array< std::optional< profile_blob_borrowed_predecessor< P > >, 2 > predecessors
Definition cola_query.h:83
Definition cola_query.h:107
void operator()(auto const &, std::uint64_t) const noexcept
Definition cola_query.h:108
Definition cola_query.h:96
bool operator()(std::uint64_t, bit_view) const
Definition cola_query.h:97
Definition cola_query.h:85
static constexpr bool scoped_views
Definition cola_query.h:90
static profile_query_context< P > borrow_query(bit_string const &&)=delete
static profile_query_context< P > borrow_query(bit_string const &query)
Definition cola_query.h:86
static first_window_result< P > search(cola_index_view< P, Family > const &view, std::uint64_t group, profile_query_context< P > const &context, Capture &&capture)
Definition cola_query.h:99
Definition cola_query.h:79
Definition cola_query.h:76
Definition cola_index.h:114
Definition cola_query.h:237
Definition cola_query.h:173
bool done() const noexcept
Definition cola_query.h:195
cola_query_cursor(cola_query_root< P, Blob > const &root, bit_view query)
Definition cola_query.h:177
bool has_match() const noexcept
Definition cola_query.h:194
P policy_type
Definition cola_query.h:174
cola_query_cursor(cola_query_cursor &&other) noexcept
Definition cola_query.h:184
bool failed_
Definition cola_query.h:247
cola_query_cursor(cola_query_cursor const &)=default
cola_query_cursor(cola_query_root< P, Blob > const &root, profile_query_context< P > context, prepared_query)
Definition cola_query.h:238
std::uint64_t step(std::uint64_t main_budget=1)
Definition cola_query.h:197
cola_query_cursor & operator=(cola_query_cursor const &)=default
std::array< std::optional< match_type >, 2 > pending_
Definition cola_query.h:246
profile_query_context< P > context_
Definition cola_query.h:244
std::uint64_t group_
Definition cola_query.h:245
match_type take_match()
Definition cola_query.h:228
std::shared_ptr< Blob const > pair_type
Definition cola_query.h:175
static cola_query_cursor from_owned(cola_query_root< P, Blob > const &root, bit_string query)
Definition cola_query.h:179
bool failed() const noexcept
Definition cola_query.h:196
pair_type current_
Definition cola_query.h:243
cola_query_cursor & operator=(cola_query_cursor &&other) noexcept
Definition cola_query.h:187
Definition cola_query.h:33
std::shared_ptr< Blob const > source
Definition cola_query.h:34
bit_string value
Definition cola_query.h:37
bool secondary
Definition cola_query.h:35
std::uint64_t ordinal
Definition cola_query.h:36
Definition cola_query.h:40
cola_query_root(pair_type head)
Definition cola_query.h:69
static cola_query_root adopt_prepared(pair_type source)
Definition cola_query.h:47
P policy_type
Definition cola_query.h:41
std::shared_ptr< Blob const > pair_type
Definition cola_query.h:42
static cola_query_root build(pair_type main={}, typename Blob::native_pointer secondary={})
Definition cola_query.h:43
pair_type head() const noexcept
Definition cola_query.h:63
cola_query_cursor< P, Blob > cursor(bit_view query) const
Definition cola_query.h:64
pair_type head_
Definition cola_query.h:70
cola_query_cursor< P, Blob > cursor_owned(bit_string query) const
Definition cola_query.h:65
static profile_query_context from_borrowed(bit_string const &query)
Definition profile.h:400
static profile_query_context from_owned(bit_string query)
Definition profile.h:336
Definition sort_profile.h:176