X-Git-Url: http://dolda2000.com/gitweb/?p=didex.git;a=blobdiff_plain;f=didex%2Fdb.py;h=068d404185d45f006b1a79821d573d9fcfade944;hp=316fa02f00804aa7bccdf79129b2f3354ffbb382;hb=947dfab3c174ecce6bd1ff18bdc4df7e0e4087c1;hpb=da5de0141d1328b254425b6a70d7a2c1f3c41c2b diff --git a/didex/db.py b/didex/db.py index 316fa02..068d404 100644 --- a/didex/db.py +++ b/didex/db.py @@ -2,6 +2,8 @@ import time, threading, struct from . import lib from bsddb3 import db as bd +__all__ = ["environment", "database"] + deadlock = bd.DBLockDeadlockError class environment(lib.closable): @@ -62,7 +64,8 @@ def opendb(env, fnm, dnm, typ, fl, mode): class txn(object): def __init__(self, env, flags=bd.DB_TXN_WRITE_NOSYNC): - self.tx = env.txn_begin(None, flags) + self.tx = env.env.txn_begin(None, flags) + self.env = env self.done = False self.pcommit = set() @@ -76,6 +79,7 @@ class txn(object): finally: run1(list[1:]) run1(list(self.pcommit)) + self.env.maint() def abort(self): self.done = True @@ -92,6 +96,15 @@ class txn(object): def postcommit(self, fun): self.pcommit.add(fun) +def dloopfun(fun): + def wrapper(self, *args, **kwargs): + while True: + try: + return fun(self, *args, **kwargs) + except deadlock: + continue + return wrapper + def txnfun(envfun): def fxf(fun): def wrapper(self, *args, tx=None, **kwargs): @@ -114,23 +127,20 @@ class database(object): self.env = env self.mode = mode self.fnm = name - fl = bd.DB_THREAD | bd.DB_AUTO_COMMIT + fl = bd.DB_THREAD if create: fl |= bd.DB_CREATE self.cf = self._opendb("cf", bd.DB_HASH, fl) self.ob = self._opendb("ob", bd.DB_HASH, fl) - def _opendb(self, dnm, typ, fl, init=None): + @txnfun(lambda self: self.env) + def _opendb(self, dnm, typ, fl, init=None, *, tx): ret = bd.DB(self.env.env) if init: init(ret) - while True: - try: - ret.open(self.fnm, dnm, typ, fl, self.mode) - except deadlock: - continue - return ret + ret.open(self.fnm, dnm, typ, fl, self.mode, txn=tx.tx) + return ret - @txnfun(lambda self: self.env.env) + @txnfun(lambda self: self.env) def _nextseq(self, *, tx): if self.cf.has_key(b"seq", txn=tx.tx): seq = struct.unpack(">Q", self.cf.get(b"seq", txn=tx.tx))[0] @@ -139,27 +149,27 @@ class database(object): self.cf.put(b"seq", struct.pack(">Q", seq + 1), txn=tx.tx) return seq - @txnfun(lambda self: self.env.env) + @txnfun(lambda self: self.env) def add(self, ob, *, tx): seq = self._nextseq(tx=tx) self.ob.put(struct.pack(">Q", seq), ob, txn=tx.tx, flags=bd.DB_NOOVERWRITE) return seq - @txnfun(lambda self: self.env.env) + @txnfun(lambda self: self.env) def replace(self, id, ob, *, tx): key = struct.pack(">Q", id) if not self.ob.has_key(key, txn=tx.tx): raise KeyError(id) self.ob.put(key, ob, txn=tx.tx) - @txnfun(lambda self: self.env.env) + @txnfun(lambda self: self.env) def get(self, id, *, tx): ret = self.ob.get(struct.pack(">Q", id), None) if ret is None: raise KeyError(id) return ret - @txnfun(lambda self: self.env.env) + @txnfun(lambda self: self.env) def remove(self, id, *, tx): key = struct.pack(">Q", id) if not self.ob.has_key(key, txn=tx.tx):