1 #ifndef GENESIS_POPULATION_WINDOW_QUEUE_WINDOW_STREAM_H_
2 #define GENESIS_POPULATION_WINDOW_QUEUE_WINDOW_STREAM_H_
45 #include <type_traits>
49 namespace population {
130 template<
class InputStreamIterator,
class DataType =
typename InputStreamIterator::value_type>
144 using InputType =
typename InputStreamIterator::value_type;
192 using InputType =
typename InputStreamIterator::value_type;
222 throw std::runtime_error(
223 "Need to set BaseWindowStream::entry_selection_function "
224 "before iterating over Windows with a QueueWindowStream."
229 if( parent_->count_ == 0 ) {
230 throw std::runtime_error(
231 "Cannot use QueueWindowStream with count == 0."
234 if( parent_->stride_ == 0 ) {
235 parent_->stride_ = parent_->count_;
237 if( parent_->stride_ > parent_->count_ ) {
238 throw std::runtime_error(
239 "Cannot use QueueWindowStream with stride > count."
271 void init_chromosome_()
278 assert( tail_buffer_.empty() );
279 assert( input_chromosome_finished_() );
282 if( base_iterator_type::current_ == base_iterator_type::end_ ) {
291 current_queue_pop_count_.clear();
292 base_iterator_type::is_first_window_ =
true;
293 base_iterator_type::is_last_window_ =
false;
296 void increment_() override final
306 base_iterator_type::current_ == base_iterator_type::end_ &&
312 if( ! base_iterator_type::is_last_window_ ) {
313 throw std::runtime_error(
"QueueWindowStream: Incrementing past the end" );
323 if( base_iterator_type::is_last_window_ ) {
324 assert( input_chromosome_finished_() );
327 base_iterator_type::is_first_window_ =
false;
340 base_iterator_type::current_ != base_iterator_type::end_ ||
341 ! tail_buffer_.empty()
349 assert( ! window_.
empty() );
357 assert( window_.
size() > 0 );
359 base_iterator_type::is_last_window_ ||
360 current_queue_pop_count_.size() == parent_->count_
363 base_iterator_type::is_last_window_ ||
364 window_.
size() >= current_queue_pop_count_.front()
373 assert( ! base_iterator_type::is_last_window_ || input_chromosome_finished_() );
379 assert( tail_buffer_.empty() ^ !base_iterator_type::is_last_window_ );
382 void pop_old_entries_()
387 ( current_queue_pop_count_.size() == parent_->count_ ) ||
388 ( current_queue_pop_count_.size() == 0 && base_iterator_type::is_first_window_ )
394 if( parent_->stride_ == parent_->count_ ) {
396 current_queue_pop_count_.clear();
397 }
else if( current_queue_pop_count_.empty() ) {
399 assert( window_.
empty() );
400 assert( current_queue_pop_count_.empty() );
401 assert( base_iterator_type::is_first_window_ );
403 assert( ! window_.
empty() );
404 assert( ! current_queue_pop_count_.empty() );
405 assert( ! base_iterator_type::is_first_window_ );
412 size_t removed_cnt = 0;
413 while( removed_cnt < parent_->stride_ ) {
417 assert( ! current_queue_pop_count_.empty() );
418 assert( window_.
size() >= current_queue_pop_count_.front() );
419 for(
size_t i = 0; i < current_queue_pop_count_.front(); ++i ) {
420 assert( ! window_.
empty() );
423 current_queue_pop_count_.pop_front();
426 assert( current_queue_pop_count_.size() > 0 );
427 assert( removed_cnt == parent_->stride_ );
432 current_queue_pop_count_.size() == 0 ||
433 current_queue_pop_count_.size() == parent_->count_ - parent_->stride_
437 void push_new_entries_()
451 if( tail_buffer_.empty() ) {
455 ( base_iterator_type::is_first_window_ && window_.
empty() ) ||
456 ( base_iterator_type::is_last_window_ && input_chromosome_finished_() )
463 assert( ! window_.
empty() || parent_->stride_ == parent_->count_ );
471 current_queue_pop_count_.push_back( tail_buffer_.size() );
472 move_tail_buffer_to_window_();
473 assert( tail_buffer_.empty() );
478 bool finished_chromosome =
false;
479 while( current_queue_pop_count_.size() < parent_->count_ ) {
483 auto const cur_pos = window_.
size() == 0 ? 0 : window_.
entries().back().position;
484 auto const add_result = add_entries_until_selected_to_queue_(
485 cur_chr, cur_pos, window_.
entries()
491 if( add_result.second ) {
492 assert( add_result.first > 0 );
493 current_queue_pop_count_.push_back( add_result.first );
496 finished_chromosome =
true;
506 if( ! finished_chromosome ) {
507 assert( tail_buffer_.empty() );
508 assert( ! window_.
empty() );
512 auto const cur_pos = window_.
size() == 0 ? 0 : window_.
entries().back().position;
513 auto const add_result = add_entries_until_selected_to_queue_(
514 cur_chr, cur_pos, tail_buffer_
519 if( add_result.second ==
false ) {
520 finished_chromosome =
true;
529 if( finished_chromosome ) {
531 tail_buffer_.empty() ||
534 assert( input_chromosome_finished_() );
535 move_tail_buffer_to_window_();
536 base_iterator_type::is_last_window_ =
true;
537 assert( tail_buffer_.empty() );
546 add_cnt == parent_->stride_ ||
547 ( add_cnt == parent_->count_ && base_iterator_type::is_first_window_ ) ||
548 ( base_iterator_type::is_last_window_ && input_chromosome_finished_() )
550 assert( add_cnt <= parent_->count_ );
551 assert( add_cnt <= window_.
size() );
554 std::pair<size_t, bool> add_entries_until_selected_to_queue_(
555 std::string
const& prev_chr,
size_t prev_pos, std::deque<typename Window::Entry>& target
559 size_t added_count = 0;
560 bool found_selected =
false;
566 if( base_iterator_type::current_ == base_iterator_type::end_ ) {
572 auto const cur_pos = parent_->
position_function( *base_iterator_type::current_ );
576 if( cur_chr != prev_chr ) {
582 if( prev_pos >= cur_pos ) {
583 throw std::runtime_error(
584 "Invalid entry in queue window that not in sequence with other entries. "
585 "Previous entry is " + prev_chr +
":" +
std::to_string( prev_pos ) +
586 ", current (invalid) entry is " + prev_chr +
":" +
std::to_string( cur_pos )
592 using WindowEntry =
typename Window::Entry;
600 ++base_iterator_type::current_;
607 assert( ! target.empty() );
609 found_selected =
true;
613 return { added_count, found_selected };
616 void move_tail_buffer_to_window_()
620 while( ! tail_buffer_.empty() ) {
629 tail_buffer_.size() == 1
636 window_.
entries().back().position <
642 window_.
entries().push_back( std::move( tail_buffer_.front() ));
643 tail_buffer_.pop_front();
647 inline bool input_chromosome_finished_()
const
652 base_iterator_type::current_ == base_iterator_type::end_ ||
658 value_type& get_current_window_() const override final
663 BaseWindowStream<InputStreamIterator, DataType>
const* get_parent_() const override final
675 size_t next_index_ = 0;
695 std::deque<size_t> current_queue_pop_count_;
704 std::deque<typename Window::Entry> tail_buffer_;
716 InputStreamIterator
begin, InputStreamIterator
end,
783 std::unique_ptr<typename BaseWindowStream<InputStreamIterator, DataType>::BaseIterator>
792 std::unique_ptr<typename BaseWindowStream<InputStreamIterator, DataType>::BaseIterator>
795 return std::unique_ptr<DerivedIterator>(
new DerivedIterator(
nullptr ));
807 mutable size_t stride_ = 0;
822 template<
class InputStreamIterator,
class DataType =
typename InputStreamIterator::value_type>
823 QueueWindowStream<InputStreamIterator, DataType>
825 InputStreamIterator begin, InputStreamIterator end,
size_t count = 0,
size_t stride = 0
853 template<
class InputStreamIterator>
854 QueueWindowStream<InputStreamIterator>
856 InputStreamIterator begin, InputStreamIterator end,
size_t count = 0,
size_t stride = 0
858 using DataType =
typename InputStreamIterator::value_type;
862 it.entry_input_function = []( DataType
const& variant ) {
865 it.chromosome_function = []( DataType
const& variant ) {
866 return variant.chromosome;
868 it.position_function = []( DataType
const& variant ) {
869 return variant.position;
871 it.entry_selection_function = []( DataType
const& variant ) {
893 template<
class InputStreamIterator>
894 WindowViewStream<InputStreamIterator>
896 InputStreamIterator begin, InputStreamIterator end,
size_t count,
size_t stride = 0
917 template<
class InputStreamIterator>
918 QueueWindowStream<InputStreamIterator>
920 InputStreamIterator begin, InputStreamIterator end,
size_t count = 0,
size_t stride = 0
922 using DataType =
typename InputStreamIterator::value_type;
926 it.entry_input_function = []( DataType
const& variant ) {
929 it.chromosome_function = []( DataType
const& variant ) {
930 return variant.chromosome;
932 it.position_function = []( DataType
const& variant ) {
933 return variant.position;
935 it.entry_selection_function = []( DataType
const& variant ) {
936 return variant.status.passing();
956 template<
class InputStreamIterator>
957 WindowViewStream<InputStreamIterator>
959 InputStreamIterator begin, InputStreamIterator end,
size_t count,
size_t stride = 0
969 #endif // include guard