File Coverage

blib/lib/Sort/Key/Top/PP.pm
Criterion Covered Total %
statement 92 120 76.6
branch 36 38 94.7
condition 12 12 100.0
subroutine 25 37 67.5
pod 0 24 0.0
total 165 231 71.4


line stmt bran cond sub pod time code
1             package Sort::Key::Top::PP;
2              
3 2     2   43817 use 5.008;
  2         7  
  2         87  
4 2     2   12 use strict;
  2         3  
  2         83  
5 2     2   10 use warnings;
  2         8  
  2         79  
6 2     2   10 no warnings qw( once );
  2         2  
  2         111  
7              
8             BEGIN {
9 2     2   4 $Sort::Key::Top::PP::AUTHORITY = 'cpan:TOBYINK';
10 2         123 $Sort::Key::Top::PP::VERSION = '0.003';
11             }
12              
13 2         21 use Exporter::Shiny our(@EXPORT) = qw(
14             top
15             topsort
16             keytop
17             keytopsort
18             ntop
19             ntopsort
20             nkeytop
21             nkeytopsort
22             rtop
23             rtopsort
24             rkeytop
25             rkeytopsort
26             rntop
27             rntopsort
28             rnkeytop
29             rnkeytopsort
30             head
31             nhead
32             keyhead
33             nkeyhead
34             tail
35             ntail
36             keytail
37             nkeytail
38 2     2   1543 );
  2         6743  
39              
40             sub _tail_numeric {
41 5     5   105 my ($list, $top_n) = @_;
42 5         7 my @top;
43             my $cur;
44 5         11 for my $i (@$list) {
45 44 100 100     159 next if @top==$top_n && $i->[0] < $top[0][0];
46 25 100       52 ((@top = $i), next) unless @top;
47 20         27 my ($low, $high) = (0, scalar @top);
48             (
49 20 100       105 ($cur = ($low + $high) >> 1),
50             ($i->[0] - $top[$cur][0] > 0)
51             ? ($low = $cur + 1)
52             : ($high = $cur),
53             ) while $low < $high;
54 20         26 splice(@top, $low, 0, $i);
55 20 100       46 shift @top if @top > $top_n;
56             }
57 5         18 return reverse @top;
58             }
59              
60             sub _head_numeric {
61 3     3   43 my ($list, $top_n) = @_;
62 3         5 my @top;
63             my $cur;
64 3         9 for my $i (@$list) {
65 25 100 100     100 next if @top==$top_n && $i->[0] > $top[0][0];
66 14 100       35 ((@top = $i), next) unless @top;
67 11         14 my ($low, $high) = (0, scalar @top);
68             (
69 11 100       61 ($cur = ($low + $high) >> 1),
70             ($top[$cur][0] - $i->[0] > 0)
71             ? ($low = $cur + 1)
72             : ($high = $cur),
73             ) while $low < $high;
74 11         15 splice(@top, $low, 0, $i);
75 11 100       26 shift @top if @top > $top_n;
76             }
77 3         14 return reverse @top;
78             }
79              
80             sub _head_stringy {
81 8     8   11 my ($list, $top_n) = @_;
82 8         9 my @top;
83             my $cur;
84 8         14 for my $i (@$list) {
85 76 100 100     226 next if @top==$top_n && $i->[0] gt $top[0][0];
86 72 100       135 ((@top = $i), next) unless @top;
87 64         74 my ($low, $high) = (0, scalar @top);
88             (
89 64 100       646 ($cur = ($low + $high) >> 1),
90             (($top[$cur][0] cmp $i->[0]) > 0)
91             ? ($low = $cur + 1)
92             : ($high = $cur),
93             ) while $low < $high;
94 64         76 splice(@top, $low, 0, $i);
95 64 100       156 shift @top if @top > $top_n;
96             }
97 8         32 return reverse @top;
98             }
99              
100             sub _tail_stringy {
101 1     1   3 my ($list, $top_n) = @_;
102 1         2 my @top;
103             my $cur;
104 1         3 for my $i (@$list) {
105 8 100 100     36 next if @top==$top_n && $i->[0] lt $top[0][0];
106 5 100       13 ((@top = $i), next) unless @top;
107 4         6 my ($low, $high) = (0, scalar @top);
108             (
109 4 50       24 ($cur = ($low + $high) >> 1),
110             (($top[$cur][0] cmp $i->[0]) < 0)
111             ? ($low = $cur + 1)
112             : ($high = $cur),
113             ) while $low < $high;
114 4         5 splice(@top, $low, 0, $i);
115 4 50       12 shift @top if @top > $top_n;
116             }
117 1         5 return reverse @top;
118             }
119              
120             sub _preprocess {
121 17     17   22 my $code = shift;
122 17         23 my $count = 0;
123 17 100       144 $code
124             ? [ map [ $code->($_), $_, $count++ ], @_ ]
125             : [ map [ $_ , $_, $count++ ], @_ ];
126             }
127              
128             sub _postprocess {
129 17     17   22 my $n = shift;
130             wantarray
131 17 100       137 ? map($_->[1], @_)
    100          
132             : ( @_ >= $n ? $_[-1][1] : undef )
133             }
134              
135             sub _restore_order;
136             if (eval { require Sort::Key }) {
137             *_restore_order = sub { &Sort::Key::ikeysort(sub { $_->[2] }, @_) };
138             }
139             else {
140 9     9   30 *_restore_order = sub { sort { $a->[2] <=> $b->[2] } @_ };
  85         117  
141             }
142              
143             sub top {
144 6     6 0 1020 my $n = shift;
145 6         14 _postprocess $n,
146             _restore_order
147             _head_stringy(
148             _preprocess(undef, @_),
149             $n
150             );
151             }
152              
153             sub topsort {
154 2     2 0 4 my $n = shift;
155 2         6 _postprocess $n,
156             _head_stringy(
157             _preprocess(undef, @_),
158             $n
159             );
160             }
161              
162             sub keytop (&$@) {
163 0     0 0 0 my $k = shift;
164 0         0 my $n = shift;
165 0         0 _postprocess $n,
166             _restore_order
167             _head_stringy(
168             _preprocess($k, @_),
169             $n
170             );
171             }
172              
173             sub keytopsort (&$@) {
174 0     0 0 0 my $k = shift;
175 0         0 my $n = shift;
176 0         0 _postprocess $n,
177             _head_stringy(
178             _preprocess($k, @_),
179             $n
180             );
181             }
182              
183             sub ntop {
184 0     0 0 0 my $n = shift;
185 0         0 _postprocess $n,
186             _restore_order
187             _head_numeric(
188             _preprocess(undef, @_),
189             $n
190             );
191             }
192              
193             sub ntopsort {
194 1     1 0 3 my $n = shift;
195 1         6 _postprocess $n,
196             _head_numeric(
197             _preprocess(undef, @_),
198             $n
199             );
200             }
201              
202             sub nkeytop (&$@) {
203 1     1 0 14 my $k = shift;
204 1         2 my $n = shift;
205 1         5 _postprocess $n,
206             _restore_order
207             _head_numeric(
208             _preprocess($k, @_),
209             $n
210             );
211             }
212              
213             sub nkeytopsort (&$@) {
214 1     1 0 3 my $k = shift;
215 1         2 my $n = shift;
216 1         3 _postprocess $n,
217             _head_numeric(
218             _preprocess($k, @_),
219             $n
220             );
221             }
222              
223             sub rtop {
224 0     0 0 0 my $n = shift;
225 0         0 _postprocess $n,
226             _restore_order
227             _tail_stringy(
228             _preprocess(undef, @_),
229             $n
230             );
231             }
232              
233             sub rtopsort {
234 1     1 0 2 my $n = shift;
235 1         4 _postprocess $n,
236             _tail_stringy(
237             _preprocess(undef, @_),
238             $n
239             );
240             }
241              
242             sub rkeytop (&$@) {
243 0     0 0 0 my $k = shift;
244 0         0 my $n = shift;
245 0         0 _postprocess $n,
246             _restore_order
247             _tail_stringy(
248             _preprocess($k, @_),
249             $n
250             );
251             }
252              
253             sub rkeytopsort (&$@) {
254 0     0 0 0 my $k = shift;
255 0         0 my $n = shift;
256 0         0 _postprocess $n,
257             _tail_stringy(
258             _preprocess($k, @_),
259             $n
260             );
261             }
262              
263             sub rntop {
264 0     0 0 0 my $n = shift;
265 0         0 _postprocess $n,
266             _restore_order
267             _tail_numeric(
268             _preprocess(undef, @_),
269             $n
270             );
271             }
272              
273             sub rntopsort {
274 0     0 0 0 my $n = shift;
275 0         0 _postprocess $n,
276             _tail_numeric(
277             _preprocess(undef, @_),
278             $n
279             );
280             }
281              
282             sub rnkeytop (&$@) {
283 2     2 0 4 my $k = shift;
284 2         2 my $n = shift;
285 2         5 _postprocess $n,
286             _restore_order
287             _tail_numeric(
288             _preprocess($k, @_),
289             $n
290             );
291             }
292              
293             sub rnkeytopsort (&$@) {
294 3     3 0 5 my $k = shift;
295 3         6 my $n = shift;
296 3         7 _postprocess $n,
297             _tail_numeric(
298             _preprocess($k, @_),
299             $n
300             );
301             }
302              
303             sub head {
304 0     0 0 0 unshift @_, 1;
305 0         0 scalar &topsort;
306             }
307              
308             sub nhead {
309 1     1 0 7 unshift @_, 1;
310 1         5 scalar &ntopsort;
311             }
312              
313             sub keyhead (&@) {
314 0     0 0 0 splice(@_, 1, 0, 1);
315 0         0 scalar &keytopsort;
316             }
317              
318             sub nkeyhead (&@) {
319 1     1 0 5 splice(@_, 1, 0, 1);
320 1         8 scalar &nkeytopsort;
321             }
322              
323             sub tail {
324 1     1 0 4 unshift @_, 1;
325 1         4 scalar &rtopsort;
326             }
327              
328             sub ntail {
329 0     0 0 0 unshift @_, 1;
330 0         0 scalar &rntopsort;
331             }
332              
333             sub keytail (&@) {
334 0     0 0 0 splice(@_, 1, 0, 1);
335 0         0 scalar &rkeytopsort;
336             }
337              
338             sub nkeytail (&@) {
339 1     1 0 4 splice(@_, 1, 0, 1);
340 1         4 scalar &rnkeytopsort;
341             }
342              
343             1;
344              
345             __END__