serialize cache using pickle
[sfa.git] / sfa / util / cache.py
1 #
2 # This module implements general purpose caching system
3 #
4 from __future__ import with_statement
5 import time
6 import threading
7 import pickle
8 from datetime import datetime
9
10 # maximum lifetime of cached data (in seconds) 
11 MAX_CACHE_TTL = 60 * 60
12
13 class CacheData:
14
15     data = None
16     created = None
17     expires = None
18     lock = None
19
20     def __init__(self, data, ttl = MAX_CACHE_TTL):
21         self.lock = threading.RLock()
22         self.data = data
23         self.renew(ttl)
24
25     def is_expired(self):
26         return time.time() > self.expires
27
28     def get_created_date(self):
29         return str(datetime.fromtimestamp(self.created))
30
31     def get_expires_date(self):
32         return str(datetime.fromtimestamp(self.expires))
33
34     def renew(self, ttl = MAX_CACHE_TTL):
35         self.created = time.time()
36         self.expires = self.created + ttl   
37        
38     def set_data(self, data, renew=True, ttl = MAX_CACHE_TTL):
39         with self.lock: 
40             self.data = data
41             if renew:
42                 self.renew(ttl)
43     
44     def get_data(self):
45         return self.data
46
47     def __getstate__(self):
48         d = dict(self.__dict__)
49         del d['lock']
50         return d
51
52     def __setstate__(self, d):
53         self.__dict__.update(d)
54         self.lock = threading.RLock()
55         
56
57 class Cache:
58
59     cache  = {}
60     lock = threading.RLock()
61    
62     def add(self, key, value, ttl = MAX_CACHE_TTL):
63         with self.lock:
64             if self.cache.has_key(key):
65                 self.cache[key].set_data(value, ttl=ttl)
66             else:
67                 self.cache[key] = CacheData(value, ttl)
68            
69     def get(self, key):
70         data = self.cache.get(key)
71         if not data or data.is_expired():
72             return None 
73         return data.get_data()
74
75     def save_to_file(self, filename):
76         f = open(filename, 'w')
77         pickle.dump(self.cache, f)
78
79     def load_from_file(self, filename):
80         f = open(filename, 'r')
81         self.cache = pickle.load(f)