1. # Batches values sourced from an iterator, producing a work batch from them.
  2. my class Rakudo::Internals::HyperIteratorBatcher does Rakudo::Internals::HyperBatcher {
  3. my constant NO_LOOKAHEAD = Mu.CREATE;
  4. has Iterator $!iterator;
  5. has $!lookahead;
  6. has int $!seq-num;
  7. submethod BUILD(Iterator :$iterator!) {
  8. $!iterator := $iterator;
  9. $!lookahead := NO_LOOKAHEAD;
  10. }
  11. method produce-batch(int $batch-size --> Rakudo::Internals::HyperWorkBatch) {
  12. nqp::stmts(
  13. (my $items := nqp::create(IterationBuffer)),
  14. nqp::unless(
  15. (my int $first = nqp::eqaddr($!lookahead,NO_LOOKAHEAD)),
  16. nqp::push($items,$!lookahead) # not first, get from previous
  17. ),
  18. nqp::unless(
  19. (my int $last = nqp::eqaddr(
  20. $!iterator.push-exactly(
  21. $items,
  22. nqp::sub_i($batch-size,nqp::not_i($first))
  23. ),
  24. IterationEnd
  25. )),
  26. ($last = nqp::eqaddr( # not last batch
  27. ($!lookahead := $!iterator.pull-one),
  28. IterationEnd # but is in this case
  29. ))
  30. ),
  31. Rakudo::Internals::HyperWorkBatch.new($!seq-num++,$items,$first,$last)
  32. )
  33. }
  34. }