31template <
typename configuration_t,
typename index_t,
typename... policies_t>
41 static_assert(!std::same_as<search_result_type, empty_type>,
"The search result type was not configured.");
92 template <tuple_like indexed_query_t,
typename callback_t>
93 requires (std::tuple_size_v<indexed_query_t> == 2)
94 && std::ranges::forward_range<std::tuple_element_t<1, indexed_query_t>>
95 && std::invocable<callback_t, search_result_type>
96 void operator()(indexed_query_t && indexed_query, callback_t && callback)
98 auto && [query_idx, query] = indexed_query;
99 auto error_state = this->max_error_counts(query);
103 auto on_hit_delegate = [&internal_hits](
auto const & it)
108 perform_search_by_hit_strategy(internal_hits, query, error_state, on_hit_delegate);
111 this->make_results(std::move(internal_hits), query_idx, callback);
96 void operator()(indexed_query_t && indexed_query, callback_t && callback) {
…}
116 index_t
const * index_ptr{
nullptr};
122 template <
bool abort_on_hit,
typename query_t,
typename delegate_t>
123 inline void search_algo_bi(query_t & query,
search_param const error_left, delegate_t && delegate);
132 template <
typename query_t,
typename delegate_t>
136 delegate_t
const & on_hit_delegate)
138 if constexpr (!traits_t::search_all_hits)
140 auto max_total = error_state.
total;
141 error_state.
total = 0;
142 while (internal_hits.
empty() && error_state.
total <= max_total)
150 constexpr bool abort_on_hit = !traits_t::search_all_best_hits;
151 search_algo_bi<abort_on_hit>(query, error_state, on_hit_delegate);
154 if constexpr (traits_t::search_strata_hits)
156 if (!internal_hits.
empty())
158 internal_hits.
clear();
159 error_state.
total += stratum - 1;
160 search_algo_bi<false>(query, error_state, on_hit_delegate);
168 search_algo_bi<false>(query, error_state, on_hit_delegate);
214template <
typename search_scheme_t>
217 using blocks_length_type =
typename search_scheme_t::value_type::blocks_length_type;
219 constexpr bool is_dyn_scheme = std::same_as<search_scheme_t, search_scheme_dyn_type>;
229 if constexpr (is_dyn_scheme)
230 result.resize(search_scheme.size());
232 uint8_t
const blocks{search_scheme[0].blocks()};
233 size_t const block_length{query_length / blocks};
234 uint8_t
const rest{
static_cast<uint8_t
>(query_length % blocks)};
236 blocks_length_type blocks_length;
239 if constexpr (is_dyn_scheme)
240 blocks_length.resize(blocks, block_length);
242 blocks_length.fill(block_length);
244 for (uint8_t block_id = 0; block_id < rest; ++block_id)
245 ++blocks_length[block_id];
247 for (
size_t search_id = 0; search_id < search_scheme.size(); ++search_id)
249 auto const &
search = search_scheme[search_id];
251 auto & [search_blocks_length, start_pos] = result[search_id];
255 if constexpr (is_dyn_scheme)
256 search_blocks_length.resize(blocks);
257 search_blocks_length[0] = blocks_length[
search.
pi[0] - 1];
258 for (uint8_t i = 1; i < blocks; ++i)
260 search_blocks_length[i] = blocks_length[
search.
pi[i] - 1] + search_blocks_length[i - 1];
262 start_pos += search_blocks_length[i] - search_blocks_length[i - 1];
271template <
bool abort_on_hit,
275 typename blocks_length_t,
279 typename cursor_t::size_type
const lb,
280 typename cursor_t::size_type
const rb,
281 uint8_t
const errors_spent,
282 uint8_t
const block_id,
284 search_t
const & search,
285 blocks_length_t
const & blocks_length,
286 search_param
const error_left,
287 delegate_t && delegate);
321template <
bool abort_on_hit,
325 typename blocks_length_t,
329 typename cursor_t::size_type
const lb,
330 typename cursor_t::size_type
const rb,
331 uint8_t
const errors_spent,
332 uint8_t
const block_id,
335 blocks_length_t
const & blocks_length,
337 delegate_t && delegate)
339 using size_type =
typename cursor_t::size_type;
341 uint8_t
const block_id2 = std::min<uint8_t>(block_id + 1,
search.
blocks() - 1);
346 size_type
const infix_lb = rb - 1;
347 size_type
const infix_rb = lb + blocks_length[block_id] - 1;
349 if (!cur.extend_right(query |
views::slice(infix_lb, infix_rb + 1)))
352 if (search_ss<abort_on_hit>(cur,
370 size_type
const infix_lb = rb - blocks_length[block_id] - 1;
371 size_type
const infix_rb = lb - 1;
373 if (!cur.extend_left(query |
views::slice(infix_lb, infix_rb + 1)))
376 if (search_ss<abort_on_hit>(cur,
401template <
bool abort_on_hit,
405 typename blocks_length_t,
409 typename cursor_t::size_type
const lb,
410 typename cursor_t::size_type
const rb,
411 uint8_t
const errors_spent,
412 uint8_t
const block_id,
415 blocks_length_t
const & blocks_length,
417 delegate_t && delegate)
419 uint8_t
const max_error_left_in_block =
search.
u[block_id] - errors_spent;
420 uint8_t
const min_error_left_in_block =
std::max(
search.
l[block_id] - errors_spent, 0);
423 if (min_error_left_in_block == 0)
425 uint8_t
const block_id2 = std::min<uint8_t>(block_id + 1,
search.
blocks() - 1);
426 bool const go_right2 = block_id2 == 0 ? true :
search.
pi[block_id2] >
search.
pi[block_id2 - 1];
428 if (search_ss<abort_on_hit>(cur,
449 && max_error_left_in_block > 0 && error_left.
total > 0 && error_left.
deletion > 0
450 && ((go_right && cur.extend_right()) || (!go_right && cur.extend_left())))
454 error_left2.deletion--;
457 if (search_ss_deletion<abort_on_hit>(cur,
473 while ((go_right && cur.cycle_back()) || (!go_right && cur.cycle_front()));
486template <
bool abort_on_hit,
490 typename blocks_length_t,
494 typename cursor_t::size_type
const lb,
495 typename cursor_t::size_type
const rb,
496 uint8_t
const errors_spent,
497 uint8_t
const block_id,
499 uint8_t
const min_error_left_in_block,
501 blocks_length_t
const & blocks_length,
503 delegate_t && delegate)
505 using size_type =
typename cursor_t::size_type;
506 if ((go_right && cur.extend_right()) || (!go_right && cur.extend_left()))
508 size_type
const chars_left = blocks_length[block_id] - (rb - lb - 1);
510 size_type lb2 = lb - !go_right;
511 size_type rb2 = rb + go_right;
515 bool const delta = cur.last_rank() !=
to_rank(query[(go_right ? rb : lb) - 1]);
521 if (error_left.
deletion == 0 && chars_left + delta < min_error_left_in_block + 1u)
527 error_left2.
total -= delta;
528 error_left2.substitution -= delta;
531 if (rb - lb == blocks_length[block_id])
537 if (search_ss_deletion<abort_on_hit>(cur,
541 errors_spent + delta,
555 uint8_t
const block_id2 = std::min<uint8_t>(block_id + 1,
search.
blocks() - 1);
556 bool const go_right2 = block_id2 == 0 ? true :
search.
pi[block_id2] >
search.
pi[block_id2 - 1];
558 if (search_ss<abort_on_hit>(cur,
562 errors_spent + delta,
577 if (search_ss<abort_on_hit>(cur,
581 errors_spent + delta,
599 if (error_left.
deletion > 0 && !(go_right && (rb == 1 || rb == std::ranges::size(query) + 1))
600 && !(!go_right && (lb == 0 || lb == std::ranges::size(query))))
604 error_left3.deletion--;
605 search_ss<abort_on_hit>(cur,
618 while ((go_right && cur.cycle_back()) || (!go_right && cur.cycle_front()));
628template <
bool abort_on_hit,
632 typename blocks_length_t,
636 typename cursor_t::size_type
const lb,
637 typename cursor_t::size_type
const rb,
638 uint8_t
const errors_spent,
639 uint8_t
const block_id,
642 blocks_length_t
const & blocks_length,
644 delegate_t && delegate)
646 uint8_t
const max_error_left_in_block =
search.
u[block_id] - errors_spent;
647 uint8_t
const min_error_left_in_block =
std::max(
search.
l[block_id] - errors_spent, 0);
650 if (min_error_left_in_block == 0 && lb == 0 && rb == std::ranges::size(query) + 1)
656 else if (((max_error_left_in_block == 0) && (rb - lb - 1 != blocks_length[block_id]))
657 || (error_left.
total == 0 && min_error_left_in_block == 0))
659 if (search_ss_exact<abort_on_hit>(cur,
677 else if (error_left.
total > 0)
682 using size_type =
typename cursor_t::size_type;
684 size_type
const lb2 = lb - !go_right;
685 size_type
const rb2 = rb + go_right;
689 error_left2.insertion--;
691 if (rb - lb == blocks_length[block_id])
698 if (search_ss_deletion<abort_on_hit>(cur,
716 if (search_ss<abort_on_hit>(cur,
733 if (search_ss_children<abort_on_hit>(cur,
740 min_error_left_in_block,
776template <
bool abort_on_hit,
typename index_t,
typename query_t,
typename search_scheme_t,
typename delegate_t>
780 search_scheme_t
const & search_scheme,
781 delegate_t && delegate)
786 for (
size_t search_id = 0; search_id < search_scheme.size(); ++search_id)
788 auto const &
search = search_scheme[search_id];
789 auto const & [blocks_length, start_pos] = block_info[search_id];
791 bool const hit = search_ss<abort_on_hit>(index.cursor(),
805 if (abort_on_hit &&
hit)
828template <
typename configuration_t,
typename index_t,
typename... policies_t>
830template <bool abort_on_hit, typename query_t, typename delegate_t>
834 delegate_t && delegate)
836 switch (error_left.
total)
839 search_ss<abort_on_hit>(*index_ptr, query, error_left, optimum_search_scheme<0, 0>, delegate);
842 search_ss<abort_on_hit>(*index_ptr, query, error_left, optimum_search_scheme<0, 1>, delegate);
845 search_ss<abort_on_hit>(*index_ptr, query, error_left, optimum_search_scheme<0, 2>, delegate);
848 search_ss<abort_on_hit>(*index_ptr, query, error_left, optimum_search_scheme<0, 3>, delegate);
852 search_ss<abort_on_hit>(*index_ptr, query, error_left, search_scheme, delegate);
Provides the bidirectional seqan3::bi_fm_index.
The algorithm that performs a bidirectional search on a bidirectional FM index using (optimal) search...
Definition search_scheme_algorithm.hpp:34
void perform_search_by_hit_strategy(std::vector< typename index_t::cursor_type > &internal_hits, query_t &query, search_param error_state, delegate_t const &on_hit_delegate)
Calls search_algo_bi depending on the search strategy (hit configuration) given in the configuration.
Definition search_scheme_algorithm.hpp:133
~search_scheme_algorithm()=default
Defaulted.
search_scheme_algorithm(search_scheme_algorithm const &)=default
Defaulted.
typename traits_t::search_result_type search_result_type
The search result type.
Definition search_scheme_algorithm.hpp:39
search_scheme_algorithm & operator=(search_scheme_algorithm &&)=default
Defaulted.
search_scheme_algorithm(search_scheme_algorithm &&)=default
Defaulted.
search_scheme_algorithm(configuration_t const &cfg, index_t const &index)
Constructs from a configuration object and an index.
Definition search_scheme_algorithm.hpp:65
search_scheme_algorithm & operator=(search_scheme_algorithm const &)=default
Defaulted.
search_scheme_algorithm()=default
Defaulted.
Configuration element to receive all hits with the best number of errors plus the given stratum....
Definition hit.hpp:107
@ result_type
ID for the result_type option.
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
@ hit
Identifier for the hit configuration (all, all_best, single_best, strata).
auto search_scheme_block_info(search_scheme_t const &search_scheme, size_t const query_length)
Returns for each search the cumulative length of blocks in the order of blocks in each search and the...
Definition search_scheme_algorithm.hpp:215
bool search_ss(cursor_t cur, query_t &query, typename cursor_t::size_type const lb, typename cursor_t::size_type const rb, uint8_t const errors_spent, uint8_t const block_id, bool const go_right, search_t const &search, blocks_length_t const &blocks_length, search_param const error_left, delegate_t &&delegate)
Searches a query sequence in a bidirectional index using a single search of a search schemes.
Definition search_scheme_algorithm.hpp:634
bool search_ss_children(cursor_t cur, query_t &query, typename cursor_t::size_type const lb, typename cursor_t::size_type const rb, uint8_t const errors_spent, uint8_t const block_id, bool const go_right, uint8_t const min_error_left_in_block, search_t const &search, blocks_length_t const &blocks_length, search_param const error_left, delegate_t &&delegate)
Searches a query sequence in a bidirectional index using a single search of a search schemes....
Definition search_scheme_algorithm.hpp:492
bool search_ss_exact(cursor_t cur, query_t &query, typename cursor_t::size_type const lb, typename cursor_t::size_type const rb, uint8_t const errors_spent, uint8_t const block_id, bool const go_right, search_t const &search, blocks_length_t const &blocks_length, search_param const error_left, delegate_t &&delegate)
Searches a query sequence in a bidirectional index using a single search of a search scheme....
Definition search_scheme_algorithm.hpp:327
bool search_ss_deletion(cursor_t cur, query_t &query, typename cursor_t::size_type const lb, typename cursor_t::size_type const rb, uint8_t const errors_spent, uint8_t const block_id, bool const go_right, search_t const &search, blocks_length_t const &blocks_length, search_param const error_left, delegate_t &&delegate)
Searches a query sequence in a bidirectional index using a single search of a search schemes....
Definition search_scheme_algorithm.hpp:407
std::vector< search_dyn > compute_ss(uint8_t const min_error, uint8_t const max_error)
Computes a (non-optimal) search scheme. Currently the generated search scheme represents trivial back...
Definition search_scheme_algorithm.hpp:186
typename transformation_trait_or< type_t, default_t >::type transformation_trait_or_t
Helper type of seqan3::detail::transformation_trait_or (transformation_trait shortcut).
Definition transformation_trait_or.hpp:48
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition slice.hpp:137
Provides concept seqan3::template_specialisation_of<mytype, [...]> for checking the type specialisati...
The internal SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
Provides the concept for seqan3::detail::sdsl_index.
Provides data structures used by different search algorithms.
Provides the data structures and precomputed instances for (optimum) search schemes.
Provides seqan3::detail::search_traits.
Provides seqan3::views::slice.
Object grouping numbers of errors for different kind of error types.
Definition search_common.hpp:22
uint8_t insertion
Total number of insertion errors.
Definition search_common.hpp:28
uint8_t total
Total number of errors (upper bound over all error types).
Definition search_common.hpp:24
uint8_t deletion
Total number of deletion errors.
Definition search_common.hpp:30
uint8_t substitution
Total number of substitution errors.
Definition search_common.hpp:26
A collection of traits extracted from the search configuration.
Definition search_traits.hpp:31
typename std::remove_cvref_t< decltype(std::declval< search_configuration_t >().get_or(search_cfg::detail::result_type< empty_search_result_type >{}))>::type search_result_type
The configured search result type.
Definition search_traits.hpp:36
Object storing information for a search (of a search scheme).
Definition search_scheme_precomputed.hpp:25
constexpr uint8_t blocks() const noexcept
Returns the number of blocks.
Definition search_scheme_precomputed.hpp:37
std::array< uint8_t, nbr_blocks > u
Upper error bound for each block (accumulated values)
Definition search_scheme_precomputed.hpp:34
std::array< uint8_t, nbr_blocks > l
Lower error bound for each block (accumulated values)
Definition search_scheme_precomputed.hpp:32
std::array< uint8_t, nbr_blocks > pi
Order of blocks.
Definition search_scheme_precomputed.hpp:30