Browse Source

Type DB labels.

Stefano Cossu 5 years ago
parent
commit
ca5e49ed47

+ 11 - 8
lakesuperior/store/base_lmdb_store.pxd

@@ -1,5 +1,7 @@
 from lakesuperior.cy_include cimport cylmdb as lmdb
 
+ctypedef char DbLabel[8]
+
 cdef:
     int rc
     size_t i
@@ -29,28 +31,29 @@ cdef class BaseLmdbStore:
         void _txn_commit(self) except *
         void _txn_abort(self) except *
         inline bint _key_exists(
-            self, unsigned char *key, unsigned char klen,
-            unsigned char *dblabel=*) except -1
+            self, unsigned char *key, unsigned char klen, DbLabel dblabel=*
+        ) except -1
 
         size_t _txn_id(self) except -1
         lmdb.MDB_cursor *_cur_open(
-                self, unsigned char *dblabel=*, lmdb.MDB_txn *txn=*) except *
+            self, DbLabel dblabel=*, lmdb.MDB_txn *txn=*
+        ) except *
 
         lmdb.MDB_dbi get_dbi(
-                self, unsigned char *dblabel=*, lmdb.MDB_txn *txn=*)
+                self, DbLabel dblabel=*, lmdb.MDB_txn *txn=*)
 
         void _put(
                 self, unsigned char *key, size_t key_size, unsigned char *data,
-                size_t data_size, unsigned char *dblabel=*,
+                size_t data_size, DbLabel dblabel=*,
                 lmdb.MDB_txn *txn=*, unsigned int flags=*) except *
 
         void _get_data(
                 self, unsigned char *key, size_t klen, lmdb.MDB_val *rv,
-                unsigned char *dblabel=*) except *
+                DbLabel dblabel=*) except *
 
         void _delete(
                 self, unsigned char *key, size_t klen,
-                unsigned char *dblabel=*) except *
+                DbLabel dblabel=*) except *
 
         dict _stats(self)
         #int _reader_list_callback(self, const unsigned char *msg, void *str_)
@@ -59,7 +62,7 @@ cdef class BaseLmdbStore:
     cpdef void destroy(self, _path=*) except *
     #cpdef get_dup_data(self, unsigned char *key, db=*)
     #cpdef get_all_pairs(self, db=*)
-    cpdef bytes get_data(self, key, dblabel=*)
+    cpdef bytes get_data(self, key, DbLabel dblabel=*)
     cpdef dict stats(self)
     cpdef int txn_id(self)
     #cpdef str reader_list(self)

+ 22 - 21
lakesuperior/store/base_lmdb_store.pyx

@@ -276,7 +276,7 @@ cdef class BaseLmdbStore:
                 for i, dblabel in enumerate(self.dbi_labels):
                     flags = self.dbi_flags.get(dblabel, 0) | create_flag
                     _check(lmdb.mdb_dbi_open(
-                            txn, dblabel.encode(), flags, self.dbis + i))
+                            txn, dblabel, flags, self.dbis + i))
                     dbi = self.dbis[i]
                     logger.debug(f'Created DB {dblabel}: {dbi}')
                     # Open and close cursor to initialize the memory slot.
@@ -450,15 +450,14 @@ cdef class BaseLmdbStore:
         """
         if new_txn is True:
             with self.txn_ctx():
-                return self._key_exists(
-                        key, len(key), dblabel=dblabel.encode())
+                return self._key_exists(key, len(key), dblabel=dblabel)
         else:
-            return self._key_exists(key, len(key), dblabel=dblabel.encode())
+            return self._key_exists(key, len(key), dblabel=dblabel)
 
 
     cdef inline bint _key_exists(
             self, unsigned char *key, unsigned char klen,
-            unsigned char *dblabel=b'') except -1:
+            DbLabel dblabel=b'') except -1:
         """
         Return whether a key exists in a database.
 
@@ -485,13 +484,14 @@ cdef class BaseLmdbStore:
         Put one key/value pair (Python-facing method).
         """
         self._put(
-                key, len(key), data, len(data), dblabel=dblabel.encode(),
-                txn=self.txn, flags=flags)
+            key, len(key), data, len(data), dblabel=dblabel,
+            txn=self.txn, flags=flags
+        )
 
 
     cdef void _put(
             self, unsigned char *key, size_t key_size, unsigned char *data,
-            size_t data_size, unsigned char *dblabel='',
+            size_t data_size, DbLabel dblabel='',
             lmdb.MDB_txn *txn=NULL, unsigned int flags=0) except *:
         """
         Put one key/value pair.
@@ -511,13 +511,13 @@ cdef class BaseLmdbStore:
                 key[: key_size], data[: data_size]))
 
 
-    cpdef bytes get_data(self, key, dblabel=''):
+    cpdef bytes get_data(self, key, DbLabel dblabel=''):
         """
         Get a single value (non-dup) for a key (Python-facing method).
         """
         cdef lmdb.MDB_val rv
         try:
-            self._get_data(key, len(key), &rv, dblabel=dblabel.encode())
+            self._get_data(key, len(key), &rv, dblabel=dblabel)
 
             return (<unsigned char *>rv.mv_data)[: rv.mv_size]
         except KeyNotFoundError:
@@ -526,7 +526,7 @@ cdef class BaseLmdbStore:
 
     cdef void _get_data(
             self, unsigned char *key, size_t klen, lmdb.MDB_val *rv,
-            unsigned char *dblabel='') except *:
+            DbLabel dblabel='') except *:
         """
         Get a single value (non-dup) for a key.
         """
@@ -545,12 +545,12 @@ cdef class BaseLmdbStore:
         """
         Delete one single value by key. Python-facing method.
         """
-        self._delete(key, len(key), dblabel.encode())
+        self._delete(key, len(key), dblabel)
 
 
     cdef void _delete(
             self, unsigned char *key, size_t klen,
-            unsigned char *dblabel=b'') except *:
+            DbLabel dblabel=b'') except *:
         """
         Delete one single value by key from a non-dup database.
 
@@ -588,13 +588,13 @@ cdef class BaseLmdbStore:
                 lmdb.mdb_stat(self.txn, self.dbis[i], &stat),
                 'Error getting datbase stats: {}')
             entries = stat.ms_entries
-            db_stats[dblabel.encode()] = <dict>stat
+            db_stats[dblabel] = <dict>stat
 
         return {
             'env_stats': env_stats,
             'env_size': os.stat(self.env_path).st_size,
             'db_stats': {
-                db_label: db_stats[db_label.encode()]
+                db_label: db_stats[db_label]
                 for db_label in self.dbi_labels
             },
         }
@@ -700,7 +700,7 @@ cdef class BaseLmdbStore:
 
 
     cdef lmdb.MDB_dbi get_dbi(
-            self, unsigned char *dblabel=NULL, lmdb.MDB_txn *txn=NULL):
+            self, DbLabel dblabel=NULL, lmdb.MDB_txn *txn=NULL):
         """
         Return a DB handle by database name.
         """
@@ -712,8 +712,9 @@ cdef class BaseLmdbStore:
         if dblabel is NULL:
             logger.debug('Getting DBI without label.')
         dbidx = (
-                0 if dblabel is NULL
-                else self.dbi_labels.index(dblabel.decode()))
+            0 if dblabel is NULL
+            else self.dbi_labels.index(dblabel)
+        )
         #logger.debug(
         #        f'Got DBI {self.dbis[dbidx]} with label {dblabel} '
         #        f'and index #{dbidx}')
@@ -722,7 +723,7 @@ cdef class BaseLmdbStore:
 
 
     cdef lmdb.MDB_cursor *_cur_open(
-            self, unsigned char *dblabel=NULL, lmdb.MDB_txn *txn=NULL) except *:
+            self, DbLabel dblabel=NULL, lmdb.MDB_txn *txn=NULL) except *:
         cdef:
             lmdb.MDB_dbi dbi
 
@@ -731,7 +732,7 @@ cdef class BaseLmdbStore:
 
         dbi = self.get_dbi(dblabel, txn=txn)
 
-        logger.debug(f'Opening cursor for DB {dblabel} (DBI {dbi})...')
+        #logger.debug(f'Opening cursor for DB {dblabel} (DBI {dbi})...')
         #try:
         #    # FIXME Either reuse the cursor, if it works, or remove this code.
         #    _check(lmdb.mdb_cursor_renew(txn, self.curs[dbi]))
@@ -744,7 +745,7 @@ cdef class BaseLmdbStore:
         _check(
                 lmdb.mdb_cursor_open(txn, dbi, self.curs + dbi),
                 f'Error opening cursor: {dblabel}')
-        logger.debug('...opened @ {:x}.'.format(<unsigned long>self.curs[dbi]))
+        #logger.debug('...opened @ {:x}.'.format(<unsigned long>self.curs[dbi]))
 
         return self.curs[dbi]
 

+ 8 - 6
lakesuperior/store/ldp_rs/lmdb_store.py

@@ -143,13 +143,15 @@ class LmdbStore(LmdbTriplestore, Store):
         prefix = prefix.encode()
         namespace = namespace.encode()
         if self.is_txn_rw:
-            self.put(prefix, namespace, 'pfx:ns')
-            self.put(namespace, prefix, 'ns:pfx')
+            # FIXME DB labels should be constants but there are problems
+            # imprting them from the Cython module.
+            self.put(prefix, namespace, b'pfx:ns_')
+            self.put(namespace, prefix, b'ns:pfx_')
         else:
             #logger.debug('Opening RW transaction.')
             with self.txn_ctx(write=True) as wtxn:
-                self.put(prefix, namespace, 'pfx:ns')
-                self.put(namespace, prefix, 'ns:pfx')
+                self.put(prefix, namespace, b'pfx:ns_')
+                self.put(namespace, prefix, b'ns:pfx_')
 
 
     def namespace(self, prefix):
@@ -157,7 +159,7 @@ class LmdbStore(LmdbTriplestore, Store):
         Get the namespace for a prefix.
         :param str prefix: Namespace prefix.
         """
-        ns = self.get_data(prefix.encode(), 'pfx:ns')
+        ns = self.get_data(prefix.encode(), b'pfx:ns_')
 
         return Namespace(ns.decode()) if ns is not None else None
 
@@ -173,7 +175,7 @@ class LmdbStore(LmdbTriplestore, Store):
 
         :rtype: str or None
         """
-        prefix = self.get_data(str(namespace).encode(), 'ns:pfx')
+        prefix = self.get_data(str(namespace).encode(), b'ns:pfx_')
 
         return prefix.decode() if prefix is not None else None
 

+ 4 - 2
lakesuperior/store/ldp_rs/lmdb_triplestore.pxd

@@ -4,7 +4,7 @@ cimport lakesuperior.cy_include.cylmdb as lmdb
 from lakesuperior.model.base cimport Key, DoubleKey, TripleKey, Buffer
 from lakesuperior.model.rdf.graph cimport Graph
 from lakesuperior.model.structures.keyset cimport Keyset
-from lakesuperior.store.base_lmdb_store cimport BaseLmdbStore
+from lakesuperior.store.base_lmdb_store cimport DbLabel, BaseLmdbStore
 
 cdef:
     enum:
@@ -14,10 +14,12 @@ cdef:
     unsigned char lookup_rank[3]
     unsigned char lookup_ordering[3][3]
     unsigned char lookup_ordering_2bound[3][3]
+    char lookup_indices[6][8] # Can't use DbLabel[6] here...
 
 
 
 cdef class LmdbTriplestore(BaseLmdbStore):
+
     cpdef dict stats(self)
     cpdef size_t _len(self, context=*) except -1
     cpdef void add(self, triple, context=*, quoted=*) except *
@@ -41,5 +43,5 @@ cdef class LmdbTriplestore(BaseLmdbStore):
         void all_contexts(self, Key** ctx, size_t* sz, triple=*) except *
         Key _append(
                 self, Buffer *value,
-                unsigned char *dblabel=*, lmdb.MDB_txn *txn=*,
+                DbLabel dblabel=*, lmdb.MDB_txn *txn=*,
                 unsigned int flags=*) except? 0

+ 92 - 78
lakesuperior/store/ldp_rs/lmdb_triplestore.pyx

@@ -48,6 +48,32 @@ INT_DUP_MASK = (
     | LSUP_REVERSEKEY | LSUP_REVERSEDUP
 )
 
+cdef:
+    DbLabel DB_T_ST = 't:st___',
+    # Joined triple keys to context key
+    DbLabel DB_SPO_C = 'spo:c__',
+    # This has empty values and is used to keep track of empty contexts.
+    DbLabel DB_C_ = 'c:_____',
+    # Prefix to namespace
+    DbLabel DB_PFX_NS = 'pfx:ns_',
+
+    # Indices
+    # Namespace to prefix
+    DbLabel DB_NS_PFX = 'ns:pfx_',
+    # Term hash to triple key
+    DbLabel DB_TH_T = 'th:t___',
+    # 1-bound lookups
+    DbLabel DB_S_PO = 's:po___',
+    DbLabel DB_P_SO = 'p:so___',
+    DbLabel DB_O_SP = 'o:sp___',
+    # 2-bound lookups
+    DbLabel DB_PO_S = 'po:s___',
+    DbLabel DB_SO_P = 'so:p___',
+    DbLabel DB_SP_O = 'sp:o___',
+    # Context lookup
+    DbLabel DB_C_SPO = 'c:spo__',
+
+
 lookup_rank = [0, 2, 1]
 """
 Order in which keys are looked up if two terms are bound.
@@ -57,10 +83,8 @@ looked up first.
 0 = s:po
 1 = p:so
 2 = o:sp
-
-If we want to get fancy, this can be rebalanced from time to time by
-looking up the number of keys in (s:po, p:so, o:sp).
 """
+
 lookup_ordering = [
     [0, 1, 2], # spo
     [1, 0, 2], # pso
@@ -72,6 +96,15 @@ lookup_ordering_2bound = [
     [0, 1, 2], # sp:o
 ]
 
+lookup_indices = [
+    DB_S_PO,
+    DB_P_SO,
+    DB_O_SP,
+    DB_PO_S,
+    DB_SO_P,
+    DB_SP_O,
+]
+
 
 logger = logging.getLogger(__name__)
 
@@ -89,51 +122,32 @@ cdef class LmdbTriplestore(BaseLmdbStore):
     """
 
     dbi_labels = [
-        # Main data
-        # Term key to serialized term content
-        't:st',
-        # Joined triple keys to context key
-        'spo:c',
-        # This has empty values and is used to keep track of empty contexts.
-        'c:',
-        # Prefix to namespace
-        'pfx:ns',
-
-        # Indices
-        # Namespace to prefix
-        'ns:pfx',
-        # Term hash to triple key
-        'th:t',
-        # Lookups
-        's:po',
-        'p:so',
-        'o:sp',
-        'po:s',
-        'so:p',
-        'sp:o',
-        'c:spo',
-    ]
-
-    lookup_indices = [
-        b's:po',
-        b'p:so',
-        b'o:sp',
-        b'po:s',
-        b'so:p',
-        b'sp:o',
+        DB_T_ST,
+        DB_SPO_C,
+        DB_C_,
+        DB_PFX_NS,
+        DB_NS_PFX,
+        DB_TH_T,
+        DB_S_PO,
+        DB_P_SO,
+        DB_O_SP,
+        DB_PO_S,
+        DB_SO_P,
+        DB_SP_O,
+        DB_C_SPO,
     ]
 
     dbi_flags = {
-        'c': INT_KEY_MASK,
-        't:st': INT_KEY_MASK,
-        's:po': INT_DUP_KEY_MASK,
-        'p:so': INT_DUP_KEY_MASK,
-        'o:sp': INT_DUP_KEY_MASK,
-        'po:s': INT_DUP_MASK,
-        'so:p': INT_DUP_MASK,
-        'sp:o': INT_DUP_MASK,
-        'c:spo': INT_DUP_KEY_MASK,
-        'spo:c': INT_DUP_MASK,
+        DB_C_: INT_KEY_MASK,
+        DB_T_ST: INT_KEY_MASK,
+        DB_S_PO: INT_DUP_KEY_MASK,
+        DB_P_SO: INT_DUP_KEY_MASK,
+        DB_O_SP: INT_DUP_KEY_MASK,
+        DB_PO_S: INT_DUP_MASK,
+        DB_SO_P: INT_DUP_MASK,
+        DB_SP_O: INT_DUP_MASK,
+        DB_C_SPO: INT_DUP_KEY_MASK,
+        DB_SPO_C: INT_DUP_MASK,
     }
     logger.debug(f'DBI flags: {dbi_flags}')
 
@@ -150,7 +164,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
         """
         Gather statistics about the database."""
         st = self._stats()
-        st['num_triples'] = st['db_stats']['spo:c']['ms_entries']
+        st['num_triples'] = st['db_stats'][DB_SPO_C]['ms_entries']
         st['store_size'] = get_tree_size(self.env_path)
 
         return st
@@ -173,7 +187,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
             key_v.mv_data = &ck
             key_v.mv_size = KLEN
 
-            cur = self._cur_open('c:spo')
+            cur = self._cur_open(DB_C_SPO)
             try:
                 _check(lmdb.mdb_cursor_get(
                         cur, &key_v, NULL, lmdb.MDB_SET))
@@ -216,7 +230,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
             c = RDFLIB_DEFAULT_GRAPH_URI
 
         s, p, o = triple
-        icur = self._cur_open('th:t')
+        icur = self._cur_open(DB_TH_T)
         try:
             for i, term_obj in enumerate((s, p, o, c)):
                 serialize_from_rdflib(term_obj, &pk_t)
@@ -225,13 +239,13 @@ cdef class LmdbTriplestore(BaseLmdbStore):
                     key_v.mv_data = thash
                     key_v.mv_size = HLEN
                     _check(lmdb.mdb_get(
-                            self.txn, self.get_dbi('th:t'), &key_v, &data_v))
+                            self.txn, self.get_dbi(DB_TH_T), &key_v, &data_v))
                     spock[i] = (<Key*>data_v.mv_data)[0]
                 except KeyNotFoundError:
                     # If term_obj is not found, add it...
                     logger.debug('Hash {} not found. Adding to DB.'.format(
                             thash[: HLEN]))
-                    spock[i] = self._append(&pk_t, dblabel=b't:st')
+                    spock[i] = self._append(&pk_t, dblabel=DB_T_ST)
 
                     # ...and index it.
                     key_v.mv_data = thash
@@ -253,21 +267,21 @@ cdef class LmdbTriplestore(BaseLmdbStore):
 
         try:
             _check(lmdb.mdb_put(
-                self.txn, self.get_dbi('c:'), &c_v, &null_v,
+                self.txn, self.get_dbi(DB_C_), &c_v, &null_v,
                 lmdb.MDB_NOOVERWRITE))
         except KeyExistsError:
             pass
         try:
             # Add triple:context association.
             _check(lmdb.mdb_put(
-                self.txn, self.get_dbi('spo:c'), &spo_v, &c_v,
+                self.txn, self.get_dbi(DB_SPO_C), &spo_v, &c_v,
                 lmdb.MDB_NODUPDATA))
         except KeyExistsError:
             pass
         try:
             # Index context:triple association.
             _check(lmdb.mdb_put(
-                self.txn, self.get_dbi('c:spo'), &c_v, &spo_v,
+                self.txn, self.get_dbi(DB_C_SPO), &c_v, &spo_v,
                 lmdb.MDB_NODUPDATA))
         except KeyExistsError:
             pass
@@ -293,7 +307,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
         c = self._normalize_context(c)
 
         ck = self.to_key(c)
-        if not self._key_exists(<unsigned char*>&ck, KLEN, b'c:'):
+        if not self._key_exists(<unsigned char*>&ck, KLEN, DB_C_):
             # Insert context term if not existing.
             if self.is_txn_rw:
                 #logger.debug('Working in existing RW transaction.')
@@ -310,7 +324,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
                 data_v.mv_data = &ck # Whatever, length is zero anyways
                 data_v.mv_size = 0
                 _check(lmdb.mdb_put(
-                    _txn, self.get_dbi(b'c:'), &key_v, &data_v, 0
+                    _txn, self.get_dbi(DB_C_), &key_v, &data_v, 0
                 ))
                 if not self.is_txn_rw:
                     _check(lmdb.mdb_txn_commit(_txn))
@@ -340,8 +354,8 @@ cdef class LmdbTriplestore(BaseLmdbStore):
         # Get the matching pattern.
         match_set = self.triple_keys(triple_pattern, context)
 
-        dcur = self._cur_open('spo:c')
-        icur = self._cur_open('c:spo')
+        dcur = self._cur_open(DB_SPO_C)
+        icur = self._cur_open(DB_C_SPO)
 
         try:
             spok_v.mv_size = TRP_KLEN
@@ -468,8 +482,8 @@ cdef class LmdbTriplestore(BaseLmdbStore):
             logger.debug(f'Add {spok[0]} to indices.')
 
         while i < 3:
-            cur1 = self._cur_open(self.lookup_indices[i]) # s:po, p:so, o:sp
-            cur2 = self._cur_open(self.lookup_indices[i + 3])# po:s, so:p, sp:o
+            cur1 = self._cur_open(lookup_indices[i]) # s:po, p:so, o:sp
+            cur2 = self._cur_open(lookup_indices[i + 3])# po:s, so:p, sp:o
             try:
                 key_v.mv_data = spok + i
                 dbl_key_v.mv_data = dbl_keys[i]
@@ -548,11 +562,11 @@ cdef class LmdbTriplestore(BaseLmdbStore):
         chash_v.mv_size = HLEN
         try:
             ck_v.mv_data = &ck
-            _check(lmdb.mdb_del(self.txn, self.get_dbi(b'c:'), &ck_v, NULL))
+            _check(lmdb.mdb_del(self.txn, self.get_dbi(DB_C_), &ck_v, NULL))
             ck_v.mv_data = &ck
-            _check(lmdb.mdb_del(self.txn, self.get_dbi(b't:st'), &ck_v, NULL))
+            _check(lmdb.mdb_del(self.txn, self.get_dbi(DB_T_ST), &ck_v, NULL))
             chash_v.mv_data = chash
-            _check(lmdb.mdb_del(self.txn, self.get_dbi(b'th:t'), &chash_v, NULL))
+            _check(lmdb.mdb_del(self.txn, self.get_dbi(DB_TH_T), &chash_v, NULL))
         except KeyNotFoundError:
             pass
 
@@ -613,7 +627,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
 
         #logger.debug('Triple keys found: {}'.format(rset.data[:rset.size]))
 
-        cur = self._cur_open('spo:c')
+        cur = self._cur_open(DB_SPO_C)
         try:
             key_v.mv_size = TRP_KLEN
             rset.keys.seek()
@@ -675,7 +689,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
                 # Context not found.
                 return Graph(self, uri=uri)
 
-            icur = self._cur_open('c:spo')
+            icur = self._cur_open(DB_C_SPO)
 
             try:
                 key_v.mv_data = &ck
@@ -808,7 +822,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
                     try:
                         spok = [tk1, tk2, tk3]
                         _check(lmdb.mdb_get(
-                            self.txn, self.get_dbi('spo:c'), &spok_v, &ck_v))
+                            self.txn, self.get_dbi(DB_SPO_C), &spok_v, &ck_v))
                     except KeyNotFoundError:
                         return Graph(self)
 
@@ -841,7 +855,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
 
         # ? ? ?
         # Get all triples in the database.
-        dcur = self._cur_open('spo:c')
+        dcur = self._cur_open(DB_SPO_C)
 
         try:
             _check(
@@ -894,8 +908,8 @@ cdef class LmdbTriplestore(BaseLmdbStore):
         logger.debug(f'lookup 1bound: {idx}, {luk}')
 
         term_order = lookup_ordering[idx]
-        icur = self._cur_open(self.lookup_indices[idx])
-        logging.debug(f'DB label: {self.lookup_indices[idx]}')
+        icur = self._cur_open(lookup_indices[idx])
+        logging.debug(f'DB label: {lookup_indices[idx]}')
         logging.debug('term order: {}'.format(term_order[: 3]))
 
         try:
@@ -965,7 +979,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
                 else:
                     luk1_offset = 1
                     luk2_offset = 0
-                dblabel = self.lookup_indices[i + 3] # skip 1bound index labels
+                dblabel = lookup_indices[i + 3] # skip 1bound index labels
                 break
 
             if i == 2:
@@ -1019,7 +1033,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
             lmdb.MDB_stat stat
             cc.HashSetConf tkeys_conf
 
-        idx_label = self.lookup_indices['spo'.index(term_type)]
+        idx_label = lookup_indices['spo'.index(term_type)]
         icur = self._cur_open(idx_label)
         try:
             _check(lmdb.mdb_stat(self.txn, lmdb.mdb_cursor_dbi(icur), &stat))
@@ -1085,7 +1099,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
             lmdb.MDB_stat stat
 
         ret = []
-        dcur = self._cur_open('pfx:ns')
+        dcur = self._cur_open(DB_PFX_NS)
         try:
             try:
                 _check(lmdb.mdb_cursor_get(
@@ -1121,8 +1135,8 @@ cdef class LmdbTriplestore(BaseLmdbStore):
             TripleKey spok
 
         cur = (
-                self._cur_open('spo:c') if triple and all(triple)
-                else self._cur_open('c:'))
+                self._cur_open(DB_SPO_C) if triple and all(triple)
+                else self._cur_open(DB_C_))
         try:
             if triple and all(triple):
                 _check(lmdb.mdb_stat(
@@ -1198,7 +1212,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
 
         _check(
             lmdb.mdb_get(
-                self.txn, self.get_dbi('t:st'), &key_v, &data_v
+                self.txn, self.get_dbi(DB_T_ST), &key_v, &data_v
             ),
             f'Error getting data for key \'{tk}\'.'
         )
@@ -1249,7 +1263,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
             #    f'{(<unsigned char*>thash)[:HLEN]} in store before adding.'
             #)
             _check(lmdb.mdb_get(
-                self.txn, self.get_dbi(b'th:t'), &key_v, &data_v)
+                self.txn, self.get_dbi(DB_TH_T), &key_v, &data_v)
             )
 
             return (<Key*>data_v.mv_data)[0]
@@ -1268,13 +1282,13 @@ cdef class LmdbTriplestore(BaseLmdbStore):
 
             try:
                 # Main entry.
-                tk = self._append(&pk_t, b't:st', txn=_txn)
+                tk = self._append(&pk_t, DB_T_ST, txn=_txn)
 
                 # Index.
                 data_v.mv_data = &tk
                 data_v.mv_size = KLEN
                 _check(lmdb.mdb_put(
-                    _txn, self.get_dbi(b'th:t'), &key_v, &data_v, 0
+                    _txn, self.get_dbi(DB_TH_T), &key_v, &data_v, 0
                 ))
                 if not self.is_txn_rw:
                     _check(lmdb.mdb_txn_commit(_txn))
@@ -1291,7 +1305,7 @@ cdef class LmdbTriplestore(BaseLmdbStore):
 
     cdef Key _append(
         self, Buffer *value,
-        unsigned char *dblabel=b'', lmdb.MDB_txn *txn=NULL,
+        DbLabel dblabel=b'', lmdb.MDB_txn *txn=NULL,
         unsigned int flags=0
         ) except? 0:
         """

+ 15 - 15
tests/1_store/test_1_0_lmdb_store.py

@@ -374,14 +374,14 @@ class TestEntryCount:
         List of index labels.
         """
         return [
-            's:po',
-            'p:so',
-            'o:sp',
-            'po:s',
-            'so:p',
-            'sp:o',
-            'spo:c',
-            'c:spo',
+            b's:po___',
+            b'p:so___',
+            b'o:sp___',
+            b'po:s___',
+            b'so:p___',
+            b'sp:o___',
+            b'spo:c__',
+            b'c:spo__',
         ]
 
 
@@ -408,8 +408,8 @@ class TestEntryCount:
             assert stat['db_stats'][idxlabel]['ms_entries'] == 1000
 
         # 1 subject, 100 predicates, 1000 objects, 1 context
-        assert stat['db_stats']['t:st']['ms_entries'] == 1102
-        assert stat['db_stats']['th:t']['ms_entries'] == 1102
+        assert stat['db_stats'][b't:st___']['ms_entries'] == 1102
+        assert stat['db_stats'][b'th:t___']['ms_entries'] == 1102
 
 
     def test_entries_partial(self, store, indices):
@@ -422,8 +422,8 @@ class TestEntryCount:
         with store.txn_ctx():
             stat = store.stats()
 
-        assert stat['db_stats']['t:st']['ms_entries'] == 1102
-        assert stat['db_stats']['th:t']['ms_entries'] == 1102
+        assert stat['db_stats'][b't:st___']['ms_entries'] == 1102
+        assert stat['db_stats'][b'th:t___']['ms_entries'] == 1102
 
 
     def test_entries_empty(self, store, indices):
@@ -439,8 +439,8 @@ class TestEntryCount:
         for idxlabel in indices:
             assert stat['db_stats'][idxlabel]['ms_entries'] == 0
 
-        assert stat['db_stats']['t:st']['ms_entries'] == 1102
-        assert stat['db_stats']['th:t']['ms_entries'] == 1102
+        assert stat['db_stats'][b't:st___']['ms_entries'] == 1102
+        assert stat['db_stats'][b'th:t___']['ms_entries'] == 1102
 
 
 
@@ -619,7 +619,7 @@ class TestCleanup:
 
     def _is_empty(self, store):
         stats = store.stats()['db_stats']
-        for dblabel in ('spo:c', 'c:spo', 's:po', 'p:so', 'o:sp',):
+        for dblabel in (b'spo:c__', b'c:spo__', b's:po___', b'p:so___', b'o:sp___',):
             if stats[dblabel]['ms_entries'] > 0:
                 return False