def from_key(key, subject, predicate, object, contexts_value): "Takes a key and subject, predicate, object; returns tuple for yield" parts = b(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)
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)) return len([key for key in self.__indices[0] if key.startswith(prefix)])
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.__indices[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: for key in self.__contexts: yield _from_string(key)
def open(self, path, create=True): self.db_env = NoopMethods() self.create = create self.path = homeDir = path if not exists(homeDir): if create: mkdir(homeDir) else: raise ValueError("graph path %r does not exist" % homeDir) if self.identifier is None: self.__identifier = URIRef(pathname2url(abspath(homeDir))) def dbOpen(name): db = DB() dbpathname = abspath(self.path) + '/' + name + ".kch" if self.create: # if not db.open(abspath(self.path) + '/' + name + ".kch", # DB.OWRITER | DB.OCREATE | DB.OAUTOSYNC | DB.OAUTOTRAN): if not db.open(dbpathname, DB.OWRITER | DB.OCREATE): raise IOError("open error: %s %s" % (dbpathname, str(db.error()))) #pragma: NO COVER return db else: # if not db.open(abspath(self.path) + '/' + name + ".kch", # DB.OWRITER | DB.OAUTOSYNC | DB.OAUTOTRAN): if not db.open(dbpathname, DB.OWRITER): #pragma: NO COVER raise IOError("open error: %s %s" % (dbpathname, str(db.error()))) #pragma: NO COVER return db # create and open the DBs self.__indices = [None,] * 3 self.__indices_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 = dbOpen(index_name) self.__indices[i] = index self.__indices_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.__indices[start], get_prefix_func(start, start + len), from_key_func(start), results_from_key_func(start, self._from_string)) self.__lookup_dict = lookup # these 3 were btree mode in sleepycat, but currently i'm using tc hash self.__contexts = dbOpen("contexts") self.__namespace = dbOpen("namespace") self.__prefix = dbOpen("prefix") self.__k2i = dbOpen("k2i") self.__i2k = dbOpen("i2k") # was DB_RECNO mode self.__journal = NoopMethods() # was DB_RECNO mode self.__needs_sync = False # # Inherited from SleepyCat, not relevant to Kyoto Cabinet # t = Thread(target=self.__sync_run) # t.setDaemon(True) # t.start() # self.__sync_thread = t self.__sync_thread = NoopMethods() # self.synchronize() self.__open = True return VALID_STORE
def from_key(key): "Takes a key; returns string" parts = b(key).split(b("^")) return parts[0], parts[(3-i+0)%3+1], \ parts[(3-i+1)%3+1], parts[(3-i+2)%3+1]
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 ^
Store.add(self, (subject, predicate, object), context, quoted) _to_string = self._to_string s = _to_string(subject) p = _to_string(predicate) o = _to_string(object) c = _to_string(context) cspo, cpos, cosp = self.__indices value = cspo.get(bb("%s^%s^%s^%s^" % (c, s, p, o))) if value is None: self.__contexts.set(bb(c), "") contexts_value = cspo.get(bb("%s^%s^%s^%s^" % ("", s, p, o))) or b("") contexts = set(contexts_value.split(b("^"))) contexts.add(bb(c)) contexts_value = b("^").join(contexts) assert contexts_value!=None cspo.set(bb("%s^%s^%s^%s^" % (c, s, p, o)), "") cpos.set(bb("%s^%s^%s^%s^" % (c, p, o, s)), "") cosp.set(bb("%s^%s^%s^%s^" % (c, o, s, p)), "") if not quoted: cspo.set(bb("%s^%s^%s^%s^" % ("", s, p, o)), contexts_value) cpos.set(bb("%s^%s^%s^%s^" % ("", p, o, s)), contexts_value) cosp.set(bb("%s^%s^%s^%s^" % ("", o, s, p)), contexts_value) self.__needs_sync = True # self.__contexts.synchronize() # for dbindex in self.__indices: