summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Hutchinson <jlhutch@gmail.com>2010-09-09 14:16:38 -0500
committerJay Hutchinson <jlhutch@gmail.com>2010-09-09 14:16:38 -0500
commitf545ffd3f09bb609e90abbb4dd6fd7dbe56ba231 (patch)
tree8d3764aeda0bf4471eb2a278161beb1476842139
parenta0597ae7a87d0e55a675adadb92c5c0423ca18f9 (diff)
downloadpylru-f545ffd3f09bb609e90abbb4dd6fd7dbe56ba231.tar.gz
Updated README.txtv0.9.1
-rw-r--r--README.txt67
-rw-r--r--setup.py3
-rw-r--r--test.py17
3 files changed, 71 insertions, 16 deletions
diff --git a/README.txt b/README.txt
index c0babf5..6358c2c 100644
--- a/README.txt
+++ b/README.txt
@@ -4,9 +4,7 @@ PyLRU
A least recently used (LRU) cache for Python.
-Pylru implements a true LRU cache along with several support classes. The cache is efficient and written in pure Python. Basic operations (lookup, insert, delete) all run in a constant amount of time, regardless of the cache size.
-
-This documentation is a work in progress. Check back soon, I'm working on it regularly. Until then see the source.
+Pylru implements a true LRU cache along with several support classes. The cache is efficient and written in pure Python. It works with Python 2.6+ including the new 3.x series. Basic operations (lookup, insert, delete) all run in a constant amount of time.
Usage
@@ -18,7 +16,7 @@ An LRU cache object has a dictionary like interface and can be used in the same
import pylru
- size = 32
+ size = 100
cache = pylru.lrucache(size)
cache[key] = value # Add a key/value pair
@@ -28,13 +26,68 @@ An LRU cache object has a dictionary like interface and can be used in the same
cache.size() # Returns the size of the cache
cache.size(x) # Changes the size of the cache. x MUST be greater than
- # zero. Decreasing the size of the cache will cause
- # elements to be ejected from the cache if the new size
- # is smaller than len(cache).
+ # zero.
x = len(cache) # Returns the number of elements stored in the cache.
# x will be less than or equal to cache.size()
cache.clear() # Remove all elements from the cache.
+The lrucache takes an optional callback function as a second argument. Since the cache has a fixed size some operations, such as an insertion, may cause a key/value pair to be ejected. If the optional callback function is given it will be called when this occurs. For example::
+
+ import pylru
+
+ def callback(key, value):
+ print (key, value) # A dumb callback that just prints the key/value
+
+ size = 100
+ cache = pylru.lrucache(size, callback)
+
+ # Use the cache... When it gets full some pairs may be ejected due to
+ # the fixed cache size. But, not before the callback is called to let you
+ # know.
+
+Often a cache is used to speed up access to some other low latency object. If that object has a dictionary interface a convieniance wrapper class provided by PyLRU can be used. This class takes as an argument the object you want to wrap and the cache size. It then creates an LRU cache for the object and automatically manages it. For example, imagine you have an object with a dictionary interface that reads/writes its values to and from a remote server. Let us call this object slowDict::
+
+ import pylru
+
+ size = 100
+ cacheDict = pylru.lruwrap(slowDict, size)
+
+ # Now cacheDict can be used just like slowDict, except all of the lookups
+ # are automatically cached for you using an LRU cache.
+
+By default lruwrap uses write-through semantics. For instance, in the above example insertions are updated in the cache and written through to slowDict immediatly. The cache and the underlying object are not allowed to get out of sync. So only lookup performace can be improved by the cache. lruwrap takes an optional third argument. If set to True write-back semantics will be used. Insertions will be updated to the cache. The underlying slowDict will automatically be updated only when a "dirty" key/value pair is ejected from the cache.
+
+The programmer is responsible for one thing though. They MUST call sync() when they are finished. This ensures that the last of the "dirty" entries in the cache are written back::
+
+
+ import pylru
+
+ size = 100
+ cacheDict = pylru.lruwrap(slowDict, size, True)
+
+ # Now cacheDict can be used just like slowDict, except all of the lookups
+ # are automatically cached for you using an LRU cache with Write-Back
+ # semantics.
+
+ # DON'T forget to call sync() when finished
+ cacheDict.sync()
+
+ To help the programmer with this the lruwrap can be used in a with statement::
+ with pylru.lruwrap(slowDict, size, True) as cacheDict
+
+ # Use cacheDict, sync() is called automatically for you when leaving the
+ # with statment block.
+
+
+PyLRU also provides a function decorator::
+
+ from pylru import lrudecorator
+
+ @lrudecorator(100)
+ def square(x):
+ return x*x
+
+ # Now results of the square function are cached for future lookup.
diff --git a/setup.py b/setup.py
index bca8bde..073b43e 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from distutils.core import setup
setup(
name = "pylru",
- version = "0.9",
+ version = "0.9.1",
py_modules=['pylru'],
description = "A least recently used (LRU) cache implementation",
author = "Jay Hutchinson",
@@ -10,6 +10,7 @@ setup(
url = "http://github.com/jlhutch/pylru",
classifiers = [
"Programming Language :: Python :: 2.6",
+ "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
diff --git a/test.py b/test.py
index 1dce3e8..27c0c0d 100644
--- a/test.py
+++ b/test.py
@@ -1,5 +1,5 @@
-from lru import *
+from pylru import *
import random
@@ -60,19 +60,19 @@ class simplelrucache:
def basictest():
- a = lrucache(64)
- b = simplelrucache(64)
+ a = lrucache(128)
+ b = simplelrucache(128)
for i in range(500):
- x = random.randint(0, 256)
- y = random.randint(0, 256)
+ x = random.randint(0, 512)
+ y = random.randint(0, 512)
a[x] = y
b[x] = y
verify(a, b)
- for i in range(500):
- x = random.randint(0, 256)
+ for i in range(1000):
+ x = random.randint(0, 512)
if x in a:
assert x in b
z = a[x]
@@ -82,7 +82,7 @@ def basictest():
verify(a, b)
for i in range(256):
- x = random.randint(0, 256)
+ x = random.randint(0, 512)
if x in a:
assert x in b
del a[x]
@@ -172,6 +172,7 @@ def verify(a, b):
if __name__ == '__main__':
+ random.seed()
basictest()
wraptest()