package Brackup::ChunkIterator;
use strict;
use warnings;
use Carp qw(croak);
sub new {
my ($class, @files) = @_;
return bless {
filelist => \@files,
chunkmag => [],
}, $class;
}
# returns either PositionedChunks, or, in cases of files
# without contents (like directories/symlinks), returns
# File objects... returns undef on end of files/chunks.
sub next {
my $self = shift;
# magazine already loaded? fire.
my $next = shift @{ $self->{chunkmag} };
return $next if $next;
# else reload...
my $file = shift @{ $self->{filelist} } or
return undef;
($next, @{$self->{chunkmag}}) = $file->chunks;
return $next if $next;
return $file;
}
sub mux_into {
my ($self, $n_copies) = @_;
my @iters;
for (1..$n_copies) {
push @iters, Brackup::ChunkIterator::SlaveIterator->new;
}
my $on_empty = sub {
my $next = $self->next;
foreach my $peer (@iters) {
push @{$peer->{mag}}, $next;
}
};
foreach (@iters) {
$_->{on_empty} = $on_empty;
}
return @iters;
}
package Brackup::ChunkIterator::SlaveIterator;
use strict;
use warnings;
use Carp qw(croak);
sub new {
my $class = shift;
return bless {
'on_empty' => undef, # subref
'mag' => [],
}, $class;
}
sub next {
my $self = shift;
# the magazine itself could be true, but contain only undef: (undef),
# which signals the end.
return shift @{$self->{mag}} if @{$self->{mag}};
$self->{on_empty}->();
return shift @{$self->{mag}};
}
sub behind_by {
my $self = shift;
return scalar @{$self->{mag}};
}
1;
syntax highlighted by Code2HTML, v. 0.9.1