2to3 -f has_key
[sfa.git] / sfa / util / cache.py
index 45961fe..38eccc9 100644 (file)
@@ -4,10 +4,11 @@
 from __future__ import with_statement
 import time
 import threading
+import pickle
 from datetime import datetime
 
 # maximum lifetime of cached data (in seconds) 
-MAX_CACHE_TTL = 60 * 60
+DEFAULT_CACHE_TTL = 60 * 60
 
 class CacheData:
 
@@ -16,7 +17,7 @@ class CacheData:
     expires = None
     lock = None
 
-    def __init__(self, data, ttl = MAX_CACHE_TTL):
+    def __init__(self, data, ttl = DEFAULT_CACHE_TTL):
         self.lock = threading.RLock()
         self.data = data
         self.renew(ttl)
@@ -30,11 +31,11 @@ class CacheData:
     def get_expires_date(self):
         return str(datetime.fromtimestamp(self.expires))
 
-    def renew(self, ttl = MAX_CACHE_TTL):
+    def renew(self, ttl = DEFAULT_CACHE_TTL):
         self.created = time.time()
         self.expires = self.created + ttl   
        
-    def set_data(self, data, renew=True, ttl = MAX_CACHE_TTL):
+    def set_data(self, data, renew=True, ttl = DEFAULT_CACHE_TTL):
         with self.lock: 
             self.data = data
             if renew:
@@ -43,20 +44,73 @@ class CacheData:
     def get_data(self):
         return self.data
 
+
+    def dump(self):
+        return self.__dict__
+
+    def __str__(self):
+        return str(self.dump())  
+        
+    def tostring(self):
+        return self.__str__()
+
+    def __getstate__(self):
+        d = dict(self.__dict__)
+        del d['lock']
+        return d
+
+    def __setstate__(self, d):
+        self.__dict__.update(d)
+        self.lock = threading.RLock()
+        
+
 class Cache:
 
     cache  = {}
     lock = threading.RLock()
+
+    def __init__(self, filename=None):
+        if filename:
+            self.load_from_file(filename)
    
-    def add(self, key, value, ttl = MAX_CACHE_TTL):
+    def add(self, key, value, ttl = DEFAULT_CACHE_TTL):
         with self.lock:
-            if self.cache.has_key(key):
+            if key in self.cache:
                 self.cache[key].set_data(value, ttl=ttl)
             else:
                 self.cache[key] = CacheData(value, ttl)
            
     def get(self, key):
         data = self.cache.get(key)
-        if not data or data.is_expired():
-            return None 
-        return data.get_data()
+        if not data:  
+            data = None
+        elif data.is_expired():
+            self.pop(key)
+            data = None 
+        else:
+            data = data.get_data()
+        return data
+
+    def pop(self, key):
+        if key in self.cache:
+            self.cache.pop(key) 
+
+    def dump(self):
+        result = {}
+        for key in self.cache:
+            result[key] = self.cache[key].__getstate__()
+        return result
+
+    def __str__(self):
+        return str(self.dump())     
+    def tostring(self):
+        return self.__str()    
+
+    def save_to_file(self, filename):
+        f = open(filename, 'w')
+        pickle.dump(self.cache, f)
+
+    def load_from_file(self, filename):
+        f = open(filename, 'r')
+        self.cache = pickle.load(f)