File Coverage

blib/lib/Paranoid/Data/AVLTree/AVLNode.pm
Criterion Covered Total %
statement 108 130 83.0
branch 19 24 79.1
condition 1 3 33.3
subroutine 33 37 89.1
pod 22 22 100.0
total 183 216 84.7


line stmt bran cond sub pod time code
1             # Paranoid::Data::AVLTree::AVLNode -- AVL Tree Node Object Class
2             #
3             # $Id: lib/Paranoid/Data/AVLTree/AVLNode.pm, 2.08 2020/12/31 12:10:06 acorliss Exp $
4             #
5             # This software is free software. Similar to Perl, you can redistribute it
6             # and/or modify it under the terms of either:
7             #
8             # a) the GNU General Public License
9             # as published by the
10             # Free Software Foundation ; either version 1
11             # , or any later version
12             # , or
13             # b) the Artistic License 2.0
14             # ,
15             #
16             # subject to the following additional term: No trademark rights to
17             # "Paranoid" have been or are conveyed under any of the above licenses.
18             # However, "Paranoid" may be used fairly to describe this unmodified
19             # software, in good faith, but not as a trademark.
20             #
21             # (c) 2005 - 2020, Arthur Corliss (corliss@digitalmages.com)
22             # (tm) 2008 - 2020, Paranoid Inc. (www.paranoid.com)
23             #
24             #####################################################################
25              
26             #####################################################################
27             #
28             # Environment definitions
29             #
30             #####################################################################
31              
32             package Paranoid::Data::AVLTree::AVLNode;
33              
34 1     1   14 use 5.008;
  1         3  
35              
36 1     1   4 use strict;
  1         1  
  1         26  
37 1     1   5 use warnings;
  1         2  
  1         32  
38 1     1   5 use vars qw($VERSION);
  1         1  
  1         33  
39 1     1   4 use base qw(Exporter);
  1         2  
  1         56  
40 1     1   6 use Paranoid;
  1         1  
  1         31  
41 1     1   4 use Carp;
  1         2  
  1         80  
42              
43             ($VERSION) = ( q$Revision: 2.08 $ =~ /(\d+(?:\.\d+)+)/sm );
44              
45 1     1   5 use constant AVLKEY => 0;
  1         2  
  1         69  
46 1     1   6 use constant AVLVAL => 1;
  1         1  
  1         44  
47 1     1   5 use constant AVLRIGHT => 2;
  1         1  
  1         43  
48 1     1   5 use constant AVLLEFT => 3;
  1         2  
  1         34  
49 1     1   5 use constant AVLRHEIGHT => 4;
  1         2  
  1         40  
50 1     1   5 use constant AVLLHEIGHT => 5;
  1         1  
  1         43  
51              
52 1     1   4 use constant AVLNHEADER => 'AVLNODE:v1:';
  1         2  
  1         169  
53              
54             #####################################################################
55             #
56             # Module code follows
57             #
58             #####################################################################
59              
60             sub new {
61              
62             # Purpose: Instantiates an AVLNode object
63             # Returns: Object reference if successful, undef otherwise
64             # Usage: $obj = Paranoid::Data::AVLTree::AVLNode->new(
65             # $key, $val
66             # );
67              
68 20     20 1 26 my $class = shift;
69 20         24 my $key = shift;
70 20         21 my $val = shift;
71 20         40 my $self = [];
72              
73 20         27 bless $self, $class;
74 20 50 33     76 if ( defined $key and length $key ) {
75 20         37 $$self[AVLKEY] = $key;
76 20         23 $$self[AVLVAL] = $val;
77 20         28 $$self[AVLRHEIGHT] = 0;
78 20         29 $$self[AVLLHEIGHT] = 0;
79             } else {
80 0         0 $self = undef;
81             }
82              
83 20         32 return $self;
84             }
85              
86             sub ioRecord {
87              
88             # Purpose: Returns a string record representation of the node
89             # Returns: String
90             # Usage: $record = $obj->ioRecord;
91              
92 0     0 1 0 my $self = shift;
93 0         0 my $rv = AVLNHEADER;
94 0         0 my ( $ksize, $vsize );
95              
96             {
97 1     1   587 use bytes;
  1         12  
  1         5  
  0         0  
98 0         0 $ksize = length $$self[AVLKEY];
99 0 0       0 $vsize = defined $$self[AVLVAL] ? length $$self[AVLVAL] : -1;
100             }
101              
102 0         0 $rv .= "$ksize:$vsize:";
103 0         0 $rv .= $$self[AVLKEY];
104 0 0       0 $rv .= $$self[AVLVAL] if defined $$self[AVLVAL];
105              
106 0         0 return $rv;
107             }
108              
109             sub key {
110              
111             # Purpose: Returns the node key
112             # Returns: String
113             # Usage: $key = $obj->key;
114              
115 705     705 1 787 my $self = shift;
116 705         1437 return $$self[AVLKEY];
117             }
118              
119             sub val {
120              
121             # Purpose: Returns the node value
122             # Returns: Scalar/undef
123             # Usage: $val = $node->val;
124              
125 20     20 1 24 my $self = shift;
126 20         43 return $$self[AVLVAL];
127             }
128              
129             sub setVal {
130              
131             # Purpose: Sets the node value
132             # Returns: Boolean
133             # Usage: $rv = $obj->setVal($val);
134              
135 0     0 1 0 my $self = shift;
136 0         0 my $val = shift;
137              
138 0         0 $$self[AVLVAL] = $val;
139              
140 0         0 return 1;
141             }
142              
143             sub right {
144              
145             # Purpose: Returns the right-side node reference
146             # Returns: AVLNode ref/undef
147             # Usage: $ref = $obj->right;
148              
149 222     222 1 259 my $self = shift;
150 222         469 return $$self[AVLRIGHT];
151             }
152              
153             sub setRight {
154              
155             # Purpose: Sets the right-side node reference
156             # Returns: Boolean
157             # Usage: $rv = $obj->setRight($node);
158              
159 31     31 1 40 my $self = shift;
160 31         33 my $val = shift;
161              
162 31         36 $$self[AVLRIGHT] = $val;
163 31 100       51 $$self[AVLRHEIGHT] = defined $val ? $val->height : 0;
164              
165 31         46 return 1;
166             }
167              
168             sub left {
169              
170             # Purpose: Returns the left-side node reference
171             # Returns: AVLNode ref/undef
172             # Usage: $ref = $obj->left;
173              
174 148     148 1 161 my $self = shift;
175 148         345 return $$self[AVLLEFT];
176             }
177              
178             sub setLeft {
179              
180             # Purpose: Sets the left-side node reference
181             # Returns: Boolean
182             # Usage: $rv = $obj->setLeft($node);
183              
184 22     22 1 47 my $self = shift;
185 22         25 my $val = shift;
186              
187 22         51 $$self[AVLLEFT] = $val;
188 22 100       85 $$self[AVLLHEIGHT] = defined $val ? $val->height : 0;
189              
190 22         34 return 1;
191             }
192              
193             sub incrRHeight {
194              
195             # Purpose: Increments the right-side branch height
196             # Returns: Boolean
197             # Usage: $rv = $obj->incrRHeight;
198              
199 28     28 1 31 my $self = shift;
200              
201 28         42 $$self[AVLRHEIGHT]++;
202              
203 28         39 return 1;
204             }
205              
206             sub incrLHeight {
207              
208             # Purpose: Increments the left-side branch height
209             # Returns: Boolean
210             # Usage: $rv = $obj->incrLHeight;
211              
212 14     14 1 15 my $self = shift;
213              
214 14         17 $$self[AVLLHEIGHT]++;
215              
216 14         20 return 1;
217             }
218              
219             sub addRHeight {
220              
221             # Purpose: Adds the passed value to the right-side height
222             # Returns: Boolean
223             # Usage: $rv = $obj->addRHeight($n);
224              
225 0     0 1 0 my $self = shift;
226 0         0 my $n = shift;
227              
228 0         0 $$self[AVLRHEIGHT] += $n;
229              
230 0         0 return 1;
231             }
232              
233             sub addLHeight {
234              
235             # Purpose: Adds the passed value to the left-side height
236             # Returns: Boolean
237             # Usage: $rv = $obj->addLHeight($n);
238              
239 2     2 1 27 my $self = shift;
240 2         3 my $n = shift;
241              
242 2         4 $$self[AVLLHEIGHT] += $n;
243              
244 2         4 return 1;
245             }
246              
247             sub decrRHeight {
248              
249             # Purpose: Decrements the right-side branch height
250             # Returns: Boolean
251             # Usage: $rv = $obj->decrRHeight;
252              
253 2     2 1 4 my $self = shift;
254              
255 2         3 $$self[AVLRHEIGHT]--;
256              
257 2         3 return 1;
258             }
259              
260             sub decrLHeight {
261              
262             # Purpose: Decrements the left-side branch height
263             # Returns: Boolean
264             # Usage: $rv = $obj->decrLHeight;
265              
266 0     0 1 0 my $self = shift;
267              
268 0         0 $$self[AVLLHEIGHT]--;
269              
270 0         0 return 1;
271             }
272              
273             sub balance {
274              
275             # Purpose: Returns the current balance of right/left-side branch heights
276             # Returns: Integer
277             # Usage: $balance = $obj->balance;
278              
279 177     177 1 188 my $self = shift;
280              
281 177         383 return $$self[AVLRHEIGHT] - $$self[AVLLHEIGHT];
282             }
283              
284             sub count {
285              
286             # Purpose: Returns the count of nodes from this node and its sub-branches
287             # Returns: Integer
288             # Usage: $count = $obj->count;
289              
290 36     36 1 38 my $self = shift;
291 36         38 my $rv = 1;
292              
293 36 100       61 $rv += $$self[AVLRIGHT]->count if defined $$self[AVLRIGHT];
294 36 100       54 $rv += $$self[AVLLEFT]->count if defined $$self[AVLLEFT];
295              
296 36         51 return $rv;
297             }
298              
299             sub height {
300              
301             # Purpose: Returns the height of this node and its longest sub-branch
302             # Returns: Integer
303             # Usage: $height = $obj->height;
304              
305 115     115 1 134 my $self = shift;
306              
307 115 100       244 return 1 + (
308             $$self[AVLRHEIGHT] > $$self[AVLLHEIGHT]
309             ? $$self[AVLRHEIGHT]
310             : $$self[AVLLHEIGHT] );
311             }
312              
313             sub rHeight {
314              
315             # Purpose: Returns the height of the right-side sub-branch
316             # Returns: Integer
317             # Usage: $height = $obj->rHeight;
318              
319 7     7 1 8 my $self = shift;
320              
321 7         24 return $$self[AVLRHEIGHT];
322             }
323              
324             sub lHeight {
325              
326             # Purpose: Returns the height of the left-side sub-branch
327             # Returns: Integer
328             # Usage: $height = $obj->lHeight;
329              
330 4     4 1 5 my $self = shift;
331              
332 4         9 return $$self[AVLLHEIGHT];
333             }
334              
335             sub updtHeights {
336              
337             # Purpose: Brute force method of recalculating all sub-branch heights
338             # Returns: Boolean
339             # Usage: $rv = $obj->updtHeights;
340              
341 39     39 1 43 my $self = shift;
342              
343 39 100       60 $$self[AVLRHEIGHT] =
344             defined $$self[AVLRIGHT]
345             ? $$self[AVLRIGHT]->height
346             : 0;
347 39 100       72 $$self[AVLLHEIGHT] =
348             defined $$self[AVLLEFT] ? $$self[AVLLEFT]->height : 0;
349              
350 39         53 return 1;
351             }
352              
353             sub children {
354              
355             # Purpose: Returns all nodes linked to from this node
356             # Returns: Array of AVLNode refs
357             # Usage: @crefs = $obj->children;
358              
359 5     5 1 5 my $self = shift;
360 5         6 my @rv;
361              
362 5 100       10 push @rv, $$self[AVLRIGHT] if defined $$self[AVLRIGHT];
363 5 100       10 push @rv, $$self[AVLLEFT] if defined $$self[AVLLEFT];
364              
365 5         13 return @rv;
366             }
367              
368             1;
369              
370             __END__