File Coverage

blib/lib/Math/PartialOrder/Caching.pm
Criterion Covered Total %
statement 60 62 96.7
branch 8 14 57.1
condition 3 5 60.0
subroutine 22 24 91.6
pod 10 10 100.0
total 103 115 89.5


line stmt bran cond sub pod time code
1             # -*- Mode: Perl -*-
2              
3             #
4             # Copyright (c) 2001, Bryan Jurish. All rights reserved.
5             #
6             # This package is free software. You may redistribute it
7             # and/or modify it under the same terms as Perl itself.
8             #
9              
10             ###############################################################
11             #
12             # File: Math::PartialOrder::Caching.pm
13             # Author: Bryan Jurish
14             #
15             # Description: PartialOrder class using hashrefs
16             # to store hierarchy information which
17             # caches inheritance- and operation-lookups
18             #
19             ###############################################################
20              
21              
22             package Math::PartialOrder::Caching;
23             # System modules
24 7     7   11932 use Carp;
  7         14  
  7         704  
25 7     7   34 use Exporter;
  7         12  
  7         202  
26             # 3rd party exstensions
27 7     7   8088 use Tie::Cache;
  7         21147  
  7         218  
28             # user extension modules
29 7     7   79 use Math::PartialOrder::Std;
  7         14  
  7         7637  
30             @ISA = qw(Math::PartialOrder::Std);
31             @EXPORT = qw();
32             @EXPORT_OK = qw($CACHE_KEY_SEP);
33              
34              
35             ###############################################################
36             # Package-Globals
37             ###############################################################
38              
39             our $VERSION = 0.01;
40              
41             our $CACHE_KEY_SEP = ',';
42              
43              
44             ###############################################################
45             # Initialization
46             # + object structure:
47             # {
48             # # --- INHERITED ---
49             # types => Set::Hashed
50             # root => scalar
51             # parents => { type1 => {p1a=>p1a,...}, ... }
52             # children => { type1 => {c1a=>c1a,...}, ... }
53             # attributes => { type1 => { attr1.1 => val1.1, ... }, ... }
54             # # --- NEW ---
55             # incache => { 'type1,type2' => $has_anc_bool, ... }
56             # opcache => { 'op,type1,type2' => \@result }
57             # }
58             ###############################################################
59             #----------------------------------------------------------------------
60             # new( {root=>$r} )
61             # + initialization routine: returns the object
62             #----------------------------------------------------------------------
63             sub new ($;$) {
64 22     22 1 1132 my $class = shift;
65 22         39 my $args = shift;
66 22         175 my $self = bless {
67             types => {},
68             root => '',
69             parents => {},
70             children => {},
71             attrs => {},
72             # --- NEW ---
73             incache => {},
74             opcache => {},
75             }, $class;
76             # root node
77 22   100     168 $self->_root($args->{root}||'BOTTOM');
78              
79 22         57 return $self;
80             }
81              
82              
83              
84             ###############################################################
85             # Hierarchy Maintainance: Type Operations
86             ###############################################################
87             #--------------------------------------------------------------
88             # types : inherited from Math::PartialOrder::Std
89              
90             #--------------------------------------------------------------
91             sub add ($$@) {
92 223     223 1 550 my $self = shift;
93 223         404 $self->_clear_cached();
94 223         1694 return $self->SUPER::add(@_);
95             }
96              
97             #--------------------------------------------------------------
98             # has_type : inherited from Math::PartialOrder::Std
99              
100             #--------------------------------------------------------------
101             sub add_parents ($$@) {
102 4     4 1 14 my $self = shift;
103 4         9 $self->_clear_cached();
104 4         34 return $self->SUPER::add_parents(@_);
105             }
106              
107             #--------------------------------------------------------------
108             sub move ($$@) {
109 61     61 1 84 my $self = shift;
110 61         133 $self->_clear_cached();
111 61         493 return $self->SUPER::move(@_);
112             }
113              
114             #--------------------------------------------------------------
115             sub remove ($@) {
116 2     2 1 2 my $self = shift;
117 2 50       8 return $self unless (@_); # not really deleting anything
118 2         5 $self->_clear_cached();
119 2         14 return $self->SUPER::remove(@_);
120             }
121              
122             #--------------------------------------------------------------
123             # parents : inherited from Math::PartialOrder::Std
124              
125             #--------------------------------------------------------------
126             # children : inherited from Math::PartialOrder::Std
127              
128             #--------------------------------------------------------------
129             # has_parent : inherited from Math::PartialOrder::Std
130              
131             #--------------------------------------------------------------
132             # has_child : inherited from Math::PartialOrder::Std
133              
134             #--------------------------------------------------------------
135             sub has_ancestor ($$$) {
136 14     14 1 20 my ($cached);
137 14 50 33     94 return (defined($_[1]) && defined($_[2]) &&
138             $_[0]->has_types($_[1],$_[2])
139             &&
140             defined($cached = $_[0]->_get_cached_in($_[1],$_[2]))
141             ? $cached
142             : $_[0]->_set_cached_in($_[1], $_[2],
143             $_[0]->SUPER::has_ancestor($_[1],$_[2])));
144             }
145              
146              
147             #--------------------------------------------------------------
148 2     2 1 7 sub has_descendant ($$$) { return $_[0]->has_ancestor(@_[2,1]); }
149              
150             #--------------------------------------------------------------
151             # get_attributes : inherited from Math::PartialOrder::Std
152              
153             #--------------------------------------------------------------
154             # get_attribute : inherited from Math::PartialOrder::Std
155              
156             #--------------------------------------------------------------
157             # set_attribute : inherited from Math::PartialOrder::Std
158              
159             #--------------------------------------------------------------
160             sub assign ($$) {
161 12     12 1 2767 my ($h1,$h2) = @_;
162 12         34 $h1->_clear_cache();
163 12         101 return $h1->SUPER::assign($h2);
164             }
165              
166              
167              
168             #--------------------------------------------------------------
169             sub merge ($@) {
170 10     10 1 19 my $h1 = shift;
171 10         27 $h1->_clear_cache();
172 10         114 return $h1->SUPER::merge(@_);
173             }
174              
175             #--------------------------------------------------------------
176             sub clear ($) {
177 14     14 1 20 my $self = shift;
178 14         29 $self->_clear_cache();
179 14         99 return $self->SUPER::clear();
180             }
181              
182             ###############################################################
183             # Additional Hierarchy Maintainence Operations
184             ###############################################################
185             #--------------------------------------------------------------
186             # ensure_types : inherited from Math::PartialOrder
187              
188             #--------------------------------------------------------------
189             # _ancestors($type) => $hashref : inherited from Math::PartialOrder::Std
190              
191             #--------------------------------------------------------------
192             # _descendants($type) => $hashref : inherited from Math::PartialOrder::Std
193              
194             #--------------------------------------------------------------
195             # _minimize : inherited from Math::PartialOrder::Std
196              
197             #--------------------------------------------------------------
198             # _maximize : inherited from Math::PartialOrder::Std
199              
200              
201             ###############################################################
202             # Hierarchy Operations
203             ###############################################################
204              
205             #--------------------------------------------------------------
206             # lub
207             sub _lub ($$$) {
208 20     20   27 my ($cached);
209             return
210 20         127 (defined($cached = $_[0]->_get_cached_op('lub',$_[1],$_[2]))
211             ? (@$cached)
212 20 50       57 : (@{$_[0]->_set_cached_op('lub', $_[1], $_[2],
213             [$_[0]->SUPER::_lub($_[1],$_[2])])}));
214             }
215              
216              
217             #--------------------------------------------------------------
218             # glb
219             sub _glb ($$$) {
220 2     2   3 my ($cached);
221             return
222 2         23 (defined($cached = $_[0]->_get_cached_op('glb',$_[1],$_[2]))
223             ? (@$cached)
224 2 50       6 : (@{$_[0]->_set_cached_op('glb', $_[1], $_[2],
225             [$_[0]->SUPER::_glb($_[1],$_[2])])}));
226             }
227              
228              
229             ###############################################################
230             # Hierarchy operation utilities
231             ###############################################################
232              
233             ###############################################################
234             # Accessors/manipulators
235             ###############################################################
236              
237             #--------------------------------------------------------------
238             # _types : inherited from Math::PartialOrder::Std
239              
240             #--------------------------------------------------------------
241             sub _root ($;$) {
242 164     164   305 my $self = shift;
243 164 100       764 return $self->{root} unless (@_);
244 50         146 $self->_clear_cache();
245 50         300 return $self->SUPER::_root(@_);
246             }
247             *root = \&_root;
248              
249             #--------------------------------------------------------------
250             # _parents : inherited from Math::PartialOrder::Std
251              
252             #--------------------------------------------------------------
253             # _children : inherited from Math::PartialOrder::Std
254              
255             #--------------------------------------------------------------
256             # _attributes : inherited from Math::PartialOrder::Std
257              
258              
259             #--------------------------------------------------------------
260 0     0   0 sub _incache ($) { return $_[0]->{incache}; }
261             sub _get_cached_in ($$$) {
262             return
263 14 50   14   316 exists($_[0]->{incache}{$_[1].$CACHE_KEY_SEP.$_[2]})
264             ? $_[0]->{incache}{$_[1].$CACHE_KEY_SEP.$_[2]}
265             : undef;
266             }
267             sub _set_cached_in ($$$$) {
268             return
269 14     14   150 $_[0]->{incache}{$_[1].$CACHE_KEY_SEP.$_[2]} = $_[3];
270             }
271              
272              
273              
274             #--------------------------------------------------------------
275 0     0   0 sub _opcache ($) { return $_[0]->{opcache}; }
276             sub _get_cached_op ($$$$) {
277             return
278 22 50   22   112 exists($_[0]->{opcache}{$_[1].$CACHE_KEY_SEP.$_[2].$CACHE_KEY_SEP.$_[3]})
279             ? $_[0]->{opcache}{$_[1].$CACHE_KEY_SEP.$_[2].$CACHE_KEY_SEP.$_[3]}
280             : undef;
281             }
282             sub _set_cached_op ($$$$$) {
283             return
284 22     22   124 $_[0]->{opcache}{$_[1].$CACHE_KEY_SEP.$_[2].$CACHE_KEY_SEP.$_[3]} = $_[4];
285             }
286              
287              
288              
289              
290             #--------------------------------------------------------------
291             *_clear_cached = \&_clear_cache;
292             sub _clear_cache ($) {
293 376     376   434 %{$_[0]->{incache}} = ();
  376         1124  
294 376         1632 %{$_[0]->{opcache}} = ();
  376         997  
295             }
296              
297              
298              
299              
300             1;
301             __END__