File Coverage

blib/lib/List/GroupingPriorityQueue.pm
Criterion Covered Total %
statement 77 77 100.0
branch 22 22 100.0
condition n/a
subroutine 16 16 100.0
pod 12 12 100.0
total 127 127 100.0


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # based on List::PriorityQueue execpt that payloads with identical
4             # priorities are grouped together
5              
6             package List::GroupingPriorityQueue;
7              
8 2     2   209338 use 5.6.0;
  2         20  
9 2     2   15 use strict;
  2         4  
  2         45  
10 2     2   13 use warnings;
  2         5  
  2         128  
11             our $VERSION = '0.01';
12              
13 2     2   1126 use parent qw(Exporter);
  2         647  
  2         11  
14             our @EXPORT_OK =
15             qw(grpriq_add grpriq_min grpriq_min_values grpriq_max grpriq_max_values);
16              
17             ########################################################################
18             #
19             # FUNCTIONS
20              
21             sub grpriq_add {
22 18     18 1 14663 my ( $qref, $priority, @rest ) = @_;
23             # special cases
24 18 100       47 unless (@$qref) {
25 4         11 @$qref = [ [@rest], $priority ];
26 4         11 return;
27             }
28 14 100       35 if ( $priority > $qref->[-1][1] ) {
29 3         9 push @$qref, [ [@rest], $priority ];
30 3         7 return;
31             }
32 11 100       29 if ( $priority < $qref->[0][1] ) {
33 2         7 unshift @$qref, [ [@rest], $priority ];
34 2         5 return;
35             }
36 9 100       20 if ( $priority == $qref->[-1][1] ) {
37 2         4 push @{ $qref->[-1][0] }, @rest;
  2         8  
38 2         5 return;
39             }
40 7 100       14 if ( $priority == $qref->[0][1] ) {
41 2         3 push @{ $qref->[0][0] }, @rest;
  2         17  
42 2         7 return;
43             }
44 5         10 my $lower = 0;
45 5         7 my $midpoint;
46 5         9 my $upper = $#$qref;
47 5         36 while ( $lower <= $upper ) {
48 12         20 $midpoint = ( $lower + $upper ) >> 1;
49 12 100       26 if ( $priority < $qref->[$midpoint][1] ) {
50 4         6 $upper = $midpoint - 1;
51 4         9 next;
52             }
53 8 100       18 if ( $priority > $qref->[$midpoint][1] ) {
54 7         10 $lower = $midpoint + 1;
55 7         16 next;
56             }
57 1         3 push @{ $qref->[$midpoint][0] }, @rest;
  1         4  
58 1         3 return;
59             }
60 4         13 splice @$qref, $lower, 0, [ [@rest], $priority ];
61 4         10 return;
62             }
63              
64 2     2 1 2951 sub grpriq_min { shift @{ $_[0] } }
  2         15  
65              
66             sub grpriq_min_values {
67 2     2 1 5 my $ref = shift @{ $_[0] };
  2         5  
68 2 100       12 return unless defined $ref;
69 1         5 $ref->[0];
70             }
71              
72 1     1 1 2 sub grpriq_max { pop @{ $_[0] } }
  1         9  
73              
74             sub grpriq_max_values {
75 2     2 1 4 my $ref = pop @{ $_[0] };
  2         6  
76 2 100       9 return unless defined $ref;
77 1         5 $ref->[0];
78             }
79              
80             ########################################################################
81             #
82             # METHODS
83              
84             sub each {
85 1     1 1 3 my ( $self, $callback ) = @_;
86 1         3 while ( my $entry = shift @{ $self->{queue} } ) {
  3         20  
87 2         5 $callback->(@$entry);
88             }
89             }
90              
91 1     1 1 17 sub new { bless { queue => [] }, $_[0] }
92              
93             sub insert {
94 8     8 1 31 my ( $self, $priority, @rest ) = @_;
95 8         26 grpriq_add( $self->{queue}, $priority, @rest );
96 8         14 return $self;
97             }
98              
99 1     1 1 3 sub min { shift @{ $_[0]->{queue} } }
  1         6  
100              
101             sub min_values {
102 3     3 1 10 my $ref = shift @{ $_[0]->{queue} };
  3         8  
103 3 100       13 return unless defined $ref;
104 2         10 $ref->[0];
105             }
106             *pop = \&min_values;
107              
108 1     1 1 3 sub max { pop @{ $_[0]->{queue} } }
  1         6  
109              
110             sub max_values {
111 2     2 1 4 my $ref = pop @{ $_[0]->{queue} };
  2         7  
112 2 100       9 return unless defined $ref;
113 1         5 $ref->[0];
114             }
115              
116             1;
117             __END__