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   853 use strict;
  1         2  
  1         25  
16 1     1   4 use warnings;
  1         2  
  1         40  
17              
18             our $VERSION = '1.887';
19              
20             ## Items below are folded into MCE.
21              
22             package # hide from rpm
23             MCE;
24              
25 1     1   4 no warnings qw( threads recursion uninitialized );
  1         2  
  1         803  
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__
210              
211             ###############################################################################
212             ## ----------------------------------------------------------------------------
213             ## Module usage.
214             ##
215             ###############################################################################
216              
217             =head1 NAME
218              
219             MCE::Core::Input::Generator - Sequence of numbers (for task_id > 0)
220              
221             =head1 VERSION
222              
223             This document describes MCE::Core::Input::Generator version 1.887
224              
225             =head1 DESCRIPTION
226              
227             This package provides a sequence of numbers used internally by the worker
228             process. Distribution is divided equally among workers. This allows sequence
229             to be configured independently among multiple user tasks.
230              
231             There is no public API.
232              
233             =head1 SEE ALSO
234              
235             The syntax for the C<sequence> option is described in L<MCE::Core>.
236              
237             =head1 AUTHOR
238              
239             Mario E. Roy, S<E<lt>marioeroy AT gmail DOT comE<gt>>
240              
241             =cut
242