<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -10,7 +10,7 @@
 &quot;&quot;&quot;Various caching utilites.
 &quot;&quot;&quot;
 
-__all__ = [&quot;memoize&quot;, &quot;clear_cache&quot;, &quot;TimedDict&quot;, &quot;MintCache&quot;]
+__all__ = [&quot;memoize&quot;, &quot;clear_cache&quot;, &quot;SizedDict&quot;, &quot;DictCache&quot;, &quot;MintCache&quot;]
 
 import time
 import math
@@ -24,8 +24,23 @@ local_cache = {'__created__': (time.ctime(), 0)}
 def clear_cache():
     &quot;&quot;&quot;Clear out the module cache&quot;&quot;&quot;
     local_cache.clear()
-    
-class TimedDict(object):
+
+class SizedDict(dict):
+    ''' A dictionary with a limit of items. '''
+
+    def __init__(self, size=1000):
+        dict.__init__(self)
+        self._maxsize = size
+        self._stack = []
+
+    def __setitem__(self, name, value):
+        if len(self._stack) &gt;= self._maxsize:
+            self.__delitem__(self._stack[0])
+            del self._stack[0]
+        self._stack.append(name)
+        return dict.__setitem__(self, name, value)
+   
+class DictCache(object):
     &quot;&quot;&quot;A wrapper around a dictionary to provide time-based expiration.
     This is intended to be used as a module cache on App Engine.&quot;&quot;&quot;
     def __init__(self, storage=local_cache):
@@ -80,10 +95,10 @@ class MintCache(object):
         http://www.djangosnippets.org/snippets/793/
         http://www.djangosnippets.org/snippets/155/
     &quot;&quot;&quot;
-    def __init__(self, storage=TimedDict(), delay=DEFAULT_DELAY):
+    def __init__(self, storage=DictCache(), delay=DEFAULT_DELAY):
         &quot;&quot;&quot;Create a wrapper
         Args:
-            storage: a cache backend. By default, it uses TimedDict 
+            storage: a cache backend. By default, it uses DictCache 
                 and compatible with Google App Engine memcache API.
     
             delay: the amount of delay (in seconds) after the timeout happens 
@@ -115,7 +130,7 @@ class MintCache(object):
         packed_val = (val, timeout, refreshed)
         return self.storage.set(key, packed_val, real_timeout)
 
-def memoize(key_func=None, storage=TimedDict(), age=0):
+def memoize(key_func=None, backend=DictCache(), age=0):
     &quot;&quot;&quot;Caches the result of a function in a cache backend.
     
     Args:
@@ -123,7 +138,7 @@ def memoize(key_func=None, storage=TimedDict(), age=0):
             If this is a string, this string is used as format for the key.
             If this is None, the key is built using combination of 
             module name, function name and all of the arguments.
-        storage: a cache backend. By default, it uses TimedDict but it 
+        backend: a cache backend. By default, it uses DictCache but it 
             is compatible with Google App Engine memcache API.
         age: number of seconds to keep values in cache
     
@@ -145,19 +160,19 @@ def memoize(key_func=None, storage=TimedDict(), age=0):
     
         from google.appengine.api import memcache
     
-        @memoize(key_func='account:name=%s', storage=memcache.Client(), age=30)
+        @memoize(key_func='account:name=%s', backend=memcache.Client(), age=30)
         def get_account_by_name(name):
             return Account.all().filter('name =', name).get()
             
     To avoid dogpile effect using module cache:
 
-        @memoize(key_func='account:name=%s', storage=MintCache())
+        @memoize(key_func='account:name=%s', backend=MintCache())
         def get_account_by_name(name):
             return Account.all().filter('name =', name).get()
     
     To avoid dogpile effect using memcache:
      
-        @memoize(key_func='account:name=%s', storage=MintCache(memcache.Client()))
+        @memoize(key_func='account:name=%s', backend=MintCache(memcache.Client()))
         def get_account_by_name(name):
             return Account.all().filter('name =', name).get()
         
@@ -181,7 +196,7 @@ def memoize(key_func=None, storage=TimedDict(), age=0):
         def __memoize(*args, **kwargs):                             
             try:
                 key = key_func(func, *args, **kwargs)
-                value = storage.get(key)
+                value = backend.get(key)
                 if value is None:
                     value = func(*args, **kwargs)
                     if value is not None:
@@ -189,7 +204,7 @@ def memoize(key_func=None, storage=TimedDict(), age=0):
                             timeout = 0
                         else:
                             timeout = time.time() + age                    
-                        storage.set(key, value, timeout)
+                        backend.set(key, value, timeout)
                 return value
             except TypeError, exc:
                 # uncachable -- for instance, passing a list as an argument.
@@ -198,8 +213,20 @@ def memoize(key_func=None, storage=TimedDict(), age=0):
         return __memoize
     return _memoize
 
-
+def run_tests():
+    def test_sized_dict():
+        h = SizedDict(1)
+        for c in ['a', 'b', 'c']:
+            h[c] = c
+            assert h[c] == c
+            
+        assert len(h) == 1
+        
+    test_sized_dict()
+        
 if __name__ == '__main__':
+    run_tests()
+    
     @memoize()
     def fib(n):
         if n in (0, 1):
@@ -223,4 +250,5 @@ if __name__ == '__main__':
     cProfile.run('print fibConstant(30)')
     print local_cache
     assert fib(10) == fibFormat(10)
-    assert fib(10) == fibConstant(10)
+    assert fib(10) == fibConstant(10) 
+    </diff>
      <filename>pquest/cache.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>6151053949bc7af13eeeadce5a8a223ab421f0ad</id>
    </parent>
  </parents>
  <author>
    <name>Cuong Tran</name>
    <email>ctran@pragmaquest.com</email>
  </author>
  <url>http://github.com/ctran/pquest-py/commit/a73ed89ff083633cd45272a608c7e908292a0503</url>
  <id>a73ed89ff083633cd45272a608c7e908292a0503</id>
  <committed-date>2009-05-07T12:53:15-07:00</committed-date>
  <authored-date>2009-05-07T12:53:15-07:00</authored-date>
  <message>added a fixed-size dict</message>
  <tree>42675f35b1d662f65e054128ea1c7c23c9b4434b</tree>
  <committer>
    <name>Cuong Tran</name>
    <email>ctran@pragmaquest.com</email>
  </committer>
</commit>
