Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/creactistore/_templates/lib/rdflib/plugins/sleepycat.py
diff options
context:
space:
mode:
Diffstat (limited to 'creactistore/_templates/lib/rdflib/plugins/sleepycat.py')
-rw-r--r--creactistore/_templates/lib/rdflib/plugins/sleepycat.py531
1 files changed, 0 insertions, 531 deletions
diff --git a/creactistore/_templates/lib/rdflib/plugins/sleepycat.py b/creactistore/_templates/lib/rdflib/plugins/sleepycat.py
deleted file mode 100644
index 67fcc17..0000000
--- a/creactistore/_templates/lib/rdflib/plugins/sleepycat.py
+++ /dev/null
@@ -1,531 +0,0 @@
-from rdflib.store import Store, VALID_STORE, CORRUPTED_STORE, NO_STORE, UNKNOWN
-from rdflib.term import URIRef
-from rdflib.py3compat import b
-def bb(u): return u.encode('utf-8')
-
-try:
- from bsddb import db
- has_bsddb = True
-except ImportError:
- try:
- from bsddb3 import db
- has_bsddb = True
- except ImportError:
- has_bsddb = False
-from os import mkdir
-from os.path import exists, abspath
-from urllib import pathname2url
-from threading import Thread
-
-import logging
-_logger = logging.getLogger(__name__)
-
-__all__ = ['Sleepycat']
-
-class Sleepycat(Store):
- context_aware = True
- formula_aware = True
- transaction_aware = False
- db_env = None
-
- def __init__(self, configuration=None, identifier=None):
- if not has_bsddb: raise Exception("Unable to import bsddb/bsddb3, store is unusable.")
- self.__open = False
- self.__identifier = identifier
- super(Sleepycat, self).__init__(configuration)
- self._loads = self.node_pickler.loads
- self._dumps = self.node_pickler.dumps
-
- def __get_identifier(self):
- return self.__identifier
- identifier = property(__get_identifier)
-
- def _init_db_environment(self, homeDir, create=True):
- envsetflags = db.DB_CDB_ALLDB
- envflags = db.DB_INIT_MPOOL | db.DB_INIT_CDB | db.DB_THREAD
- if not exists(homeDir):
- if create==True:
- mkdir(homeDir) # TODO: implement create method and refactor this to it
- self.create(homeDir)
- else:
- return NO_STORE
- db_env = db.DBEnv()
- db_env.set_cachesize(0, 1024*1024*50) # TODO
- #db_env.set_lg_max(1024*1024)
- db_env.set_flags(envsetflags, 1)
- db_env.open(homeDir, envflags | db.DB_CREATE)
- return db_env
-
- def is_open(self):
- return self.__open
-
- def open(self, path, create=True):
- if not has_bsddb: return NO_STORE
- homeDir = path
-
- if self.__identifier is None:
- self.__identifier = URIRef(pathname2url(abspath(homeDir)))
-
- db_env = self._init_db_environment(homeDir, create)
- if db_env == NO_STORE:
- return NO_STORE
- self.db_env = db_env
- self.__open = True
-
- dbname = None
- dbtype = db.DB_BTREE
- # auto-commit ensures that the open-call commits when transactions are enabled
- dbopenflags = db.DB_THREAD
- if self.transaction_aware == True:
- dbopenflags |= db.DB_AUTO_COMMIT
-
- dbmode = 0660
- dbsetflags = 0
-
- # create and open the DBs
- self.__indicies = [None,] * 3
- self.__indicies_info = [None,] * 3
- for i in xrange(0, 3):
- index_name = to_key_func(i)((b("s"), b("p"), b("o")), b("c")).decode()
- index = db.DB(db_env)
- index.set_flags(dbsetflags)
- index.open(index_name, dbname, dbtype, dbopenflags|db.DB_CREATE, dbmode)
- self.__indicies[i] = index
- self.__indicies_info[i] = (index, to_key_func(i), from_key_func(i))
-
- lookup = {}
- for i in xrange(0, 8):
- results = []
- for start in xrange(0, 3):
- score = 1
- len = 0
- for j in xrange(start, start+3):
- if i & (1<<(j%3)):
- score = score << 1
- len += 1
- else:
- break
- tie_break = 2-start
- results.append(((score, tie_break), start, len))
-
- results.sort()
- score, start, len = results[-1]
-
- def get_prefix_func(start, end):
- def get_prefix(triple, context):
- if context is None:
- yield ""
- else:
- yield context
- i = start
- while i<end:
- yield triple[i%3]
- i += 1
- yield ""
- return get_prefix
-
- lookup[i] = (self.__indicies[start], get_prefix_func(start, start + len), from_key_func(start), results_from_key_func(start, self._from_string))
-
-
- self.__lookup_dict = lookup
-
- self.__contexts = db.DB(db_env)
- self.__contexts.set_flags(dbsetflags)
- self.__contexts.open("contexts", dbname, dbtype, dbopenflags|db.DB_CREATE, dbmode)
-
- self.__namespace = db.DB(db_env)
- self.__namespace.set_flags(dbsetflags)
- self.__namespace.open("namespace", dbname, dbtype, dbopenflags|db.DB_CREATE, dbmode)
-
- self.__prefix = db.DB(db_env)
- self.__prefix.set_flags(dbsetflags)
- self.__prefix.open("prefix", dbname, dbtype, dbopenflags|db.DB_CREATE, dbmode)
-
- self.__k2i = db.DB(db_env)
- self.__k2i.set_flags(dbsetflags)
- self.__k2i.open("k2i", dbname, db.DB_HASH, dbopenflags|db.DB_CREATE, dbmode)
-
- self.__i2k = db.DB(db_env)
- self.__i2k.set_flags(dbsetflags)
- self.__i2k.open("i2k", dbname, db.DB_RECNO, dbopenflags|db.DB_CREATE, dbmode)
-
- self.__needs_sync = False
- t = Thread(target=self.__sync_run)
- t.setDaemon(True)
- t.start()
- self.__sync_thread = t
- return VALID_STORE
-
-
- def __sync_run(self):
- from time import sleep, time
- try:
- min_seconds, max_seconds = 10, 300
- while self.__open:
- if self.__needs_sync:
- t0 = t1 = time()
- self.__needs_sync = False
- while self.__open:
- sleep(.1)
- if self.__needs_sync:
- t1 = time()
- self.__needs_sync = False
- if time()-t1 > min_seconds or time()-t0 > max_seconds:
- self.__needs_sync = False
- _logger.debug("sync")
- self.sync()
- break
- else:
- sleep(1)
- except Exception, e:
- _logger.exception(e)
-
- def sync(self):
- if self.__open:
- for i in self.__indicies:
- i.sync()
- self.__contexts.sync()
- self.__namespace.sync()
- self.__prefix.sync()
- self.__i2k.sync()
- self.__k2i.sync()
-
- def close(self, commit_pending_transaction=False):
- self.__open = False
- self.__sync_thread.join()
- for i in self.__indicies:
- i.close()
- self.__contexts.close()
- self.__namespace.close()
- self.__prefix.close()
- self.__i2k.close()
- self.__k2i.close()
- self.db_env.close()
-
- def add(self, (subject, predicate, object), context, quoted=False, txn=None):
- """\
- Add a triple to the store of triples.
- """
- assert self.__open, "The Store must be open."
- assert context!=self, "Can not add triple directly to store"
- Store.add(self, (subject, predicate, object), context, quoted)
-
- _to_string = self._to_string
-
- s = _to_string(subject, txn=txn)
- p = _to_string(predicate, txn=txn)
- o = _to_string(object, txn=txn)
- c = _to_string(context, txn=txn)
-
- cspo, cpos, cosp = self.__indicies
-
- value = cspo.get(bb("%s^%s^%s^%s^" % (c, s, p, o)), txn=txn)
- if value is None:
- self.__contexts.put(bb(c), "", txn=txn)
-
- contexts_value = cspo.get(bb("%s^%s^%s^%s^" % ("", s, p, o)), txn=txn) or b("")
- contexts = set(contexts_value.split(b("^")))
- contexts.add(bb(c))
- contexts_value = b("^").join(contexts)
- assert contexts_value!=None
-
- cspo.put(bb("%s^%s^%s^%s^" % (c, s, p, o)), "", txn=txn)
- cpos.put(bb("%s^%s^%s^%s^" % (c, p, o, s)), "", txn=txn)
- cosp.put(bb("%s^%s^%s^%s^" % (c, o, s, p)), "", txn=txn)
- if not quoted:
- cspo.put(bb("%s^%s^%s^%s^" % ("", s, p, o)), contexts_value, txn=txn)
- cpos.put(bb("%s^%s^%s^%s^" % ("", p, o, s)), contexts_value, txn=txn)
- cosp.put(bb("%s^%s^%s^%s^" % ("", o, s, p)), contexts_value, txn=txn)
-
- self.__needs_sync = True
-
- def __remove(self, (s, p, o), c, quoted=False, txn=None):
- cspo, cpos, cosp = self.__indicies
- contexts_value = cspo.get(b("^").join([b(""), s, p, o, b("")]), txn=txn) or b("")
- contexts = set(contexts_value.split(b("^")))
- contexts.discard(c)
- contexts_value = b("^").join(contexts)
- for i, _to_key, _from_key in self.__indicies_info:
- i.delete(_to_key((s, p, o), c), txn=txn)
- if not quoted:
- if contexts_value:
- for i, _to_key, _from_key in self.__indicies_info:
- i.put(_to_key((s, p, o), b("")), contexts_value, txn=txn)
- else:
- for i, _to_key, _from_key in self.__indicies_info:
- try:
- i.delete(_to_key((s, p, o), b("")), txn=txn)
- except db.DBNotFoundError, e:
- pass # TODO: is it okay to ignore these?
-
- def remove(self, (subject, predicate, object), context, txn=None):
- assert self.__open, "The Store must be open."
- Store.remove(self, (subject, predicate, object), context)
- _to_string = self._to_string
-
- if context is not None:
- if context == self:
- context = None
-
- if subject is not None and predicate is not None and object is not None and context is not None:
- s = _to_string(subject, txn=txn)
- p = _to_string(predicate, txn=txn)
- o = _to_string(object, txn=txn)
- c = _to_string(context, txn=txn)
- value = self.__indicies[0].get(bb("%s^%s^%s^%s^" % (c, s, p, o)), txn=txn)
- if value is not None:
- self.__remove((bb(s), bb(p), bb(o)), bb(c), txn=txn)
- self.__needs_sync = True
- else:
- cspo, cpos, cosp = self.__indicies
- index, prefix, from_key, results_from_key = self.__lookup((subject, predicate, object), context, txn=txn)
-
- cursor = index.cursor(txn=txn)
- try:
- current = cursor.set_range(prefix)
- needs_sync = True
- except db.DBNotFoundError:
- current = None
- needs_sync = False
- cursor.close()
- while current:
- key, value = current
- cursor = index.cursor(txn=txn)
- try:
- cursor.set_range(key)
- # Hack to stop 2to3 converting this to next(cursor)
- current = getattr(cursor, 'next')()
- except db.DBNotFoundError:
- current = None
- cursor.close()
- if key.startswith(prefix):
- c, s, p, o = from_key(key)
- if context is None:
- contexts_value = index.get(key, txn=txn) or b("")
- contexts = set(contexts_value.split(b("^"))) # remove triple from all non quoted contexts
- contexts.add(b("")) # and from the conjunctive index
- for c in contexts:
- for i, _to_key, _ in self.__indicies_info:
- i.delete(_to_key((s, p, o), c), txn=txn)
- else:
- self.__remove((s, p, o), c, txn=txn)
- else:
- break
-
- if context is not None:
- if subject is None and predicate is None and object is None:
- # TODO: also if context becomes empty and not just on remove((None, None, None), c)
- try:
- self.__contexts.delete(bb(_to_string(context, txn=txn)), txn=txn)
- except db.DBNotFoundError, e:
- pass
-
- self.__needs_sync = needs_sync
-
- def triples(self, (subject, predicate, object), context=None, txn=None):
- """A generator over all the triples matching """
- assert self.__open, "The Store must be open."
-
- if context is not None:
- if context == self:
- context = None
-
- _from_string = self._from_string
- index, prefix, from_key, results_from_key = self.__lookup((subject, predicate, object), context, txn=txn)
-
- cursor = index.cursor(txn=txn)
- try:
- current = cursor.set_range(prefix)
- except db.DBNotFoundError:
- current = None
- cursor.close()
- while current:
- key, value = current
- cursor = index.cursor(txn=txn)
- try:
- cursor.set_range(key)
- # Cheap hack so 2to3 doesn't convert to next(cursor)
- current = getattr(cursor, 'next')()
- except db.DBNotFoundError:
- current = None
- cursor.close()
- if key and key.startswith(prefix):
- contexts_value = index.get(key, txn=txn)
- yield results_from_key(key, subject, predicate, object, contexts_value)
- else:
- break
-
- def __len__(self, context=None):
- assert self.__open, "The Store must be open."
- if context is not None:
- if context == self:
- context = None
-
- if context is None:
- prefix = b("^")
- else:
- prefix = bb("%s^" % self._to_string(context))
-
- index = self.__indicies[0]
- cursor = index.cursor()
- current = cursor.set_range(prefix)
- count = 0
- while current:
- key, value = current
- if key.startswith(prefix):
- count +=1
- # Hack to stop 2to3 converting this to next(cursor)
- current = getattr(cursor, 'next')()
- else:
- break
- cursor.close()
- return count
-
- def bind(self, prefix, namespace):
- prefix = prefix.encode("utf-8")
- namespace = namespace.encode("utf-8")
- bound_prefix = self.__prefix.get(namespace)
- if bound_prefix:
- self.__namespace.delete(bound_prefix)
- self.__prefix[namespace] = prefix
- self.__namespace[prefix] = namespace
-
- def namespace(self, prefix):
- prefix = prefix.encode("utf-8")
- ns = self.__namespace.get(prefix, None)
- if ns is not None:
- return ns.decode('utf-8')
- return None
-
- def prefix(self, namespace):
- namespace = namespace.encode("utf-8")
- prefix = self.__prefix.get(namespace, None)
- if prefix is not None:
- return prefix.decode('utf-8')
- return None
-
- def namespaces(self):
- cursor = self.__namespace.cursor()
- results = []
- current = cursor.first()
- while current:
- prefix, namespace = current
- results.append((prefix.decode('utf-8'), namespace.decode('utf-8')))
- # Hack to stop 2to3 converting this to next(cursor)
- current = getattr(cursor, 'next')()
- cursor.close()
- for prefix, namespace in results:
- yield prefix, URIRef(namespace)
-
- def contexts(self, triple=None):
- _from_string = self._from_string
- _to_string = self._to_string
-
- if triple:
- s, p, o = triple
- s = _to_string(s)
- p = _to_string(p)
- o = _to_string(o)
- contexts = self.__indicies[0].get(bb("%s^%s^%s^%s^" % ("", s, p, o)))
- if contexts:
- for c in contexts.split(b("^")):
- if c:
- yield _from_string(c)
- else:
- index = self.__contexts
- cursor = index.cursor()
- current = cursor.first()
- cursor.close()
- while current:
- key, value = current
- context = _from_string(key)
- yield context
- cursor = index.cursor()
- try:
- cursor.set_range(key)
- # Hack to stop 2to3 converting this to next(cursor)
- current = getattr(cursor, 'next')()
- except db.DBNotFoundError:
- current = None
- cursor.close()
-
- def _from_string(self, i):
- k = self.__i2k.get(int(i))
- return self._loads(k)
-
- def _to_string(self, term, txn=None):
- k = self._dumps(term)
- i = self.__k2i.get(k, txn=txn)
- if i is None:
- # weird behavoir from bsddb not taking a txn as a keyword argument
- # for append
- if self.transaction_aware:
- i = "%s" % self.__i2k.append(k, txn)
- else:
- i = "%s" % self.__i2k.append(k)
-
- self.__k2i.put(k, i, txn=txn)
- else:
- i = i.decode()
- return i
-
- def __lookup(self, (subject, predicate, object), context, txn=None):
- _to_string = self._to_string
- if context is not None:
- context = _to_string(context, txn=txn)
- i = 0
- if subject is not None:
- i += 1
- subject = _to_string(subject, txn=txn)
- if predicate is not None:
- i += 2
- predicate = _to_string(predicate, txn=txn)
- if object is not None:
- i += 4
- object = _to_string(object, txn=txn)
- index, prefix_func, from_key, results_from_key = self.__lookup_dict[i]
- #print (subject, predicate, object), context, prefix_func, index #DEBUG
- prefix = bb("^".join(prefix_func((subject, predicate, object), context)))
- return index, prefix, from_key, results_from_key
-
-
-def to_key_func(i):
- def to_key(triple, context):
- "Takes a string; returns key"
- return b("^").join((context, triple[i%3], triple[(i+1)%3], triple[(i+2)%3], b(""))) # "" to tac on the trailing ^
- return to_key
-
-def from_key_func(i):
- def from_key(key):
- "Takes a key; returns string"
- parts = key.split(b("^"))
- return parts[0], parts[(3-i+0)%3+1], parts[(3-i+1)%3+1], parts[(3-i+2)%3+1]
- return from_key
-
-def results_from_key_func(i, from_string):
- def from_key(key, subject, predicate, object, contexts_value):
- "Takes a key and subject, predicate, object; returns tuple for yield"
- parts = key.split(b("^"))
- if subject is None:
- # TODO: i & 1: # dis assemble and/or measure to see which is faster
- # subject is None or i & 1
- s = from_string(parts[(3-i+0)%3+1])
- else:
- s = subject
- if predicate is None:#i & 2:
- p = from_string(parts[(3-i+1)%3+1])
- else:
- p = predicate
- if object is None:#i & 4:
- o = from_string(parts[(3-i+2)%3+1])
- else:
- o = object
- return (s, p, o), (from_string(c) for c in contexts_value.split(b("^")) if c)
- return from_key
-
-def readable_index(i):
- s, p, o = "?" * 3
- if i & 1: s = "s"
- if i & 2: p = "p"
- if i & 4: o = "o"
- return "%s,%s,%s" % (s, p, o)