parallel: :::: now does nesting/product/cartesian/multiply (--xapply missing)

This commit is contained in:
Ole Tange 2011-05-04 23:58:00 +02:00
parent 7f731a54b7
commit a560a74b8a

View file

@ -3905,6 +3905,7 @@ sub new {
sub get { sub get {
my $self = shift; my $self = shift;
return $self->nest_get();
if(@{$self->{'unget'}}) { if(@{$self->{'unget'}}) {
return shift @{$self->{'unget'}}; return shift @{$self->{'unget'}};
} }
@ -3964,6 +3965,93 @@ sub get {
} }
} }
sub nest_get {
my $self = shift;
if(@{$self->{'unget'}}) {
return shift @{$self->{'unget'}};
}
my @record = ();
my $prepend = undef;
my $empty = 1;
my $no_of_inputs = $#{$self->{'fhs'}} + 1;
if(not @::arg_matrix) {
# Initialize @::arg_matrix with one arg from each file
# read one line from each file
my @first_arg_set;
for (my $fhno = 0; $fhno < $no_of_inputs ; $fhno++) {
my $fh = $self->{'fhs'}[$fhno];
my $arg = <$fh>;
# Remove delimiter
$arg =~ s:$/$::;
$::arg_matrix[$fhno][0]=Arg->new($arg);
push @first_arg_set, $::arg_matrix[$fhno][0];
}
$self->unget([@first_arg_set]);
}
my @fh = @{$self->{'fhs'}};
for (my $fhno = 0; $fhno < $no_of_inputs; $fhno++) {
if(eof($fh[$fhno])) {
next;
} else {
# read one
my $f = $fh[$fhno];
my $arg = <$f>;
# Remove delimiter
$arg =~ s:$/$::;
my $len = $#{$::arg_matrix[$fhno]}+1;
$::arg_matrix[$fhno][$len]=Arg->new($arg);
# make all new combinations
my @combarg = ();
for (my $fhn = 0; $fhn < $no_of_inputs; $fhn++) {
push @combarg, [0, $#{$::arg_matrix[$fhn]}];
}
$combarg[$fhno] = [$len,$len]; # Find only combinations with this new entry
my @combinations = expand_combinations(@combarg);
# map combinations
# [ 1, 3, 7], [ 2, 4, 1 ]
# =>
# [ m[0][1], m[1][3], m[3][7]], [ m[0][2], m[1][4], m[2][1] ]
my @mapped;
for my $c (@combinations) {
my @a;
for my $n (0 .. $no_of_inputs - 1 ) {
push @a, $::arg_matrix[$n][$$c[$n]];
}
push @mapped, [@a];
}
# unget the mapped
push @{$self->{'unget'}}, @mapped;
# get the first
return shift @{$self->{'unget'}};
}
}
# all are eof; return undef
return undef;
}
sub expand_combinations {
# Input:
# ([xmin,xmax], [ymin,ymax], ...)
# Returns ([x,y,...],[x,y,...])
# where xmin <= x <= xmax and ymin <= y <= ymax
my $minmax_ref = shift;
my $xmin = $$minmax_ref[0];
my $xmax = $$minmax_ref[1];
my @p;
if(@_) {
# If there are more columns: Compute those recursively
my @rest = expand_combinations(@_);
for(my $x = $xmin; $x <= $xmax; $x++) {
push @p, map { [$x, @$_] } @rest;
}
} else {
for(my $x = $xmin; $x <= $xmax; $x++) {
push @p, [$x];
}
}
return @p;
}
sub unget { sub unget {
my $self = shift; my $self = shift;
::debug("MultifileQueue-unget '@_'\n"); ::debug("MultifileQueue-unget '@_'\n");