summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Hutchinson <jlhutch@gmail.com>2010-08-25 00:20:25 -0500
committerJay Hutchinson <jlhutch@gmail.com>2010-08-25 00:20:25 -0500
commit921882ca647f8c046ccf735deabbf19ae7020b39 (patch)
treef0df0f2803cf0f14e37b188f2ea7f7a8b238f4b2
parent1ab7e96778db3daa0f343946d91136c74147d2a0 (diff)
downloadpylru-921882ca647f8c046ccf735deabbf19ae7020b39.tar.gz
Started modifications on lrucache and lruwrapper to add optional write-back cache semantics.
-rw-r--r--lru.py52
1 files changed, 45 insertions, 7 deletions
diff --git a/lru.py b/lru.py
index 6df1507..f14ebf7 100644
--- a/lru.py
+++ b/lru.py
@@ -44,9 +44,9 @@ class _dlnode(object):
class lrucache(object):
- def __init__(self, size):
+ def __init__(self, size, callback=None):
-
+ self.callback = callback
# Initialize the hash table as empty.
self.table = {}
@@ -68,6 +68,11 @@ class lrucache(object):
return len(self.table)
def clear(self):
+ if self.callback:
+ for key in self.table:
+ node = self.table[key]
+ self.callback(node.key, node.obj)
+
self.table.clear()
node = self.head
@@ -131,9 +136,11 @@ class lrucache(object):
# If the node already contains something we need to remove the old key from
# the dictionary.
if node.key is not None:
+ if self.callback:
+ self.callback(node.key, node.obj)
del self.table[node.key]
- # Place the key and the object in the node
+ # Place the new key and object in the node
node.key = key
node.obj = obj
@@ -201,6 +208,8 @@ class lrucache(object):
assert self.listSize > 1 # Invarient
node = self.head.prev
if node.key is not None:
+ if self.callback:
+ self.callback(node.key, node.obj)
del self.table[node.key]
# Splice the tail node out of the list
@@ -251,18 +260,31 @@ class lrucache(object):
# Wrapper using write-through semantics
class lruwrap(object):
- def __init__(self, store, size):
- self.cache = lrucache(size)
+ def __init__(self, store, size, writethrough=True):
+ self.writethrough = writethrough
+
+ if self.writethrough:
+ self.cache = lrucache(size)
+ else:
+ self.cache = lrucache(size, self.ejectCallBack)
+ self.dirty = set()
+
self.store = store
+
+
def __len__(self):
+ # XXX We could cache the size
return len(self.store)
def clear(self):
self.cache.clear()
+ if self.writethrough: # XXX Remove this test XXX
+ assert len(self.dirty) == 0
self.store.clear()
-
+
def __contains__(self, key):
+ # XXX Should this bring the key/value into the cache?
if key in self.cache:
return True
if key in self.store:
@@ -280,14 +302,30 @@ class lruwrap(object):
def __setitem__(self, key, value):
self.cache[key] = value
- self.store[key] = value
+ if self.writethrough:
+ self.store[key] = value
+ else:
+ self.dirty.add(key)
+
def __delitem__(self, key):
try:
del self.cache[key]
+ if not self.writethrough:
+ self.dirty.remove(key)
except KeyError:
pass
del self.store[key]
+
+ def ejectCallback(self, key, value):
+ if key in self.dirty:
+ self.store[key] = value
+ self.dirty.remove(key)
+
+ def __del__(self):
+ # Flush the dirty objects
+ self.sync()
+
class lrudecorator(object):