SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
|
A blocking algorithm executor for algorithms. More...
#include <seqan3/core/algorithm/detail/algorithm_executor_blocking.hpp>
Private Types | |
enum | fill_status { non_empty_buffer , empty_buffer , end_of_resource } |
Return status for seqan3::detail::algorithm_executor_blocking::fill_buffer. More... | |
Resource types | |
using | resource_type = std::views::all_t< resource_t > |
The underlying resource type. | |
using | resource_iterator_type = std::ranges::iterator_t< resource_type > |
The iterator over the underlying resource. | |
using | resource_difference_type = std::iter_difference_t< resource_iterator_type > |
The difference type over the underlying resource. | |
Buffer types | |
using | bucket_type = std::vector< algorithm_result_t > |
The type of a bucket storing the results produced by a single algorithm invocation. | |
using | bucket_iterator_type = std::ranges::iterator_t< bucket_type > |
The iterator type of a bucket. | |
using | buffer_type = std::vector< bucket_type > |
The type of the buffer. | |
using | buffer_iterator_type = std::ranges::iterator_t< buffer_type > |
The iterator type of the buffer. | |
Related Symbols | |
(Note that these are not member symbols.) | |
Type deduction guides | |
template<typename resource_rng_t , std::semiregular algorithm_t, std::semiregular algorithm_result_t> | |
algorithm_executor_blocking (resource_rng_t &&, algorithm_t, algorithm_result_t const &) -> algorithm_executor_blocking< resource_rng_t, algorithm_t, algorithm_result_t, execution_handler_sequential > | |
Deduce the type from the provided arguments and set the sequential execution handler. | |
Constructors, destructor and assignment | |
The class is move-only, i.e. it is not copy-constructible or copy-assignable. | |
execution_handler_t | exec_handler {} |
The execution policy. | |
resource_type | resource |
The underlying resource. | |
resource_iterator_type | resource_it {} |
The iterator over the resource that stores the current state of the executor. | |
algorithm_t | algorithm {} |
The algorithm to invoke. | |
buffer_type | buffer {} |
The buffer storing the algorithm results in buckets. | |
buffer_iterator_type | buffer_it {} |
The iterator pointing to the current bucket in the buffer. | |
buffer_iterator_type | buffer_end_it {} |
The iterator pointing behind the last bucket (must not be the end of the buffer). | |
bucket_iterator_type | bucket_it {} |
The bucket iterator pointing to the next result within the current bucket. | |
size_t | buffer_size {1} |
The end get pointer in the buffer. | |
algorithm_executor_blocking ()=delete | |
Deleted default constructor because this class manages an external resource. | |
algorithm_executor_blocking (algorithm_executor_blocking const &)=delete | |
This class provides unique ownership over the managed resource and is therefor not copyable. | |
algorithm_executor_blocking (algorithm_executor_blocking &&other) noexcept | |
Move constructs the resource of the other executor. | |
algorithm_executor_blocking & | operator= (algorithm_executor_blocking const &)=delete |
This class provides unique ownership over the managed resource and is therefor not copyable. | |
algorithm_executor_blocking & | operator= (algorithm_executor_blocking &&other) |
Move assigns from the resource of another executor. | |
~algorithm_executor_blocking ()=default | |
Defaulted. | |
algorithm_executor_blocking (resource_t resource, algorithm_t algorithm, algorithm_result_t const result=algorithm_result_t{}, execution_handler_t &&exec_handler=execution_handler_t{}) | |
Constructs this executor with the given resource range. | |
std::optional< algorithm_result_t > | next_result () |
} | |
bool | is_eof () noexcept |
Checks whether the end of the input resource was reached. | |
algorithm_executor_blocking (algorithm_executor_blocking &&other, resource_difference_type old_resource_position) noexcept | |
This constructor is needed to ensure initialisation order for the move construction. | |
resource_difference_type | resource_position () |
Number of times the resource_it was incremented. | |
fill_status | fill_buffer () |
Fills the buffer by storing the results of an algorithm invocation into a pre-assigned bucket. | |
bool | is_buffer_empty () const |
Whether the internal buffer is empty. | |
void | reset_buffer () |
Resets the buckets. | |
void | find_next_non_empty_bucket () |
Finds the first non-empty bucket starting from the current position of the buffer iterator. | |
void | go_to_next_result () |
Moves the bucket iterator to the next available result. | |
void | move_initialise (algorithm_executor_blocking &&other, resource_difference_type old_resource_position) noexcept |
Helper function to move initialise this from other . | |
A blocking algorithm executor for algorithms.
resource_t | The underlying range of sequence pairs to be computed; must model std::ranges::viewable_range and std::ranges::forward_range. |
algorithm_t | The algorithm to be invoked on the elements of the given resource; must model std::semiregular. |
algorithm_result_t | The result type generated by the algorithm; must model std::semiregular. |
execution_handler_t | The execution handler managing the execution of the algorithms. |
This blocking algorithm executor provides an additional buffer over the computed algorithm results to allow a two-way execution flow. The results can then be accessed in an order-preserving manner using the seqan3::detail::algorithm_executor_blocking::next_result() member function.
The blocking algorithm executor invokes the algorithm on each element of the given resource. It passes as second argument a callback function that stores the results of the algorithm in a pre-assigned buffer location. The algorithm must therefor model std::invocable with the first argument type being std::ranges::range_reference_t of the resource_t
and the second argument type being convertible to std::function<void(algorithm_result_t)>.
Since it is not clear how many results a single invocation of the given algorithm produces the buffered results are placed into buckets. The number of available buckets is determined by the execution policy. In sequential execution mode only one bucket is available and only one invocation is buffered at a time. In the parallel execution, a bucket is allocated for every element of the underlying resource.
|
private |
Return status for seqan3::detail::algorithm_executor_blocking::fill_buffer.
|
inlinenoexcept |
Move constructs the resource of the other executor.
[in] | other | The other executor (prvalue) to move from. |
Handling the move of the underlying resource, respectively result buffer, requires some non-default operations. The iterator holding the current state of the executor must be reinitailised after the resource and buffer have been moved.
no-throw guarantee.
Constant if the underlying resource type models std::ranges::random_access_range, otherwise linear.
|
inline |
Constructs this executor with the given resource range.
[in] | resource | The underlying resource. |
[in] | algorithm | The algorithm to invoke on the elements of the underlying resource. |
[in] | result | A dummy result object to deduce the type of the underlying buffer value. |
[in] | exec_handler | The execution handler to use [optional]. |
If the execution handler is parallel, it allocates a buffer of the size of the given resource range. Otherwise the buffer size is 1. Also note that the third argument is used for deducing the algorithm result type and is otherwise not used in the context of the class' construction.
|
inlineprivatenoexcept |
This constructor is needed to ensure initialisation order for the move construction.
We need to access the processed seqan3::detail::algorithm_executor_blocking::resource_position BEFORE moving the resource range. As that could invalidate iterators.
|
inlineprivate |
Finds the first non-empty bucket starting from the current position of the buffer iterator.
Finds the first non-empty bucket and sets the bucket iterator to the first element of this bucket. If all buckets are empty, then the buffer iterator is set to the end of the buffer and the bucket iterator is not modified.
|
inlineprivate |
Moves the bucket iterator to the next available result.
If the current bucket is consumed, then the buffer iterator is incremented and the next non-empty bucket is found by calling seqan3::detail::algorithm_executor_blocking::find_next_non_empty_bucket.
|
inlineprivate |
Whether the internal buffer is empty.
true
if all elements of the internal buffer have been consumed, otherwise false
.
|
inline |
}
Returns the next available algorithm result.
If there is no algorithm result available anymore the buffer will be refilled until either there is a new result available or the end of the underlying resource was reached. This operation is blocking such that the next result is only available after all algorithm invocations triggered during seqan3::detail::algorithm_executor_blocking::fill_buffer have finished.
Throws std::bad_function_call if the algorithm was not set.
|
inline |
Move assigns from the resource of another executor.
[in] | other | The other executor (prvalue) to move from. |
Handling the move of the underlying resource, respectively result buffer, requires some non-default operations. The iterator holding the current state of the executor must be reinitailised after the resource and buffer have been moved.
no-throw guarantee.
Constant if the underlying resource type models std::ranges::random_access_range, otherwise linear.
|
inlineprivate |
Resets the buckets.
Clears all buckets and sets the buffer iterator to the first bucket. The buckets are not shrunk such that the allocated memory for each bucket can be reused between invocations of seqan3::detail::algorithm_executor_blocking::fill_buffer.
|
inlineprivate |
Number of times the resource_it was incremented.