parent
5818f6d492
commit
2554f770ee
@ -0,0 +1,75 @@ |
||||
from ConfigParser import ConfigParser |
||||
import cPickle as pickle |
||||
from threading import Lock |
||||
#TODO replace ConfigParser for better performance |
||||
|
||||
class PersistentContainer(object): |
||||
cfgparsers = dict() |
||||
locks = dict() |
||||
def __init__(self,namespace,path): |
||||
self.namespace = namespace |
||||
self.path = path |
||||
self.trans_cache = dict() |
||||
self.trans_del = [] |
||||
|
||||
if not path in PersistentContainer.locks: |
||||
PersistentContainer.locks[path] = Lock() |
||||
self.transaction = PersistentContainer.locks[path] |
||||
|
||||
if not path in PersistentContainer.cfgparsers: |
||||
PersistentContainer.cfgparsers[path] = ConfigParser() |
||||
PersistentContainer.cfgparsers[path].read([path]) |
||||
self.cp = PersistentContainer.cfgparsers[path] |
||||
|
||||
if not self.cp.has_section(namespace): |
||||
self.cp.add_section(namespace) |
||||
|
||||
def start_transaction(self,blocking=True): |
||||
return self.transaction.acquire(blocking) |
||||
|
||||
def commit_transaction(self): |
||||
self._write() |
||||
self.transaction.release() |
||||
|
||||
def rollback(self): |
||||
for k in self.trans_cache: |
||||
del self.trans_cache[k] |
||||
self.transaction.release() |
||||
|
||||
def is_owned(self): |
||||
return self.transaction.locked() |
||||
|
||||
def __getitem__(self, name): |
||||
if self.cp.has_option(self.namespace,name): |
||||
return pickle.loads(self.cp.get(self.namespace,name)) |
||||
return None |
||||
|
||||
def __setitem__(self, name,val): |
||||
self.trans_cache[name]=val |
||||
if not self.is_owned(): |
||||
self._write() |
||||
|
||||
def __delitem__(self, name): |
||||
if name not in self.trans_del: |
||||
self.trans_del.append(name) |
||||
if name in self.trans_cache: |
||||
del self.trans_cache[name] |
||||
if not self.is_owned(): |
||||
self._write() |
||||
|
||||
|
||||
def __contains__(self,name): |
||||
return self.cp.has_option(self.namespace,name) |
||||
|
||||
def _write(self): |
||||
for k in self.trans_cache: |
||||
val = self.trans_cache[k] |
||||
self.cp.set(self.namespace,k,pickle.dumps(val)) |
||||
while len(self.trans_del): |
||||
n = self.trans_del.pop() |
||||
self.cp.remove_option(self.namespace,n) |
||||
|
||||
f = open(self.path,'w') |
||||
self.cp.write(f) |
||||
f.close() |
||||
|
||||
Loading…
Reference in new issue