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