25namespace seqan3::detail
30enum class error_type : uint8_t
43template <
typename configuration_t,
typename index_t,
typename... policies_t>
44class unidirectional_search_algorithm :
protected policies_t...
48 using traits_t = search_traits<configuration_t>;
50 using search_result_type =
typename traits_t::search_result_type;
52 static_assert(!std::same_as<search_result_type, empty_type>,
"The search result type was not configured.");
58 unidirectional_search_algorithm() =
default;
59 unidirectional_search_algorithm(unidirectional_search_algorithm
const &) =
default;
60 unidirectional_search_algorithm(unidirectional_search_algorithm &&) =
default;
61 unidirectional_search_algorithm & operator=(unidirectional_search_algorithm
const &) =
default;
62 unidirectional_search_algorithm & operator=(unidirectional_search_algorithm &&) =
default;
63 ~unidirectional_search_algorithm() =
default;
75 unidirectional_search_algorithm(configuration_t
const & cfg, index_t
const & index) : policies_t{cfg}...
77 stratum = cfg.get_or(search_cfg::hit_strata{0}).stratum;
102 template <
typename indexed_query_t,
typename callback_t>
103 requires (std::tuple_size_v<indexed_query_t> == 2)
104 && std::ranges::forward_range<std::tuple_element_t<1, indexed_query_t>>
105 && std::invocable<callback_t, search_result_type>
106 void operator()(indexed_query_t && indexed_query, callback_t && callback)
108 auto && [query_idx, query] = indexed_query;
109 auto error_state = this->max_error_counts(query);
113 delegate = [&internal_hits](
auto const & it)
118 perform_search_by_hit_strategy(internal_hits, query, error_state);
120 this->make_results(std::move(internal_hits), query_idx, callback);
125 index_t
const * index_ptr{
nullptr};
128 std::function<void(
typename index_t::cursor_type
const &)> delegate;
134 template <
bool abort_on_hit,
typename query_t>
135 bool search_trivial(
typename index_t::cursor_type cur,
137 typename index_t::cursor_type::size_type
const query_pos,
138 search_param
const error_left,
139 error_type
const prev_error);
147 template <
typename query_t>
150 search_param error_state)
152 if constexpr (!traits_t::search_all_hits)
154 auto max_total = error_state.total;
155 error_state.total = 0;
157 while (internal_hits.
empty() && error_state.total <= max_total)
165 constexpr bool abort_on_hit = !traits_t::search_all_best_hits;
166 search_trivial<abort_on_hit>(index_ptr->cursor(), query, 0, error_state, error_type::none);
170 if constexpr (traits_t::search_strata_hits)
172 if (!internal_hits.
empty())
174 internal_hits.
clear();
175 error_state.total += stratum - 1;
176 search_trivial<false>(index_ptr->cursor(), query, 0, error_state, error_type::none);
184 search_trivial<false>(index_ptr->cursor(), query, 0, error_state, error_type::none);
208template <
typename configuration_t,
typename index_t,
typename... policies_t>
209template <
bool abort_on_hit,
typename query_t>
210inline bool unidirectional_search_algorithm<configuration_t, index_t, policies_t...>::search_trivial(
211 typename index_t::cursor_type cur,
213 typename index_t::cursor_type::size_type
const query_pos,
214 search_param
const error_left,
215 error_type
const prev_error)
221 using drop_size_t = std::ranges::range_difference_t<query_t>;
223 || cur.extend_right(
std::views::drop(query,
static_cast<drop_size_t
>(query_pos))))
234 bool const allow_insertion =
235 (cur.query_length() > 0) ? cur.last_rank() !=
seqan3::to_rank(query[query_pos]) : true;
237 if (allow_insertion && (prev_error != error_type::deletion || error_left.substitution == 0)
238 && error_left.insertion > 0)
240 search_param error_left2{error_left};
241 error_left2.insertion--;
246 if (search_trivial<abort_on_hit>(cur, query, query_pos + 1, error_left2, error_type::insertion)
254 if (((query_pos > 0 && error_left.deletion > 0) || error_left.substitution > 0) && cur.extend_right())
259 if (error_left.substitution > 0)
262 search_param error_left2{error_left};
263 error_left2.total -= delta;
264 error_left2.substitution -= delta;
266 if (search_trivial<abort_on_hit>(cur, query, query_pos + 1, error_left2, error_type::matchmm)
277 if (error_left.substitution == 0 && cur.last_rank() ==
seqan3::to_rank(query[query_pos]))
279 if (search_trivial<abort_on_hit>(cur, query, query_pos + 1, error_left, error_type::matchmm)
290 if ((prev_error != error_type::insertion || error_left.substitution == 0)
291 && error_left.deletion > 0)
293 search_param error_left2{error_left};
295 error_left2.deletion--;
300 if (search_trivial<abort_on_hit>(cur, query, query_pos, error_left2, error_type::deletion)
309 while (cur.cycle_back());
314 if (cur.extend_right(query[query_pos]))
316 if (search_trivial<abort_on_hit>(cur, query, query_pos + 1, error_left, error_type::matchmm)
Core alphabet concept and free function/type trait wrappers.
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:155
@ none
No flag is set.
Definition: debug_stream_type.hpp:32
typename decltype(detail::split_after< i >(list_t{}))::second_type drop
Return a seqan3::type_list of the types in the input type list, except the first n.
Definition: traits.hpp:395
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:146
Provides the concept for seqan3::detail::sdsl_index.
Provides data structures used by different search algorithms.
Provides seqan3::detail::search_traits.
Forward declares seqan3::detail::test_accessor.