|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Tie::FileLRUCache;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
79168
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
4
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
436
 | 
 use Class::ParmList qw (simple_parms parse_parms);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1340
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
    | 
| 
7
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
432
 | 
 use Digest::SHA1 qw(sha1_hex);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
653
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
    | 
| 
8
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use Fcntl qw (:flock);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
111
 | 
    | 
| 
9
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use File::Spec;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
10
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
610
 | 
 use Storable qw (nstore nfreeze retrieve);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2727
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
    | 
| 
11
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use Symbol qw (gensym);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use vars qw ($VERSION);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 BEGIN {  | 
| 
16
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
3422
 | 
     $VERSION = "1.06";  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ###########################################################################  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Tie::FileLRUCache - A lightweight but robust filesystem based persistent LRU cache  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 CHANGES  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1.06 2020.10.08  - Changed license to MIT License. Updated maintainer info.  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    Updated build files. Added GitHub repo meta to build.  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    Changed minimum supported version of Perl to 5.6.  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1.05 2005.09.13  - Changes to pod tests to make them more CPANTS friendly.  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    No functional changes.  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1.04 2005.09.13  - Removed use of lexical warnings pragma to fix compatibility  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    with Perl 5.005.  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    Fixed minor typographical errors in documentation.  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1.03 2005.09.10 - Changed build test to handle difference in treatment of hashes  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   in scalar context between 5.6.x and 5.8.x versions of Perl that  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   caused a test failure under Perl 5.6.x.  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1.02 2005.09.08 - Added build tests. Major code cleanup. Improved platform portability.  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   Added and documented 'cache_dir', 'keep_last' and 'number_of_entries'  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   methods. Added Module::Build support.  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1.01 1999.12.09 - Added detainting in internal cache maintaining  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   functions to evade Taint's tainting  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   of filenames read via readdir().  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 OBJECT INTERFACE  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  use Tie::FileLRUCache;  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $cache = Tie::FileLRUCache->new({ -cache_dir => $directory, -keep_last => 100 });  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Inserting value into LRU cache using '-key'  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->update({ -key => $key, -value => $value });  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Inserting value into LRU cache using '-cache_key'  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $cache_key = $cache->make_cache_key({ -key => $key });  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->update({ -cache_key => $cache_key, -value => $value });  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Checking LRU cache  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my ($in_cache,$value) = $cache->check({ -key => $key });  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  if ($in_cache) {  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      return $value;  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Not in cache - do something else  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Checking LRU cache with speed up hack for objects, hashes, arrays etc used as keys  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $cache_key = $cache->make_cache_key({ -key => $something });  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my ($in_cache,$value) = $cache->check({ -cache_key => $cache_key });  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  if ($in_cache) {  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      return $value;  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Not in cache - do something else  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Deleting a key and its value from the cache  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->delete({ -key => $key });  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Clearing LRU cache  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->clear;  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 TIED INTERFACE  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  use Tie::FileLRUCache;  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  [$X =] tie %hash,  'Tie::FileLRUCache', $cache_dir, $keep_last_n;  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Adding a key/value to the cache  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $hash{$key} = $value;  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Checking the cache  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  if (not exists $hash{$key}) {;  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      # No match  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        .  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        .  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        .  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  } else {  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      my $value = $hash{$key};  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        .  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        .  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        .  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Removing a value from the cache;  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  delete $hash{$key};  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Clearing the cache  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  %hash = ();  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Note: Iteration over the cache (each, keys, values) is _NOT_ supported.  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Provides a lightweight persistent filesystem based LRU cache.  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It uses the 'last accessed' timestamp generated by the file system  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to determine the 'oldest' cache entry and discards the oldest  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 cache entries when needed to stay under the -keep_last limit.  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If you store thing very fast (such that many entries receive the  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 same time stamp), it is essentially a coin toss which entry  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 within a single timestamped second gets purged from the cache  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to make room for new ones.  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It is not designed to handle huge numbers of cached items. It is probably  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 unwise to set the 'keep_last' higher than around 100.  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 OBJECT METHODS  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item new({[ -cache_dir => $cache_directory] [, -keep_last => $keep_last_n ] });  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Creates and optionally initializes a Tie::FileLRUCache object:  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Example:  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $cache = Tie::FileLRUCache->new({  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                        -cache_dir => '/tmp/testing',  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                        -keep_last => 100,  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                      });  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The default cache size is 100 entries unless specified.  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
171
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
  
1
  
 | 
2537
 | 
     my $proto   = shift;  | 
| 
172
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     my $package = __PACKAGE__;  | 
| 
173
 | 
13
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
47
 | 
     my $class = ref ($proto) || $proto || $package;  | 
| 
174
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     my $self  = bless {}, $class;  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
176
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
     my $parms = parse_parms({ -parms => \@_,  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                        -legal => [-cache_dir, -keep_last],  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     -required => [],  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     -defaults => { -keep_last => 100,  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                                    -cache_dir => undef,  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                                    },  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             });  | 
| 
183
 | 
13
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1231
 | 
     if (not defined $parms) {  | 
| 
184
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         my $error_message = Class::ParmList->error;  | 
| 
185
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         require Carp;  | 
| 
186
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
160
 | 
         Carp::croak ($package . "::new() - Parameter error '$error_message'\n");  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Save settings  | 
| 
190
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     my ($cache_dir,$keep_last) = $parms->get(-cache_dir,-keep_last);  | 
| 
191
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
313
 | 
     $self->cache_dir($cache_dir);  | 
| 
192
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     $self->keep_last($keep_last);  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
194
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     $self;  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item check({ -key => $key });  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Reads the cache for the key.  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Returns two values: $cache_hit (true if a hit was found, false if not)  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $value     (the cached value, undef if no hit)  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Examples:  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    my ($cache_hit,$value) = $cache->check({ -key => $key });  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    my ($cache_hit,$value) = $cache->check({ -cache_key => $cache_key });  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The '-key' form is used when you just want to use a raw key. It can use  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 blessed objects, hash refs, scalars, or array refs as keys. The more complex  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 structures take a speed penalty for computing a canonical form.  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 You can minimize this penalty by using the '-cache_key' form instead.  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The '-cache_key' form is used for performance reasons when using keys  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 such as complex blessed objects or hashes as a key. The -cache_key  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is obtained with a call to 'make_cache_key'. It is legal to mix  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 -cache_key and -key based calls - they are cross-compatible.  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub check {  | 
| 
229
 | 
48
 | 
 
 | 
 
 | 
  
48
  
 | 
  
1
  
 | 
325
 | 
     my $self = shift;  | 
| 
230
 | 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
     my $package = __PACKAGE__;  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
232
 | 
48
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
82
 | 
     if (not wantarray) {  | 
| 
233
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         require Carp;  | 
| 
234
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
         Carp::croak ($package . "::check() - Called in a scalar context\n");  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
237
 | 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
231
 | 
     my $parms = parse_parms({ -parms => \@_,  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                        -legal => [-cache_key, -key],  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     -required => [],  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     -defaults => {},  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                   });  | 
| 
242
 | 
46
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
4820
 | 
     if (not defined $parms) {  | 
| 
243
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         my $error_message = Class::ParmList->error;  | 
| 
244
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         require Carp;  | 
| 
245
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
         Carp::croak ($package . "::check() - $error_message\n");  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
247
 | 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
136
 | 
     my ($key,$cache_key) = $parms->get(-key,-cache_key);  | 
| 
248
 | 
45
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1314
 | 
     if (not (defined ($key) or defined ($cache_key))) {  | 
| 
249
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         require Carp;  | 
| 
250
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
         Carp::croak ($package . "::check() - Called without either a -key or -cache_key\n");  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
253
 | 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
96
 | 
     my $cache_dir = $self->cache_dir;  | 
| 
254
 | 
44
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
     unless (defined $cache_dir) {  | 
| 
255
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         require Carp;  | 
| 
256
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
         Carp::croak ($package . "::check - No cache directory set.\n");  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Ok. Set our lock on the cache  | 
| 
260
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87
 | 
     $self->_lock_cache;  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Generate the cache_key (done by making a cannonical  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # network order Storable string out of the key) if we  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # don't already have it  | 
| 
265
 | 
43
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
98
 | 
     unless (defined $cache_key) {  | 
| 
266
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
         $cache_key = $self->make_cache_key({ -key => $key });  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Generate a unique cache file name by taking a SHA1 hash of $cache_key  | 
| 
270
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
287
 | 
     my $cache_hash = lc(sha1_hex($cache_key));  | 
| 
271
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
136
 | 
     $cache_hash    =~ s/\s//gs;  | 
| 
272
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
249
 | 
     my ($untainted_cache_hash) = $cache_hash =~ m/^([a-f0-9]+)$/s;  | 
| 
273
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
480
 | 
     my $cache_file  = File::Spec->catfile($cache_dir, "cl_$untainted_cache_hash");  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Check if there is a cache entry for this key  | 
| 
276
 | 
43
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
768
 | 
     unless (-e $cache_file) {  | 
| 
277
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
94
 | 
         $self->_unlock_cache;  | 
| 
278
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
147
 | 
         return (0,undef);  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Yes. Get it. And update the last modified and last accessed dates.  | 
| 
282
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
     my $entry;  | 
| 
283
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     eval {  | 
| 
284
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
         $entry = retrieve($cache_file);  | 
| 
285
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1653
 | 
         my $now = time;  | 
| 
286
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
361
 | 
         utime ($now, $now, $cache_file);  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
288
 | 
21
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
67
 | 
     if ($@) {  | 
| 
289
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $@;  | 
| 
290
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
291
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
292
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak($package . "::check - Error while retrieving cache entry file '$cache_file': $error\n");  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
294
 | 
21
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
     unless (defined $entry) {  | 
| 
295
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
296
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
297
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
298
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak($package . "::update - Failed to retrieve cache entry file '$cache_file': $error\n");  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Release the lock.  | 
| 
302
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
     $self->_unlock_cache;  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
304
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     my $cache_value = $entry->{'-value'};  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Give them their cupie doll  | 
| 
307
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
165
 | 
     return (1, $cache_value);  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item make_cache_key({ -key => $key });  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Generates a cache key by canonicalizing a passed  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 key as a network ordered canonical Storable string.  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Example:  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $cache_key = $cache->make_cache_key({ -key => $key });  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub make_cache_key {  | 
| 
328
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
  
1
  
 | 
25
 | 
     my $self = shift;  | 
| 
329
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $package = __PACKAGE__;  | 
| 
330
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     my $parms = parse_parms({ -parms => \@_,  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                        -legal => [],  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     -required => ['-key'],  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     -defaults => {},  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                   });  | 
| 
335
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1000
 | 
     unless (defined $parms) {  | 
| 
336
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         my $error_message = Class::ParmList->error;  | 
| 
337
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         require Carp;  | 
| 
338
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
         Carp::croak ($package . "::make_cache_key() - $error_message\n");  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
340
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
     my ($key) = $parms->get(-key);  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
342
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
176
 | 
     my $temp =  $Storable::canonical;  | 
| 
343
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
     my $result = nfreeze(\$key);  | 
| 
344
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
369
 | 
     $Storable::canonical = $temp;  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
346
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     if (not $result) {  | 
| 
347
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
348
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
349
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::check() - Unable to serialize passed -key value: $error");  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
351
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     return $result;  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item clear;  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Completely clears the cache of all cache entries.  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub clear {  | 
| 
367
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
22
 | 
     my $self = shift;  | 
| 
368
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $package = __PACKAGE__;  | 
| 
369
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my $cache_dir = $self->cache_dir;  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
371
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     unless (defined $cache_dir) {  | 
| 
372
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         require Carp;  | 
| 
373
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
168
 | 
         Carp::croak ($package . "::clear - No cache directory set.\n");  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
375
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     if ($cache_dir eq '') {  | 
| 
376
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         require Carp;  | 
| 
377
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
         Carp::croak ($package . "::clear - Cannot use root directory as cache directory.\n");  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
379
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
38
 | 
     if ((-e $cache_dir) and (not -d _)) {  | 
| 
380
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
381
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::clear - '$cache_dir' already exists and is not a directory.\n");  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
384
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     $self->_lock_cache;  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
386
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $cache_dir_fh = gensym;  | 
| 
387
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
71
 | 
     if (not opendir ($cache_dir_fh, $cache_dir)) {  | 
| 
388
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
389
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
390
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
391
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::clear - Failed to open directory '$cache_dir' for reading: $error\n");  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
394
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
     my @raw_directory_list = readdir($cache_dir_fh);  | 
| 
395
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     unless (closedir ($cache_dir_fh)) {  | 
| 
396
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
397
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
398
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
399
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::clear - Failed to close directory '$cache_dir': $error\n");  | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  Untaint the filenames, convert them to absolute file paths and unlink them.  | 
| 
403
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     my @raw_files_list = grep(/^(cacheline_[a-zA-Z0-9]{1,50}|cl_[a-zA-Z0-9]{1,50})$/s, @raw_directory_list);  | 
| 
404
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my @file_list = ();  | 
| 
405
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     foreach my $item (@raw_files_list) {  | 
| 
406
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
         my ($filename) = $item =~ m/^(.*)$/s;  | 
| 
407
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
94
 | 
         my $file_path =  File::Spec->catfile($cache_dir, $filename);  | 
| 
408
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
485
 | 
         unless (unlink $file_path) {  | 
| 
409
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $error = $!;  | 
| 
410
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $self->_unlock_cache;  | 
| 
411
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             require Carp;  | 
| 
412
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             Carp::croak($package . "::clear - Failed to unlink file '$file_path': $error");  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
416
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $self->_unlock_cache;  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
418
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     return;  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item update({ [-key => $key,] [-cache_key => $cache_key, ], -value => $value [, -keep_last => $keep_last_n ] });  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Updates the Least Recently Used (LRU) cache for the specified  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 key with the passed value.  '-keep_last' is optional after the first access  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to a dataset. It will use the I 'keep_last' used  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 if not specified.  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It is legal to use ordinary scalars, hash references, or array references  | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 as keys as well as objects as -keys or -values.  Basically, anything that  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Storable can reproducibly serialize can be used.  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Examples:  | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->update({ -key => $key, -value => $value });  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->update({ -key => $key, -value => $value, -keep_last => 100});  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $cache_key = $cache->make_cache_key({ -key => $key });  | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->update({ -cache_key => $cache_key, -value => $value });  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $cache_key = $cache->make_cache_key({ -key => $key });  | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->update({ -cache_key => $cache_key, -value => $value, -keep_last => 50 });  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  -cache_key is assumed to be a simple scalar value for use as a key.  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  -key can be pretty much anything Storable can successfully and reproducibly serialize.  | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 One or the other I be passed.  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub update {  | 
| 
459
 | 
21
 | 
 
 | 
 
 | 
  
21
  
 | 
  
1
  
 | 
6001426
 | 
     my $self = shift;  | 
| 
460
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
     my $package = __PACKAGE__;  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
462
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
164
 | 
     my $parms = parse_parms({ -parms => \@_,  | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                               -legal => ['-keep_last', '-key', '-cache_key'],  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            -required => ['-value'],  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            -defaults => {'-keep_last' => $self->keep_last},  | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          });  | 
| 
467
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
3555
 | 
     unless (defined $parms) {  | 
| 
468
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         my $error_message = Class::ParmList->error;  | 
| 
469
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         require Carp;  | 
| 
470
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
         Carp::croak ($package . "::update() - $error_message\n");  | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
472
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
     my ($key,$cache_key,$value,$keep_last) = $parms->get('-key', '-cache_key', '-value', '-keep_last');  | 
| 
473
 | 
20
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
981
 | 
     unless (defined ($key) or defined ($cache_key)) {  | 
| 
474
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         require Carp;  | 
| 
475
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
         Carp::croak ($package . "::update() - Called without either a -key or -cache_key. At least one of them must be passed.\n");  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
478
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
     my ($cache_dir) = $self->cache_dir;  | 
| 
479
 | 
19
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
     unless (defined $cache_dir) {  | 
| 
480
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         require Carp;  | 
| 
481
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
         Carp::croak ($package . "::update - No cache directory set.\n");  | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Generate the cache_key (done by making a cannonical  | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # network order Storable string out of the key) if we  | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # don't already have one.  | 
| 
487
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
54
 | 
     unless (defined $cache_key) {  | 
| 
488
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         $cache_key = $self->make_cache_key({ -key => $key });  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Generate a unique cache file  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # name by taking a SHA1 hash of  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # $cache_key and dumping it as hex  | 
| 
494
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
268
 | 
     my $cache_hash = lc(sha1_hex($cache_key));  | 
| 
495
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
     $cache_hash    =~ s/\s//gs;  | 
| 
496
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
151
 | 
     my ($untainted_cache_hash) = $cache_hash =~ m/^([a-f0-9]+)$/s;  | 
| 
497
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
383
 | 
     my $cache_file  = File::Spec->catfile($cache_dir, "cl_$untainted_cache_hash");  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Serialize the $value for storage  | 
| 
500
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
77
 | 
     my $entry = { -value => $value };  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set our lock on the cache directory  | 
| 
503
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
86
 | 
     $self->_lock_cache;  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ##########  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Store the cache entry.  | 
| 
507
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     my $result;  | 
| 
508
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
     eval { $result = nstore($entry,$cache_file); };  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117
 | 
    | 
| 
509
 | 
18
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5491
 | 
     if ($@) {  | 
| 
510
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $@;  | 
| 
511
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
512
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
513
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak($package . "::update - Error while saving cache entry file '$cache_file': $error");  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
515
 | 
18
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
55
 | 
     unless (defined $result) {  | 
| 
516
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
517
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
518
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
519
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak($package . "::update - Error while saving cache entry file '$cache_file': $error\n");  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ########################################  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Check if we need to purge old entries  | 
| 
524
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     my $cache_dir_fh = gensym;  | 
| 
525
 | 
18
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
672
 | 
     unless (opendir ($cache_dir_fh, $cache_dir)) {  | 
| 
526
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
527
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
528
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
529
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::update - Failed to open directory '$cache_dir' for reading: $error\n");  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
531
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
701
 | 
     my @raw_file_list = grep(/^(cacheline_[a-fA-F0-9]{1,50}|cl_[a-fA-F0-9]{1,50})$/s,readdir($cache_dir_fh));  | 
| 
532
 | 
18
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
292
 | 
     unless (closedir ($cache_dir_fh)) {  | 
| 
533
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
534
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
535
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
536
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::update - Failed to close directory '$cache_dir': $error\n");  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  Untainting the filenames and converting them to absolute file paths.  | 
| 
540
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
     my @file_list = ();  | 
| 
541
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     foreach my $item (@raw_file_list) {  | 
| 
542
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
221
 | 
         my ($filename) = $item =~ m/^(.*)$/s;  | 
| 
543
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
460
 | 
         my $file_path =  File::Spec->catfile($cache_dir, $filename);  | 
| 
544
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
         push (@file_list,$file_path);  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
546
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     my $n_files = $#file_list + 1;  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # No problems. All done.  | 
| 
549
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
58
 | 
     if ($n_files <= $keep_last) {  | 
| 
550
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
         $self->_unlock_cache;  | 
| 
551
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
164
 | 
         return;  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Too many entries. Delete the excess entries (usually only one)  | 
| 
555
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my %file_last_access = ();  | 
| 
556
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     foreach my $file (@file_list) {  | 
| 
557
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
271
 | 
         my $last_accessed = (stat($file))[9];  | 
| 
558
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
         $file_last_access{$file} = $last_accessed;  | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
560
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     my @sorted_file_list =  sort { $file_last_access{$b} <=> $file_last_access{$a} } @file_list;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
70
 | 
    | 
| 
561
 | 
4
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
30
 | 
     while (($n_files > $keep_last) and ($n_files > 0))  {  | 
| 
562
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         $n_files--;  | 
| 
563
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         my $pruned_file = $sorted_file_list[$n_files];  | 
| 
564
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
266
 | 
         unless (unlink $pruned_file) {  | 
| 
565
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $error = $!;  | 
| 
566
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $self->_unlock_cache;  | 
| 
567
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             require Carp;  | 
| 
568
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             Carp::croak($package . "::update - Failed to unlink file '$pruned_file': $error");  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Release our lock and return  | 
| 
573
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
     $self->_unlock_cache;  | 
| 
574
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
     return;  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item delete({ -key => $key });  | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Forces the deletion of a specific key from the cache.  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Example:  | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $cache->delete({ -key => $key });  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub delete {  | 
| 
594
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
101
 | 
     my $self = shift;  | 
| 
595
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $package = __PACKAGE__;  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
597
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     my $parms = parse_parms({ -parms => \@_,  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                               -legal => [-key, -cache_key],  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            -required => [],  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            -defaults => {},  | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          });  | 
| 
602
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
647
 | 
     if (not defined $parms) {  | 
| 
603
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         my $error_message = Class::ParmList->error;  | 
| 
604
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         require Carp;  | 
| 
605
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
         Carp::croak ($package . "::delete() - $error_message\n");  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
607
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     my ($key,$cache_key) = $parms->get(-key, -cache_key);  | 
| 
608
 | 
6
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
146
 | 
     if (not (defined ($key) or defined ($cache_key))) {  | 
| 
609
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         require Carp;  | 
| 
610
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
         Carp::croak ($package . "::delete() - Called without either a -key or -cache_key\n");  | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
613
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     my $cache_dir = $self->cache_dir;  | 
| 
614
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     unless (defined $cache_dir) {  | 
| 
615
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         require Carp;  | 
| 
616
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
         Carp::croak ($package . "::delete - No cache directory set.\n");  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
618
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     if ($cache_dir eq '') {  | 
| 
619
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
620
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::delete - Cannot use root directory as cache directory.\n");  | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Generate the cache_key (done by making a cannonical  | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # network order Storable string out of the key) if we  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # don't already have it  | 
| 
626
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     if (not defined $cache_key) {  | 
| 
627
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         $cache_key = $self->make_cache_key({ -key => $key });  | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Generate a unique cache file  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # name by taking a SHA1 hash of  | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # $cache_key  | 
| 
633
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     my $cache_hash = lc(sha1_hex($cache_key));  | 
| 
634
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     $cache_hash    =~ s/\s//gs;  | 
| 
635
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     my ($untainted_cache_hash) = $cache_hash =~ m/^([a-f0-9]+)$/s;  | 
| 
636
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
     my $cache_file  = File::Spec->catfile($cache_dir, "cl_$untainted_cache_hash");  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Ok. Set our lock on the cache directory  | 
| 
639
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $self->_lock_cache;  | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # If it is in the cache, remove it  | 
| 
642
 | 
4
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
218
 | 
     if ((-e $cache_file) and (not unlink $cache_file)) {  | 
| 
643
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
644
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->_unlock_cache;  | 
| 
645
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
646
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak($package . "::delete - Failed to unlink file '$cache_file': $error");  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Release our lock and return  | 
| 
650
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     $self->_unlock_cache;  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item cache_dir([$cache_directory_path]);  | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Get/Set accessor for the cache directory path.  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Ex.  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $cache_directory = $cache->cache_dir;  | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $cache->cache_dir($cache_directory);  | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
671
 | 
163
 | 
 
 | 
 
 | 
  
163
  
 | 
  
1
  
 | 
348
 | 
 sub cache_dir   { return shift->_property('cache_dir',   @_); }  | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item keep_last([$keep_last_n]);  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Get/Set accessor for the keep last N setting.  | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Ex.  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $n_last = $cache->keep_last;  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $cache->keep_last(20);  | 
| 
686
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
690
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
691
 | 
37
 | 
 
 | 
 
 | 
  
37
  
 | 
  
1
  
 | 
137
 | 
 sub keep_last   { return shift->_property('keep_last',   @_); }  | 
| 
692
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
693
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
694
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
695
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
696
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item number_of_entries;  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
700
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Returns the current number of entries in the cache.  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
703
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub number_of_entries {  | 
| 
707
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
2000426
 | 
     my $self = shift;  | 
| 
708
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my $package = __PACKAGE__;  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
710
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     my $cache_dir_fh = gensym;  | 
| 
711
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
     my $cache_dir    = $self->cache_dir;  | 
| 
712
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     unless (defined $cache_dir) {  | 
| 
713
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
714
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::delete - No cache directory set.\n");  | 
| 
715
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
716
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     if ($cache_dir eq '') {  | 
| 
717
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
718
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::delete - Cannot use root directory as cache directory.\n");  | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
721
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
157
 | 
     unless (opendir ($cache_dir_fh, $cache_dir)) {  | 
| 
722
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
723
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
724
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::update - Failed to open directory '$cache_dir' for reading: $error\n");  | 
| 
725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
726
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
149
 | 
     my @raw_file_list = grep(/^(cacheline_[a-fA-F0-9]{1,50}|cl_[a-fA-F0-9]{1,50})$/s,readdir($cache_dir_fh));  | 
| 
727
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
57
 | 
     unless (closedir ($cache_dir_fh)) {  | 
| 
728
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
729
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
730
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::update - Failed to close directory '$cache_dir': $error\n");  | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
732
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $n_entries = $#raw_file_list + 1;  | 
| 
733
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     return $n_entries;  | 
| 
734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
735
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
736
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                                                                     #  | 
| 
738
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # PRIVATE METHODS                                                     #  | 
| 
739
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                                                                     #  | 
| 
740
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Internals. Documented for maintainance reasons only.                #  | 
| 
741
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Do not use these methods from outside this module.                  #  | 
| 
742
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                                                                     #  | 
| 
743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
744
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
745
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
746
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # _cache_lock_fh([$fh]);  | 
| 
747
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
748
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Get/Set accessor used to store a reference to the filehandle  | 
| 
749
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # used for locking.  | 
| 
750
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
751
 | 
134
 | 
 
 | 
 
 | 
  
134
  
 | 
 
 | 
286
 | 
 sub _cache_lock_fh { return shift->_property('_cache_lock_fh', @_); }  | 
| 
752
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
753
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
754
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # _lock_cache;  | 
| 
755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
756
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Obtains a lock on the 'cache.lock' file for this LRU cache.  | 
| 
757
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
758
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  Example:  | 
| 
759
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #     $self->_lock_cache;  | 
| 
760
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
761
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # This will create the 'cache.lock' file if it does not already exist,  | 
| 
762
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # creating any intermediate directories as needed.  | 
| 
763
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
764
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # It also writes the current PID to the lock file.  | 
| 
765
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
766
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _lock_cache {  | 
| 
767
 | 
67
 | 
 
 | 
 
 | 
  
67
  
 | 
 
 | 
82
 | 
     my $self = shift;  | 
| 
768
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
     my $package = __PACKAGE__;  | 
| 
769
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
770
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
122
 | 
     my $cache_dir = $self->cache_dir;  | 
| 
771
 | 
67
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
135
 | 
     if (not defined $cache_dir) {  | 
| 
772
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
773
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::_lock_cache - No cache directory set.\n");  | 
| 
774
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
775
 | 
67
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
135
 | 
     if ($cache_dir eq '') {  | 
| 
776
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
777
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::_lock_cache - Cannot use root directory as cache directory.\n");  | 
| 
778
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
779
 | 
67
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
1870
 | 
     if ((-e $cache_dir) and (not -d _)) {  | 
| 
780
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
781
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::_lock_cache - '$cache_dir' already exists and is not a directory.\n");  | 
| 
782
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
783
 | 
67
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
730
 | 
     if (not -e $cache_dir) {  | 
| 
784
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         eval {  | 
| 
785
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             require File::Path;  | 
| 
786
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             File::Path::mkpath ($cache_dir);  | 
| 
787
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
788
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ($@) {  | 
| 
789
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
            my $error = $@;  | 
| 
790
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
            require Carp;  | 
| 
791
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
            Carp::croak ($package . "::_lock_cache - unable to create directory '$cache_dir': $error");  | 
| 
792
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
793
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
794
 | 
67
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
747
 | 
     if (not ((-e $cache_dir) and (-d _))) {  | 
| 
795
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
796
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::_lock_cache - Unable to create directory '$cache_dir'\n");  | 
| 
797
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
798
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
792
 | 
     my $document_name = File::Spec->catfile($cache_dir,'.cache.lock');  | 
| 
799
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
265
 | 
     my $cache_lock_fh = gensym;  | 
| 
800
 | 
67
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3633
 | 
     unless (open ($cache_lock_fh,">>$document_name")) {  | 
| 
801
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
802
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
803
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::_lock_cache - Unable to open '$document_name': $error\n");  | 
| 
804
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
805
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
254
 | 
     my $lock_timeout = 100;  | 
| 
806
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
729
 | 
     while (not flock($cache_lock_fh, LOCK_EX()|LOCK_NB())) {  | 
| 
807
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $lock_timeout--;  | 
| 
808
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         select (undef,undef,undef,0.1);  | 
| 
809
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ($lock_timeout == 0) {  | 
| 
810
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $error = $!;  | 
| 
811
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             require Carp;  | 
| 
812
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             Carp::croak ($package . "::_lock_cache - Unable to get an exclusive lock on '$document_name': $error\n");  | 
| 
813
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
814
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
815
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
350
 | 
     my $fh = select ($cache_lock_fh);  | 
| 
816
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
241
 | 
     $|++;  | 
| 
817
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
161
 | 
     select ($fh);  | 
| 
818
 | 
67
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1750
 | 
     unless (truncate ($cache_lock_fh, 0)) {  | 
| 
819
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
820
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
821
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::_lock_cache - Unable to truncate '$document_name': $error\n");  | 
| 
822
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
823
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1997
 | 
     print $cache_lock_fh "$$\n";  | 
| 
824
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
312
 | 
     $self->_cache_lock_fh($cache_lock_fh);  | 
| 
825
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
826
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
116
 | 
     return;  | 
| 
827
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
828
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
829
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
830
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
831
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # _unlock_cache;  | 
| 
832
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
833
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Release a lock on the 'cache.lock' file for this LRU cache.  | 
| 
834
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
835
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  Example:  | 
| 
836
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #     $self->_unlock_cache;  | 
| 
837
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
838
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _unlock_cache {  | 
| 
839
 | 
67
 | 
 
 | 
 
 | 
  
67
  
 | 
 
 | 
109
 | 
     my $self = shift;  | 
| 
840
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87
 | 
     my $package = __PACKAGE__;  | 
| 
841
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
842
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
107
 | 
     my $cache_lock_fh = $self->_cache_lock_fh;  | 
| 
843
 | 
67
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1876
 | 
     unless (truncate ($cache_lock_fh,0)) {  | 
| 
844
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
845
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
846
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::_lock_cache - Unable to truncate cache.lock file: $error\n");  | 
| 
847
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
848
 | 
67
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
921
 | 
     unless (close ($cache_lock_fh)) {  | 
| 
849
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $error = $!;  | 
| 
850
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
851
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak ($package . "::_unlock_cache - Error while closing cache.lock file: $error\n");  | 
| 
852
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
853
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
220
 | 
     return;  | 
| 
854
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
855
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
856
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ####################################################################  | 
| 
857
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # _property('property_name' => $property_value)  | 
| 
858
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
859
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # get/set base accessor for property values  | 
| 
860
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
861
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _property {  | 
| 
862
 | 
334
 | 
 
 | 
 
 | 
  
334
  
 | 
 
 | 
430
 | 
     my $self    = shift;  | 
| 
863
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
864
 | 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
409
 | 
     my $property = shift;  | 
| 
865
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
866
 | 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
400
 | 
     my $package = __PACKAGE__;  | 
| 
867
 | 
334
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
652
 | 
     if (0 == @_) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
868
 | 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
382
 | 
         my $output = $self->{$package}->{$property};  | 
| 
869
 | 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
669
 | 
         return $output;  | 
| 
870
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
871
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (1 == @_) {  | 
| 
872
 | 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
         my $input = shift;  | 
| 
873
 | 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
210
 | 
         $self->{$package}->{$property} = $input;  | 
| 
874
 | 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
380
 | 
         return;  | 
| 
875
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
876
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
877
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         require Carp;  | 
| 
878
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         Carp::croak("Bad calling parameters to ${package}::${property}()\n");  | 
| 
879
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
880
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
881
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
882
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ####################################################################  | 
| 
883
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
884
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub TIEHASH {  | 
| 
885
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
815
 | 
     my $proto = shift;  | 
| 
886
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $package = __PACKAGE__;  | 
| 
887
 | 
4
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
18
 | 
     my $class = ref ($proto) || $proto || $package;  | 
| 
888
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $self  = bless {}, $class;  | 
| 
889
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
890
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my ($cache_dir,$keep_last) = @_;  | 
| 
891
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
892
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     $keep_last = 100 unless (defined $keep_last);  | 
| 
893
 | 
4
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
22
 | 
     unless (defined ($cache_dir) and ($cache_dir ne '')) {  | 
| 
894
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         require Carp;  | 
| 
895
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
174
 | 
         Carp::croak($package . ": Missing required parameter (cache_dir)\n");  | 
| 
896
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
897
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     $self->cache_dir($cache_dir);  | 
| 
898
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $self->keep_last($keep_last);  | 
| 
899
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     return $self;  | 
| 
900
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
902
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
903
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
904
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub STORE {  | 
| 
905
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
 
 | 
6001338
 | 
     my $self = shift;  | 
| 
906
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
907
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     my ($key,$value) = @_;  | 
| 
908
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
909
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
66
 | 
     if (ref(\$key) eq 'SCALAR') {  | 
| 
910
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
         $self->update({ -cache_key => $key, -value => $value });  | 
| 
911
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
912
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         $self->update({ -key => $key, -value => $value });  | 
| 
913
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
914
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
915
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
916
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
917
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
918
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub FETCH {  | 
| 
919
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
53
 | 
     my $self = shift;  | 
| 
920
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
921
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     my ($key)  = @_;  | 
| 
922
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
923
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     if (ref(\$key) eq 'SCALAR') {  | 
| 
924
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
         my ($cache_hit, $value) = $self->check({ -cache_key => $key });  | 
| 
925
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
         return $value;  | 
| 
926
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
927
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
928
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         my ($cache_hit,$value) = $self->check({ -key => $key });  | 
| 
929
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         return $value;  | 
| 
930
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
931
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
932
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
933
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
934
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
935
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
936
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub DELETE {  | 
| 
937
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
20
 | 
     my $self = shift;  | 
| 
938
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
939
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     my ($key) = @_;  | 
| 
940
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
941
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     if (ref(\$key) eq 'SCALAR') {  | 
| 
942
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         $self->delete({ -cache_key => $key });  | 
| 
943
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
944
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         $self->delete({ -key => $key });  | 
| 
945
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
946
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
947
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
948
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
949
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub CLEAR {  | 
| 
951
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
8
 | 
     my $self = shift;  | 
| 
952
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
953
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     $self->clear;  | 
| 
954
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
955
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
956
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
957
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
958
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub EXISTS {  | 
| 
959
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
176
 | 
     my $self = shift;  | 
| 
960
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
961
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     my ($key) = @_;  | 
| 
962
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
963
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
     if (ref(\$key) eq 'SCALAR') {  | 
| 
964
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
         my ($cache_hit,$value) = $self->check({ -cache_key => $key });  | 
| 
965
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
         return $cache_hit;  | 
| 
966
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
967
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         my ($cache_hit,$value) = $self->check({ -key => $key });  | 
| 
968
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         return $cache_hit;  | 
| 
969
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
970
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
971
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
972
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
973
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
974
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
975
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Iteration over the cache is not supported  | 
| 
976
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
977
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
978
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
15
 | 
 sub FIRSTKEY { undef; }  | 
| 
979
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
980
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
981
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
982
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
983
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Iteration over the cache is not supported  | 
| 
984
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
985
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
986
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 sub NEXTKEY { undef; }  | 
| 
987
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
988
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
989
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
990
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # We return the number of cache entries in a scalar context  | 
| 
991
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
992
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
993
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub SCALAR {  | 
| 
994
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
     my $self = shift;  | 
| 
995
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
996
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->number_of_entries;  | 
| 
997
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
998
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
999
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
1000
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #######################################################################  | 
| 
1001
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1002
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT  | 
| 
1003
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1004
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Copyright 1999, 2020 Jerilyn Franz and FreeRun Technologies, Inc. All Rights Reserved.  | 
| 
1005
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1006
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VERSION  | 
| 
1007
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1008
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  1.06 released 2020.10.08  | 
| 
1009
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1010
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 LICENSE  | 
| 
1011
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1012
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 MIT License  | 
| 
1013
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1014
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Copyright (c) 2020 Jerilyn Franz  | 
| 
1015
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1016
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Permission is hereby granted, free of charge, to any person obtaining a copy  | 
| 
1017
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 of this software and associated documentation files (the "Software"), to deal  | 
| 
1018
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 in the Software without restriction, including without limitation the rights  | 
| 
1019
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  | 
| 
1020
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 copies of the Software, and to permit persons to whom the Software is  | 
| 
1021
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 furnished to do so, subject to the following conditions:  | 
| 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1023
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The above copyright notice and this permission notice shall be included in all  | 
| 
1024
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 copies or substantial portions of the Software.  | 
| 
1025
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1026
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  | 
| 
1027
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  | 
| 
1028
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  | 
| 
1029
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  | 
| 
1030
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  | 
| 
1031
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  | 
| 
1032
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 SOFTWARE.  | 
| 
1033
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1034
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DISCLAIMER  | 
| 
1035
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1036
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS  | 
| 
1037
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE  | 
| 
1038
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  | 
| 
1039
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 PARTICULAR PURPOSE.  | 
| 
1040
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1041
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Use of this software in any way or in any form, source or binary,  | 
| 
1042
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is not allowed in any country which prohibits disclaimers of any  | 
| 
1043
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 implied warranties of merchantability or fitness for a particular  | 
| 
1044
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 purpose or any disclaimers of a similar nature.  | 
| 
1045
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1046
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,  | 
| 
1047
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 SPECIAL, INCIDENTAL,  OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE  | 
| 
1048
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 USE OF THIS SOFTWARE AND ITS DOCUMENTATION (INCLUDING, BUT NOT  | 
| 
1049
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 LIMITED TO, LOST PROFITS) EVEN IF I HAVE BEEN ADVISED OF THE  | 
| 
1050
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 POSSIBILITY OF SUCH DAMAGE  | 
| 
1051
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1052
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
1053
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1054
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Jerilyn Franz  | 
| 
1055
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 TODO  | 
| 
1057
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1058
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Nothing.  | 
| 
1059
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1060
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
1061
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1062
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |