File Coverage

blib/lib/Data/Queue.pm
Criterion Covered Total %
statement 69 74 93.2
branch 9 18 50.0
condition n/a
subroutine 13 13 100.0
pod 7 9 77.7
total 98 114 85.9


line stmt bran cond sub pod time code
1             package Data::Queue;
2              
3             =head1 NAME
4              
5             Data::Queue - Order/Unordered stack
6              
7             =head1 SYNOPSIS
8              
9             use Data::Queue;
10              
11             my $stack=new Data::Queue;
12              
13             my $id=$stack->add($job);
14              
15             while($stack->has_next) {
16             my ($id,$job)=$stack->get_next;
17             }
18              
19             =head1 DESCRIPTION
20              
21             Stack, with the ablity to add and remove elements by id on the fly. Elements go in and out of the stack in the id order.
22              
23             =cut
24              
25 1     1   588 use Modern::Perl;
  1         3  
  1         8  
26 1     1   533 use Moo;
  1         10299  
  1         7  
27 1     1   1691 use Data::Result;
  1         50206  
  1         40  
28 1     1   17 use namespace::clean;
  1         7  
  1         9  
29             our $VERSION='1.0001';
30              
31             with 'Data::Result::Moo';
32              
33             sub BUILD {
34 2     2 0 3565 my ($self,$args)=@_;
35 2         6 my $data={};
36 2         14 $self->{id}=0;
37 2         7 $self->{data}={};
38 2         13 $self->{stack}=[];
39             };
40              
41             =head1 OO Methods
42              
43             =over 4
44              
45             =item * my @ids=$stack->add(@list)
46              
47             Adds a list of objects onto the stack
48              
49             Arguments:
50              
51             @ids: List of ids relative to @list
52             @list: List of elements to put on the stack
53              
54             =cut
55              
56             sub add {
57 3     3 1 1081 my ($self,@list)=@_;
58              
59 3         8 my @result;
60 3         12 my $list=$self->{list};
61 3         7 foreach my $obj (@list) {
62 6         14 $self->{id}++;
63 6         26 my $set=[$self->{id},$obj];
64              
65 6         20 $self->{data}->{$self->{id}}=$set;
66 6         13 push @{$self->{stack}},$self->{id};
  6         17  
67 6         20 push @result,$self->{id};
68             }
69              
70 3         18 @result;
71             }
72              
73             =item * my ($id,$value)=$stack->get_next
74              
75             Returns the next id=>value pair from the set.
76              
77             =cut
78              
79             sub get_next {
80 5     5 1 3493 my ($self)=@_;
81 5         10 my $id=shift @{$self->{stack}};
  5         14  
82 5         17 my $set=delete $self->{data}->{$id};
83              
84 5 50       15 return wantarray ? @{$set} : $set->[1];
  5         22  
85             }
86              
87             =item * if($stack->has_next) { ... }
88              
89             Returns a Data::Result object, when true, it is safe to call $stack->get_next
90              
91             =cut
92              
93             sub has_next {
94 4     4 0 6891 my ($self)=@_;
95 4 50       9 return $#{$self->{stack}}==-1 ?
  4         26  
96             $self->new_false("No elements left on the stack!") :
97             $self->new_true("yes we have more");
98             }
99              
100             =item * if($self->has_id($id)) { ... }
101              
102             Returns a Data::Result object:
103              
104             When true: it contains the object from the stack
105             When false: it contains an error message
106              
107             =cut
108              
109             sub has_id {
110 2     2 1 607 my ($self,$id)=@_;
111              
112 2         9 my $result=$self->new_false('Object Not on stack');
113 2 100       484 if(exists $self->{data}->{$id}) {
114 1         7 $result=$self->new_true($self->{data}->{$id}->[1]);
115             }
116 2         317 return $result;
117             }
118              
119             =item * my $id=$stack->add_by_id($id=>$obj);
120              
121             Adds the element pair to the stack, with a given id, if the id existed the old element is removed.
122              
123             =cut
124              
125             sub add_by_id {
126 3     3 1 15 my ($self,$id,$value)=@_;
127 3         13 $self->{data}->{$id}=[$id,$value];
128              
129 3 100       16 $self->{id}=$id if $id >$self->{id};
130 3         8 my $stack=$self->{stack};
131              
132 3 100       8 if($#{$stack}==-1) {
  3 50       12  
    0          
    0          
    0          
133 2         8 $self->rebuild_stack;
134             } elsif($stack->[0] > $id) {
135 1         3 unshift @{$stack},$id;
  1         4  
136             } elsif($stack->[0]==$id) {
137             # do nothing!
138 0         0 } elsif($stack->[$#{$stack}] < $id) {
139 0         0 push @{$stack},$id;
  0         0  
140 0         0 } elsif($stack->[$#{$stack}] == $id) {
141             # do nothing!
142             } else {
143 0         0 $self->rebuild_stack;
144             }
145 3         24 return $id;
146             }
147              
148             =item * $stack->remove($id)
149              
150             Removes the $id from the stack
151              
152             =cut
153              
154             sub remove {
155 1     1 1 5 my ($self,$id)=@_;
156 1         4 delete $self->{data}->{$id};
157 1         6 $self->rebuild_stack;
158 1         3 return;
159             }
160              
161             =item * $self->rebuild_stack
162              
163             Internal method for rebuilding the internal stack as needed.
164              
165             =cut
166              
167             sub rebuild_stack {
168 3     3 1 9 my ($self)=@_;
169 3         8 my @set=sort { $a->[0] <=> $b->[0] } values %{$self->{data}};
  3         11  
  3         16  
170 3         8 @{$self->{stack}}=();
  3         9  
171 3         11 foreach my $set (@set) {
172 5         11 push @{$self->{stack}},$set->[0];
  5         16  
173             }
174 3         9 return;
175             }
176              
177             =item * my $total=$stack->total
178              
179             Returns the total number of elements on the stack
180              
181             =cut
182              
183             sub total {
184 6     6 1 4065 my ($self)=@_;
185 6         12 return scalar(keys %{$self->{data}});
  6         37  
186             }
187              
188             =back
189              
190             =head1 AUTHOR
191              
192             Mike Shipper Mike Shipper
193              
194             =cut
195              
196             1;