File Coverage

blib/lib/Hash/PriorityQueue.pm
Criterion Covered Total %
statement 48 50 96.0
branch 14 18 77.7
condition 8 9 88.8
subroutine 7 7 100.0
pod 4 4 100.0
total 81 88 92.0


line stmt bran cond sub pod time code
1             package Hash::PriorityQueue;
2              
3             our $VERSION = '0.01';
4              
5 6     6   109243 use strict;
  6         14  
  6         221  
6 6     6   30 use warnings;
  6         12  
  6         190  
7              
8 6     6   39 use List::Util qw(min);
  6         12  
  6         3674  
9              
10             sub new {
11 5     5 1 77 return bless {
12             queue => {}, # payloads by prio
13             prios => {}, # prios by payload
14             min_key => undef,
15             }, shift();
16             }
17              
18             sub delete {
19 3     3 1 20 my ($self, $payload) = @_;
20 3         5 my $op = $self->{prios}->{$payload};
21 3 50       8 if (defined($op)) {
22 3         4 $self->{queue}->{$op} = [ grep { $_ ne $payload } @{$self->{queue}->{$op}} ];
  3         10  
  3         8  
23 3 50       5 if (!@{$self->{queue}->{$op}}) {
  3         10  
24 3         5 delete($self->{queue}->{$op});
25 3 50       21 if ($self->{min_key} == $op) {
26 0         0 $self->{min_key} = min keys(%{$self->{queue}});
  0         0  
27             }
28             }
29             }
30             }
31              
32             sub pop {
33 62     62 1 157 my ($self) = @_;
34 62 100       151 if (!defined($self->{min_key})) {
35 8         38 return undef;
36             }
37              
38 54         52 my $elem = shift(@{$self->{queue}->{$self->{min_key}}});
  54         107  
39 54 100       63 if (!@{$self->{queue}->{$self->{min_key}}}) {
  54         228  
40 38         71 delete($self->{queue}->{$self->{min_key}});
41 38         41 $self->{min_key} = min keys(%{$self->{queue}});
  38         187  
42             }
43 54         106 delete($self->{prios}->{$elem});
44 54         173 return $elem;
45             }
46              
47             sub update {
48 59     59 1 1105 my ($self, $payload, $priority) = @_;
49 59         114 my $op = $self->{prios}->{$payload};
50 59 100       110 if (defined($op)) {
51 4         8 $self->{queue}->{$op} = [ grep { $_ ne $payload } @{$self->{queue}->{$op}} ];
  2         8  
  4         15  
52 4 50       7 if (!@{$self->{queue}->{$op}}) {
  4         18  
53 4         10 delete($self->{queue}->{$op});
54             }
55             }
56              
57 59         139 $self->{prios}->{$payload} = $priority;
58 59         60 push(@{$self->{queue}->{$priority}}, $payload);
  59         173  
59 59 100 100     473 if (!defined($self->{min_key}) or $priority < $self->{min_key}) {
    100 100        
      66        
60 17         48 $self->{min_key} = $priority;
61             } elsif ($priority > $self->{min_key} and (defined($op) and !defined($self->{queue}->{$op}))) {
62 2         3 $self->{min_key} = min keys(%{$self->{queue}});
  2         30  
63             }
64             }
65              
66             *insert = \&update;
67              
68             1;
69              
70             __END__