ensembl-hive  2.8.1
LruIdCache.pm
Go to the documentation of this file.
1 =head1 LICENSE
2 
3 See the NOTICE file distributed with this work for additional information
4 regarding copyright ownership.
5 
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 
18 =cut
19 
20 
21 =head1 CONTACT
22 
23  Please email comments or questions to the public Ensembl
24  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.
25 
26  Questions may also be sent to the Ensembl help desk at
27  <http://www.ensembl.org/Help/Contact>.
28 
29 =cut
30 
31 =head1 NAME
32 
33 Bio::EnsEMBL::DBSQL::Support::LruIdCache - ID based caching using an LRU backed cache
34 
35 =head1 SYNOPSIS
36 
37  my $cache = Bio::EnsEMBL::DBSQL::Support::LruIdCache->new($adaptor, 2);
38  my $obj = $cache->put(1, 'a');
39  my $obj = $cache->put(2, 'b');
40  my $obj = $cache->put(3, 'c');
41 
42  is_deeply([$cache->cache_keys()], ['b','c']); #ID 1 was ejected under LRU rules
43 
44 =head1 DESCRIPTION
45 
46 An implementation of caching which uses the oldest accessed key as the
47 value to be ejected from the cache when the maximum size has been hit. See
48 the following page for more information about this algorithm
49 
50 http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used
51 
52 =head1 METHODS
53 
54 =cut
55 
56 package Bio::EnsEMBL::DBSQL::Support::LruIdCache;
57 
58 use strict;
59 use warnings;
62 use Bio::EnsEMBL::Utils::Scalar qw/assert_ref/;
63 
64 my $DEFAULT = 1000;
65 
66 =head2 new
67 
68  Arg [1] : Bio::EnsEMBL::DBSQL::BaseAdaptor $db_adaptor
69  Arg [2] : Int size of the cache. Defaults to 1000
70  Example : my $cache = Bio::EnsEMBL::DBSQL::Support::LruIdCache->new($db_adaptor, 10);
71  Description: Creates a new cache class instance
73  Exceptions : none
74  Caller : BaseAdaptors
75  Status : Beta
76 
77 =cut
78 
79 sub new {
80  my ($class, $adaptor, $lru_size) = @_;
81  my $self = $class->SUPER::new($adaptor);
82  $lru_size ||= $DEFAULT;
83  $self->lru_size($lru_size);
84  return $self;
85 }
86 
87 =head2 lru_size
88 
89  Arg [1] : Int size of the cache
90  Example : $cache->lru_size(10);
91  Description: Resets the size of the cache and forces a rebuild of the cache
92  object to apply this new sizing. Also functions as a getter
93  Returntype : Int
94  Exceptions : none
95  Caller : BaseAdaptors
96  Status : Beta
97 
98 =cut
99 
100 sub lru_size {
101  my ($self, $lru_size) = @_;
102  if(defined $lru_size) {
103  $self->{'lru_size'} = $lru_size;
104  $self->delete_cache();
105  }
106  return $self->{'lru_size'};
107 }
108 
109 =head2 build_cache
110 
111  Description: Returns an instance of C<Bio::EnsEMBL::Utils::Cache> and sized
112  according to the return value in C<lru_cache()>
113  Returntype : Bio::EnsEMBL::Utils::Cache
114  Exceptions : none
115  Caller : BaseAdaptors
116  Status : Beta
117 
118 =cut
119 
120 sub build_cache {
121  my ($self) = @_;
122  tie my %cache, 'Bio::EnsEMBL::Utils::Cache', $self->lru_size();
123  return \%cache;
124 }
125 
126 =head2 get
127 
128  Arg [1] : String key to retrieve
129  Example : $is($cache->get(1), 'a');
130  Description: Retrieves the value held in the cache. If the value is not in
131  the cache we will retrieve the value from
132  C<_uncached_fetch_by_dbID> and then store that value
133  Returntype : Scalar value held in the cache or nothing if the ID was not present
134  Exceptions : If key was undefined
135  Caller : BaseAdaptors
136  Status : Beta
137 
138 =cut
139 
140 sub get {
141  my ($self, $key) = @_;
142  my $value = $self->SUPER::get($key);
143  if(! defined $value) {
144  my $new_value = $self->adaptor()->_uncached_fetch_by_dbID($key);
145  if(defined $new_value) {
146  $self->put($key, $new_value);
147  $value = $new_value;
148  }
149  }
150  return $value if defined $value;
151  return;
152 }
153 
154 =head2 get_by_list
155 
156  Arg [1] : ArrayRef keys to retrieve
157  Arg [2] : Bio::EnsEMBL::Slice optional attribute for
158  C<_uncached_fetch_all_by_dbID_list()> delegation
159  Example : is($cache->get_by_list([1,2]), ['a','b']);
160  Description: Attempts to retrieve all values currently available in the cache,
161  fetches any remaining values and stores these in the cache.
162  Returntype : ArrayRef of found values
163  Exceptions : None
164  Caller : BaseAdaptors
165  Status : Beta
166 
167 =cut
168 
169 sub get_by_list {
170  my ($self, $list, $slice) = @_;
171  assert_ref($list, 'ARRAY', 'list');
172  my $results = $self->SUPER::get_by_list($list);
173  my %available = map { $_->dbID(), $_ } @{$results};
174  my @to_fetch;
175  foreach my $input (@{$list}) {
176  next if ! defined $input;
177  push(@to_fetch, $input) if ! exists $available{$input};
178  }
179 
180  my $fetched = $self->adaptor()->_uncached_fetch_all_by_dbID_list(\@to_fetch, $slice);
181  foreach my $obj (@{$fetched}) {
182  push(@{$results}, $obj);
183  $self->put($obj->dbID(), $obj);
184  }
185 
186  return $results;
187 }
188 
189 1;
map
public map()
Bio::EnsEMBL::DBSQL::Support::BaseCache::delete_cache
public void delete_cache()
Bio::EnsEMBL::DBSQL::Support::BaseCache
Definition: BaseCache.pm:55
Bio::EnsEMBL::Slice
Definition: Slice.pm:50
Bio::EnsEMBL::Utils::Cache
Definition: Cache.pm:71
Bio::EnsEMBL::DBSQL::Support::BaseCache::put
public Scalar put()
about
public about()
Bio::EnsEMBL::DBSQL::BaseAdaptor
Definition: BaseAdaptor.pm:71
Bio::EnsEMBL::Utils::Scalar
Definition: Scalar.pm:66
Bio::EnsEMBL::DBSQL::Support::LruIdCache::new
public Bio::EnsEMBL::DBSQL::Support::BaseCache new()
Bio::EnsEMBL::DBSQL::Support::LruIdCache
Definition: LruIdCache.pm:27