|
@@ -4,6 +4,7 @@ Custom Datastructures
|
|
|
|
|
|
"""
|
|
"""
|
|
import time
|
|
import time
|
|
|
|
+import heapq
|
|
import traceback
|
|
import traceback
|
|
from UserList import UserList
|
|
from UserList import UserList
|
|
from Queue import Queue, Empty as QueueEmpty
|
|
from Queue import Queue, Empty as QueueEmpty
|
|
@@ -223,3 +224,34 @@ class LimitedSet(object):
|
|
def first(self):
|
|
def first(self):
|
|
"""Get the oldest member."""
|
|
"""Get the oldest member."""
|
|
return self.chronologically[0]
|
|
return self.chronologically[0]
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class LocalCache(dict):
|
|
|
|
+ """Dictionary with a finite number of keys.
|
|
|
|
+
|
|
|
|
+ Older keys are expired first, but note that the timestamp
|
|
|
|
+ is not updated if a key is inserted twice, so it's not that great
|
|
|
|
+ for anything but unique keys.
|
|
|
|
+
|
|
|
|
+ """
|
|
|
|
+
|
|
|
|
+ def __init__(self, limit=None, initial=None):
|
|
|
|
+ super(LocalCache, self).__init__()
|
|
|
|
+ self.limit = limit
|
|
|
|
+ self.timestamps = []
|
|
|
|
+ initial = initial or {}
|
|
|
|
+ for key, value in initial.items():
|
|
|
|
+ self[key] = value
|
|
|
|
+
|
|
|
|
+ def __setitem__(self, key, value):
|
|
|
|
+ baseproxy = super(LocalCache, self)
|
|
|
|
+ item = time.time(), key
|
|
|
|
+ if len(self) >= self.limit:
|
|
|
|
+ timestamp, expired_key = heapq.heapreplace(self.timestamps, item)
|
|
|
|
+ baseproxy.pop(expired_key, None)
|
|
|
|
+ else:
|
|
|
|
+ heapq.heappush(self.timestamps, item)
|
|
|
|
+ baseproxy.__setitem__(key, value)
|
|
|
|
+
|
|
|
|
+ def __delitem__(self, key):
|
|
|
|
+ raise NotImplementedError("LocalCache doesn't support deletion.")
|