File Coverage

blib/lib/MCE/Core/Input/Generator.pm
Criterion Covered Total %
statement 9 91 9.8
branch 0 66 0.0
condition 0 23 0.0
subroutine 3 8 37.5
pod n/a
total 12 188 6.3


line stmt bran cond sub pod time code
1             ###############################################################################
2             ## ----------------------------------------------------------------------------
3             ## Sequence of numbers (for task_id > 0).
4             ##
5             ## This package provides a sequence of numbers used internally by the worker
6             ## process. Distribution is divided equally among workers. This allows sequence
7             ## to be configured independently among multiple user tasks.
8             ##
9             ## There is no public API.
10             ##
11             ###############################################################################
12              
13             package MCE::Core::Input::Generator;
14              
15 1     1   973 use strict;
  1         2  
  1         30  
16 1     1   12 use warnings;
  1         1  
  1         49  
17              
18             our $VERSION = '1.888';
19              
20             ## Items below are folded into MCE.
21              
22             package # hide from rpm
23             MCE;
24              
25 1     1   5 no warnings qw( threads recursion uninitialized );
  1         2  
  1         989  
26              
27             ###############################################################################
28             ## ----------------------------------------------------------------------------
29             ## Worker process -- Sequence Generator (equal distribution among workers).
30             ##
31             ###############################################################################
32              
33             sub _worker_sequence_generator {
34              
35 0     0     my ($self) = @_;
36              
37 0           @_ = ();
38              
39             _croak('MCE::_worker_sequence_generator: (user_func) is not specified')
40 0 0         unless (defined $self->{user_func});
41              
42 0   0       my $_bounds_only = $self->{bounds_only} || 0;
43 0           my $_max_workers = $self->{max_workers};
44 0           my $_chunk_size = $self->{chunk_size};
45 0           my $_wuf = $self->{_wuf};
46              
47 0           my ($_begin, $_end, $_step, $_fmt);
48              
49 0 0         if (ref $self->{sequence} eq 'ARRAY') {
50 0           ($_begin, $_end, $_step, $_fmt) = @{ $self->{sequence} };
  0            
51             }
52             else {
53 0           $_begin = $self->{sequence}->{begin};
54 0           $_end = $self->{sequence}->{end};
55 0           $_step = $self->{sequence}->{step};
56 0           $_fmt = $self->{sequence}->{format};
57             }
58              
59 0   0       my $_wid = $self->{_task_wid} || $self->{_wid};
60 0           my $_next = ($_wid - 1) * $_chunk_size * $_step + $_begin;
61 0           my $_chunk_id = $_wid;
62              
63 0 0         $_fmt =~ s/%// if (defined $_fmt);
64              
65             ## -------------------------------------------------------------------------
66              
67 0           local $_;
68              
69 0     0     $self->{_last_jmp} = sub { goto _WORKER_SEQ_GEN__LAST; };
  0            
70              
71 0 0         if ($_begin == $_end) { ## Identical, yes.
    0          
72              
73 0 0         if ($_wid == 1) {
74 0     0     $self->{_next_jmp} = sub { goto _WORKER_SEQ_GEN__LAST; };
  0            
75              
76 0 0         $_ = (defined $_fmt) ? _sprintf("%$_fmt", $_next) : $_next;
77              
78 0 0 0       if ($_chunk_size > 1 || $_bounds_only) {
79 0 0         $_ = ($_bounds_only) ? [ $_, $_ ] : [ $_ ];
80             }
81              
82 0           $_wuf->($self, $_, $_chunk_id);
83             }
84             }
85             elsif ($_chunk_size == 1) { ## Chunking, no.
86              
87 0     0     $self->{_next_jmp} = sub { goto _WORKER_SEQ_GEN__NEXT_A; };
  0            
88              
89 0           my $_flag = ($_begin < $_end);
90              
91 0           while (1) {
92 0 0 0       return if ( $_flag && $_next > $_end);
93 0 0 0       return if (!$_flag && $_next < $_end);
94              
95 0 0         $_ = (defined $_fmt) ? _sprintf("%$_fmt", $_next) : $_next;
96 0 0         $_ = [ $_, $_ ] if ($_bounds_only);
97              
98 0           $_wuf->($self, $_, $_chunk_id);
99              
100 0           _WORKER_SEQ_GEN__NEXT_A:
101              
102             $_chunk_id += $_max_workers;
103 0           $_next = ($_chunk_id - 1) * $_step + $_begin;
104             }
105             }
106             else { ## Chunking, yes.
107              
108 0     0     $self->{_next_jmp} = sub { goto _WORKER_SEQ_GEN__NEXT_B; };
  0            
109              
110 0           while (1) {
111 0           my @_n = (); my $_n_begin = $_next;
  0            
112              
113             ## -------------------------------------------------------------------
114              
115 0 0         if ($_bounds_only) {
116 0           my ($_tmp_b, $_tmp_e) = ($_next);
117              
118 0 0         if ($_begin <= $_end) {
119 0 0         if ($_step * ($_chunk_size - 1) + $_n_begin <= $_end) {
    0          
120 0           $_tmp_e = $_step * ($_chunk_size - 1) + $_n_begin;
121             }
122             elsif ($_step == 1) {
123 0 0         $_tmp_e = $_end if ($_next <= $_end);
124             }
125             else {
126 0           for my $_i (1 .. $_chunk_size) {
127 0 0         last if ($_next > $_end);
128 0           $_tmp_e = $_next;
129 0           $_next = $_step * $_i + $_n_begin;
130             }
131             }
132             }
133             else {
134 0 0         if ($_step * ($_chunk_size - 1) + $_n_begin >= $_end) {
    0          
135 0           $_tmp_e = $_step * ($_chunk_size - 1) + $_n_begin;
136             }
137             elsif ($_step == -1) {
138 0 0         $_tmp_e = $_end if ($_next >= $_end);
139             }
140             else {
141 0           for my $_i (1 .. $_chunk_size) {
142 0 0         last if ($_next < $_end);
143 0           $_tmp_e = $_next;
144 0           $_next = $_step * $_i + $_n_begin;
145             }
146             }
147             }
148              
149 0 0         return unless (defined $_tmp_e);
150              
151 0 0         @_n = (defined $_fmt)
152             ? ( _sprintf("%$_fmt",$_tmp_b), _sprintf("%$_fmt",$_tmp_e) )
153             : ( $_tmp_b, $_tmp_e );
154             }
155              
156             ## -------------------------------------------------------------------
157              
158             else {
159 0 0         if ($_begin <= $_end) {
160 0 0 0       if (!defined $_fmt && $_step == 1 && abs($_end) < ~1 && abs($_begin) < ~1) {
      0        
      0        
161 0 0         @_n = ($_next + $_chunk_size <= $_end)
162             ? ($_next .. $_next + $_chunk_size - 1)
163             : ($_next .. $_end);
164             }
165             else {
166 0           for my $_i (1 .. $_chunk_size) {
167 0 0         last if ($_next > $_end);
168              
169 0 0         push @_n, (defined $_fmt)
170             ? _sprintf("%$_fmt", $_next) : $_next;
171              
172 0           $_next = $_step * $_i + $_n_begin;
173             }
174             }
175             }
176             else {
177 0           for my $_i (1 .. $_chunk_size) {
178 0 0         last if ($_next < $_end);
179              
180 0 0         push @_n, (defined $_fmt)
181             ? _sprintf("%$_fmt", $_next) : $_next;
182              
183 0           $_next = $_step * $_i + $_n_begin;
184             }
185             }
186              
187 0 0         return unless (scalar @_n);
188             }
189              
190             ## -------------------------------------------------------------------
191              
192 0           $_ = \@_n;
193 0           $_wuf->($self, \@_n, $_chunk_id);
194              
195 0           _WORKER_SEQ_GEN__NEXT_B:
196              
197             $_chunk_id += $_max_workers;
198 0           $_next = ($_chunk_id - 1) * $_chunk_size * $_step + $_begin;
199             }
200             }
201              
202 0           _WORKER_SEQ_GEN__LAST:
203              
204             return;
205             }
206              
207             1;
208              
209             __END__