File Coverage

blib/lib/AI/Pathfinding/SMAstar/AVLQueue.pm
Criterion Covered Total %
statement 65 104 62.5
branch 14 26 53.8
condition 1 3 33.3
subroutine 14 21 66.6
pod 0 17 0.0
total 94 171 54.9


line stmt bran cond sub pod time code
1             #
2             # Queue.pm
3             #
4             # Implementation of a queue based on a binary tree
5             # A tree structure is used rather than a heap to allow
6             # infrequent, but necessary, arbitrary access to elements
7             # in the middle of the queue in log(n) time
8             #
9             # This is primarily necessary to facilitat the SMAstar
10             # path-finding algorithm.
11             #
12             #
13             # Author: matthias beebe
14             # Date : June 2008
15             #
16             #
17             package AI::Pathfinding::SMAstar::AVLQueue;
18              
19 1     1   14 use Tree::AVL;
  1         1  
  1         24  
20 1     1   635 use AI::Pathfinding::SMAstar::PairObj;
  1         2  
  1         103  
21 1     1   6 use Carp;
  1         2  
  1         76  
22 1     1   5 use strict;
  1         1  
  1         1502  
23              
24              
25              
26             ##################################################
27             # AVLQueue constructor
28             ##################################################
29             sub new {
30 20     20 0 25 my $invocant = shift;
31 20   33     68 my $class = ref($invocant) || $invocant;
32 20         69 my $self = {
33             _key => undef, # for comparisons with other queues, etc.
34              
35             _avltree => Tree::AVL->new(fcompare => \&AI::Pathfinding::SMAstar::AVLQueue::compare_obj_counters,
36             fget_key => \&AI::Pathfinding::SMAstar::AVLQueue::obj_counter,
37             fget_data => \&AI::Pathfinding::SMAstar::AVLQueue::obj_value),
38            
39             _counter => 0,
40            
41             _obj_counts_tree => Tree::AVL->new(fcompare => \&AI::Pathfinding::SMAstar::PairObj::compare_keys_numeric,
42             fget_key => \&AI::Pathfinding::SMAstar::PairObj::key,
43             fget_data => \&AI::Pathfinding::SMAstar::PairObj::val),
44            
45             @_, # Override previous attributes
46             };
47 20         663 return bless $self, $class;
48             }
49              
50              
51              
52             ##############################################
53             # accessor
54             ##############################################
55              
56             sub key
57             {
58 50     50 0 351 my $self = shift;
59 50 50       92 if (@_) { $self->{_key} = shift }
  0         0  
60 50         106 return $self->{_key};
61             }
62              
63              
64              
65              
66              
67             #############################################################################
68             #
69             # other methods
70             #
71             #############################################################################
72              
73              
74             sub get_keys_iterator
75             {
76 0     0 0 0 my ($self) = @_;
77 0         0 return $self->{_obj_counts_tree}->get_keys_iterator();
78             }
79              
80              
81              
82             sub compare_obj_counters{
83 5     5 0 19 my ($obj, $arg_obj) = @_;
84              
85 5 50       17 if ($arg_obj){
86 5         6 my $arg_key = $arg_obj->{_queue_counter};
87 5         7 my $key = $obj->{_queue_counter};
88            
89 5 100       11 if($arg_key > $key){
    50          
    0          
90 1         2 return(-1);
91             }
92             elsif($arg_key == $key){
93 4         8 return(0);
94             }
95             elsif($arg_key < $key){
96 0         0 return(1);
97             }
98             }
99             else{
100 0         0 croak "AVLQueue::compare_obj_counters: error: null argument object\n";
101             }
102             }
103              
104              
105             sub obj_counter{
106 26     26 0 239 my ($obj) = @_;
107 26         55 return $obj->{_queue_counter};
108             }
109              
110             sub obj_value{
111 0     0 0 0 my ($obj) = @_;
112 0         0 return $obj->{_value};
113             }
114              
115              
116              
117             sub compare {
118 38     38 0 201 my ($self, $arg_obj) = @_;
119              
120 38 50       64 if ($arg_obj){
121 38         45 my $arg_key = $arg_obj->{_key};
122 38         38 my $key = $self->{_key};
123            
124 38 100       100 if($arg_key > $key){
    100          
    50          
125 15         30 return(-1);
126             }
127             elsif($arg_key == $key){
128 13         26 return(0);
129             }
130             elsif($arg_key < $key){
131 10         23 return(1);
132             }
133             }
134             else{
135 0         0 croak "AVLQueue::compare error: null argument object\n";
136             }
137             }
138              
139             sub lookup {
140 0     0 0 0 my ($self, $obj) = @_;
141 0         0 my $found_obj = $self->{_avltree}->lookup_obj($obj);
142              
143 0 0       0 if(!$found_obj){
144 0         0 croak "AVLQueue::lookup: did not find obj in queue\n";
145 0         0 return;
146             }
147 0         0 return $found_obj;
148             }
149              
150             sub lookup_by_key {
151 0     0 0 0 my ($self, $key) = @_;
152 0         0 my $pair = AI::Pathfinding::SMAstar::PairObj->new(
153             _queue_counter => $key,
154             );
155 0         0 my $found_obj = $self->{_avltree}->lookup_obj($pair);
156              
157 0 0       0 if(!$found_obj){
158 0         0 croak "AVLQueue::lookup: did not find obj in queue\n";
159 0         0 return;
160             }
161 0         0 return $found_obj;
162             }
163              
164              
165             sub remove {
166 4     4 0 5 my ($self, $obj, $compare_func) = @_;
167 4         4 my $found_obj;
168            
169 4         22 $found_obj = $self->{_avltree}->remove($obj);
170              
171 4 50       69 if(!$found_obj){
172 0         0 croak "AVLQueue::remove: did not find obj in queue\n";
173 0         0 return;
174             }
175            
176 4         7 my $count = $found_obj->{_queue_counter};
177            
178              
179 4         13 my $pairobj = AI::Pathfinding::SMAstar::PairObj->new(_key => $count,
180             _value => $count);
181 4         11 $self->{_obj_counts_tree}->remove($pairobj);
182              
183 4         66 return $found_obj;
184             }
185              
186              
187              
188             sub is_empty
189             {
190 9     9 0 12 my ($self) = @_;
191            
192 9 100       28 if($self->{_avltree}->is_empty()){
193 8         71 return 1;
194             }
195 1         10 return 0;
196             }
197              
198              
199             sub insert
200             {
201 16     16 0 23 my ($self,
202             $obj) = @_;
203            
204 16         19 my $count = $self->{_counter};
205              
206 16         25 $obj->{_queue_counter} = $count;
207 16         37 $self->{_avltree}->insert($obj);
208            
209              
210              
211 16         169 my $pairobj = AI::Pathfinding::SMAstar::PairObj->new(_key => $count,
212             _value => $count);
213 16         44 $self->{_obj_counts_tree}->insert($pairobj);
214              
215 16         140 $self->{_counter} = $self->{_counter} + 1;
216              
217            
218 16         54 return;
219             }
220              
221              
222             sub pop_top
223             {
224 5     5 0 6 my ($self) = @_;
225            
226 5         13 my $top = $self->{_avltree}->pop_smallest();
227 5         72 my $count = $top->{_queue_counter};
228            
229              
230 5         18 my $pairobj = AI::Pathfinding::SMAstar::PairObj->new(_key => $count,
231             _value => $count);
232 5         15 $self->{_obj_counts_tree}->remove($pairobj);
233              
234              
235 5         97 return $top;
236             }
237              
238              
239              
240             sub top
241             {
242 6     6 0 8 my ($self) = @_;
243            
244 6         14 my $top = $self->{_avltree}->smallest();
245 6         93 return $top;
246            
247              
248             }
249              
250              
251             sub get_list{
252 0     0 0   my ($self) = @_;
253 0           return $self->{_avltree}->get_list();
254             }
255              
256              
257             sub get_size{
258 0     0 0   my ($self) = @_;
259 0           my $avltree = $self->{_avltree};
260 0           my $size = $avltree->get_size();
261 0           return $size;
262             }
263              
264              
265             sub print{
266 0     0 0   my ($self, $delim) = @_;
267 0           my @tree_elts = $self->{_avltree}->get_list();
268            
269 0           foreach my $obj (@tree_elts){
270 0           print $obj->{_start_word} . ", " . $obj->{_phrase} . ", " . $obj->{_queue_counter} . "\n";
271            
272             }
273              
274 0           print "\n\nobj_counts_tree:\n";
275 0           $self->{_obj_counts_tree}->print("*");
276              
277              
278              
279 0           my $iterator = $self->{_obj_counts_tree}->get_keys_iterator();
280 0           print "\n\niterator keys:\n";
281 0           while(defined(my $key = $iterator->())){
282 0           print "iterator key: $key\n";
283             }
284            
285              
286             }
287              
288              
289              
290              
291             1;