Skip to content

Commit b02d3ef

Browse files
Added doctests for the DecayingLRUCache class
1 parent 0cb17b0 commit b02d3ef

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

README.txt

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,97 @@ same key value (though any number of concurrent threads might be busy loading
254254
the resources associated with different keys).
255255

256256

257+
Caching and stale entries
258+
==========================
259+
260+
There is another `AutoLRUCache`-like class provided by the LRU module,
261+
which gives more control over timing out of entries than `AutoLRUCache` does.
262+
263+
264+
>>> from darts.lib.utils.lru import DecayingLRUCache
265+
>>> current_time = 0
266+
>>> def tick():
267+
... global current_time
268+
... current_time += 1
269+
270+
Here, we defined a simple "clock". We could have used the system clock,
271+
but roling our own here gives us more control over the notion of "time".
272+
Now, let's define a simple cache entry:
273+
274+
>>> from collections import namedtuple
275+
>>> Entry = namedtuple("Entry", "timestamp payload")
276+
>>> def make_entry(payload):
277+
... return Entry(current_time, payload)
278+
279+
and a loader function
280+
281+
>>> def load(full_key):
282+
... print "Loading", full_key
283+
... return make_entry(u"Entry for %r" % (full_key,))
284+
285+
For the following parts, we consider an entry to be "too old", if it has
286+
been created more then two "ticks" ago:
287+
288+
>>> def is_still_current(entry):
289+
... return current_time - entry.timestamp <= 2
290+
291+
Finally, we create another cache thingy
292+
293+
>>> cache = DecayingLRUCache(load, tester=is_still_current, capacity=3)
294+
295+
The `DecayingLRUCache` shows much of the same behaviour of the `AutoLRUCache`,
296+
namely:
297+
298+
>>> cache.load(1)
299+
Loading 1
300+
Entry(timestamp=0, payload=u'Entry for 1')
301+
>>> cache.load(2)
302+
Loading 2
303+
Entry(timestamp=0, payload=u'Entry for 2')
304+
>>> cache.load(3)
305+
Loading 3
306+
Entry(timestamp=0, payload=u'Entry for 3')
307+
>>> cache.load(4)
308+
Loading 4
309+
Entry(timestamp=0, payload=u'Entry for 4')
310+
>>> cache.load(1)
311+
Loading 1
312+
Entry(timestamp=0, payload=u'Entry for 1')
313+
314+
The entry with key `1` had to be reloaded, since the cache has a capacity of
315+
3, and the old entry for `1` was evicted when the entry for `4` was loaded
316+
and we needed to make room.
317+
318+
>>> cache.load(3)
319+
Entry(timestamp=0, payload=u'Entry for 3')
320+
321+
Now, let's advance time
322+
323+
>>> tick()
324+
>>> cache.load(3)
325+
Entry(timestamp=0, payload=u'Entry for 3')
326+
327+
The entry is still available.
328+
329+
>>> tick()
330+
>>> cache.load(3)
331+
Entry(timestamp=0, payload=u'Entry for 3')
332+
>>> tick()
333+
>>> cache.load(3)
334+
Loading 3
335+
Entry(timestamp=3, payload=u'Entry for 3')
336+
337+
Note, that eviction is still based on LRU, not on the age test.
338+
339+
257340
Change Log
258341
==========
259342

343+
Version 0.4
344+
------------
345+
346+
Added class `DecayingLRUCache`
347+
260348
Version 0.3
261349
------------
262350

darts/lib/utils/lru.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"""
2626

2727
import sys
28-
from threading import RLock, Condition, Thread
28+
from threading import RLock, Lock, Condition, Thread
2929

3030
__all__ = (
3131
'LRUDict', 'AutoLRUCache', 'CacheLoadError', 'CacheAbandonedError',
@@ -823,7 +823,7 @@ class AutoLRUCache(object):
823823

824824
def __init__(self, loader, capacity=1024):
825825
super(AutoLRUCache, self).__init__()
826-
self.__lock = RLock()
826+
self.__lock = Lock()
827827
self.__cache = LRUDict(capacity)
828828
self.__loader = loader
829829
self.__loading = dict()
@@ -1011,7 +1011,7 @@ def __init__(self, loader, tester=good, key=identity, capacity=1024):
10111011
"""Initialize a new instance
10121012
"""
10131013

1014-
super(CarefulLRUCache, self).__init__()
1014+
super(DecayingLRUCache, self).__init__()
10151015
self.__lock = Lock()
10161016
self.__cache = LRUDict(capacity)
10171017
self.__loader = loader

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
setup(
2727
name = "darts.util.lru",
28-
version = "0.3",
28+
version = "0.4",
2929
description='Simple dictionary with LRU behaviour',
3030
zip_safe=True,
3131
packages = find_packages(),

0 commit comments

Comments
 (0)