|
@@ -1,5 +1,7 @@
|
|
|
#include <ftw.h>
|
|
|
|
|
|
+#include "uthash.h"
|
|
|
+
|
|
|
#include "store_mdb.h"
|
|
|
|
|
|
/**
|
|
@@ -23,8 +25,11 @@
|
|
|
#define ENV_FILE_MODE 0640
|
|
|
|
|
|
|
|
|
-typedef char DbLabel[8];
|
|
|
+/*
|
|
|
+ * Data types.
|
|
|
+ */
|
|
|
|
|
|
+typedef char DbLabel[8];
|
|
|
|
|
|
// TODO Most of these are no longer used. Clean up.
|
|
|
typedef enum {
|
|
@@ -33,22 +38,19 @@ typedef enum {
|
|
|
LSSTORE_DIRTY_TXN = 4, // Main txn was opened in a subroutine.
|
|
|
} StoreState;
|
|
|
|
|
|
-
|
|
|
typedef enum {
|
|
|
OP_ADD,
|
|
|
OP_REMOVE,
|
|
|
} StoreOp;
|
|
|
|
|
|
-
|
|
|
-typedef struct MDBStore {
|
|
|
- MDB_env * env; // Environment handle.
|
|
|
- MDB_txn * txn; // Current transaction.
|
|
|
- MDB_dbi dbi[N_DB]; // DB handles. Refer to DbIdx enum.
|
|
|
- LSUP_Buffer * default_ctx;// Default ctx as a serialized URI.
|
|
|
- StoreState state; // Store state.
|
|
|
+typedef struct mdbstore_t {
|
|
|
+ MDB_env * env; // Environment handle.
|
|
|
+ MDB_txn * txn; // Current transaction.
|
|
|
+ MDB_dbi dbi[N_DB]; // DB handles. Refer to DbIdx enum.
|
|
|
+ LSUP_Buffer * default_ctx; // Default ctx as a serialized URI.
|
|
|
+ StoreState state; // Store state.
|
|
|
} MDBStore;
|
|
|
|
|
|
-
|
|
|
/** @brief Iterator operation.
|
|
|
*
|
|
|
* Function executed for each iteration of a #MDBIterator. It assumes that a
|
|
@@ -59,15 +61,16 @@ typedef struct MDBStore {
|
|
|
* value for the next result. It is up to the caller to evaluate this value
|
|
|
* and decide whether to call the function again.
|
|
|
*/
|
|
|
-typedef void (*iter_op_fn_t)(struct MDBIterator *it);
|
|
|
+typedef void (*iter_op_fn_t)(LSUP_MDBIterator *it);
|
|
|
|
|
|
|
|
|
/** @brief Triple iterator.
|
|
|
*/
|
|
|
-typedef struct MDBIterator {
|
|
|
+typedef struct mdbstore_iter_t {
|
|
|
MDBStore * store; // MDB store pointer.
|
|
|
MDB_txn * txn; // MDB transaction.
|
|
|
MDB_cursor * cur; // MDB cursor.
|
|
|
+ MDB_cursor * ctx_cur; // MDB c:spo index cursor.
|
|
|
MDB_val key, data; // Internal data handlers.
|
|
|
LSUP_TripleKey spok; // Triple to be populated with match.
|
|
|
LSUP_Key ck; // Ctx key to filter by. May be NULL_TRP.
|
|
@@ -76,10 +79,32 @@ typedef struct MDBIterator {
|
|
|
LSUP_Key luk[3]; // 0÷3 lookup keys.
|
|
|
size_t i; // Internal counter for paged lookups.
|
|
|
int rc; // MDB_* return code for the next result.
|
|
|
- StoreState state; // State flags.
|
|
|
} MDBIterator;
|
|
|
|
|
|
|
|
|
+// Set of single keys.
|
|
|
+typedef struct key_set_t {
|
|
|
+ LSUP_Key key;
|
|
|
+ UT_hash_handle hh;
|
|
|
+} KeySet;
|
|
|
+
|
|
|
+// Set of triple keys.
|
|
|
+typedef struct triple_set_t {
|
|
|
+ LSUP_TripleKey spok;
|
|
|
+ UT_hash_handle hh;
|
|
|
+} TripleSet;
|
|
|
+
|
|
|
+// Map of context to triple set.
|
|
|
+typedef struct ctx_triple_map_t {
|
|
|
+ LSUP_Key ck;
|
|
|
+ TripleSet * spok;
|
|
|
+ UT_hash_handle hh;
|
|
|
+} CtxTripleMap;
|
|
|
+
|
|
|
+/*
|
|
|
+ * Static variables.
|
|
|
+ */
|
|
|
+
|
|
|
/*
|
|
|
* TODO At the moment up to 64-bit key / hash values are allowed. Later on,
|
|
|
* 128-bit keys should be allowed by compile options, and that will no longer
|
|
@@ -121,7 +146,7 @@ MAIN_TABLE
|
|
|
LOOKUP_TABLE
|
|
|
#undef ENTRY
|
|
|
|
|
|
-/**
|
|
|
+/*
|
|
|
* Numeric index of each DB. Prefixed with IDX_
|
|
|
*
|
|
|
* These index numbers are referred to in all the arrays defeined below. They
|
|
@@ -144,7 +169,7 @@ static const char *db_labels[N_DB] = {
|
|
|
#undef ENTRY
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
+/*
|
|
|
* DB flags. These are aligned with the dbi_labels index.
|
|
|
*/
|
|
|
static const unsigned int db_flags[N_DB] = {
|
|
@@ -154,7 +179,7 @@ static const unsigned int db_flags[N_DB] = {
|
|
|
#undef ENTRY
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
+/*
|
|
|
* 1-bound and 2-bound lookup indices.
|
|
|
*
|
|
|
* N.B. Only the first 6 (1-bound and 2-bound term lookup) are used.
|
|
@@ -179,7 +204,7 @@ static const uint8_t lookup_ordering_2bound[3][3] = {
|
|
|
};
|
|
|
|
|
|
|
|
|
-/**
|
|
|
+/*
|
|
|
* Static prototypes.
|
|
|
*/
|
|
|
static int index_triple(
|
|
@@ -382,12 +407,6 @@ LSUP_mdbstore_add_iter (MDBIterator *it, const LSUP_SerTriple *sspo)
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
LSUP_Buffer *st = LSUP_striple_pos (sspo, i);
|
|
|
|
|
|
-#ifdef DEBUG3
|
|
|
- printf ("Inserting term: ");
|
|
|
- LSUP_buffer_print (st);
|
|
|
- printf ("\n");
|
|
|
-#endif
|
|
|
-
|
|
|
spok[i] = LSUP_buffer_hash (st);
|
|
|
|
|
|
it->key.mv_data = spok + i;
|
|
@@ -405,8 +424,8 @@ LSUP_mdbstore_add_iter (MDBIterator *it, const LSUP_SerTriple *sspo)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- log_debug ("Inserting spok: {%lx, %lx, %lx}", spok[0], spok[1], spok[2]);
|
|
|
- log_debug ("Into context: %lx", it->ck);
|
|
|
+ log_trace ("Inserting spok: {%lx, %lx, %lx}", spok[0], spok[1], spok[2]);
|
|
|
+ log_trace ("Into context: %lx", it->ck);
|
|
|
|
|
|
// Insert spo:c.
|
|
|
it->key.mv_data = spok;
|
|
@@ -485,37 +504,31 @@ LSUP_mdbstore_add (
|
|
|
}
|
|
|
|
|
|
|
|
|
-static LSUP_Key __attribute__ ((unused))
|
|
|
+/*
|
|
|
+static LSUP_Key
|
|
|
sterm_to_key (
|
|
|
LSUP_MDBStore *store, const LSUP_Buffer *sterm)
|
|
|
{
|
|
|
// TODO this will be replaced by a lookup when 128-bit hash is introduced.
|
|
|
return LSUP_buffer_hash (sterm);
|
|
|
}
|
|
|
+*/
|
|
|
|
|
|
|
|
|
static LSUP_rc
|
|
|
-key_to_sterm(
|
|
|
- LSUP_MDBStore *store, const LSUP_Key key, LSUP_Buffer *sterm,
|
|
|
- MDB_txn *txn)
|
|
|
+key_to_sterm (LSUP_MDBIterator *it, const LSUP_Key key, LSUP_Buffer *sterm)
|
|
|
{
|
|
|
LSUP_rc rc = LSUP_NORESULT;
|
|
|
int db_rc;
|
|
|
- bool txn_dirty = false;
|
|
|
-
|
|
|
- if (!txn) {
|
|
|
- db_rc = mdb_txn_begin (store->env, NULL, MDB_RDONLY, &txn);
|
|
|
- if (db_rc != MDB_SUCCESS) return LSUP_DB_ERR;
|
|
|
- txn_dirty = true;
|
|
|
- }
|
|
|
|
|
|
MDB_val key_v, data_v;
|
|
|
key_v.mv_data = (void*)&key;
|
|
|
key_v.mv_size = KLEN;
|
|
|
|
|
|
- db_rc = mdb_get (txn, store->dbi[IDX_T_ST], &key_v, &data_v);
|
|
|
+ db_rc = mdb_get (it->txn, it->store->dbi[IDX_T_ST], &key_v, &data_v);
|
|
|
|
|
|
if (db_rc == MDB_SUCCESS) {
|
|
|
+ free (sterm->addr);
|
|
|
sterm->addr = data_v.mv_data;
|
|
|
sterm->size = data_v.mv_size;
|
|
|
rc = LSUP_OK;
|
|
@@ -525,8 +538,6 @@ key_to_sterm(
|
|
|
sterm->size = 0;
|
|
|
} else rc = LSUP_ERROR;
|
|
|
|
|
|
- if (txn_dirty) mdb_txn_abort (txn);
|
|
|
-
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -553,6 +564,24 @@ LSUP_mdbstore_lookup(
|
|
|
|
|
|
uint8_t idx0, idx1;
|
|
|
|
|
|
+ // Start RO transaction if not in a write txn already.
|
|
|
+ if (it->store->txn) it->txn = it->store->txn;
|
|
|
+ else {
|
|
|
+ it->rc = mdb_txn_begin (it->store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
+ if (it->rc != MDB_SUCCESS) {
|
|
|
+ log_error ("Database error: %s", LSUP_strerror (it->rc));
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Context index loop.
|
|
|
+ if (UNLIKELY (mdb_cursor_open (
|
|
|
+ it->txn, it->store->dbi[IDX_SPO_C], &it->ctx_cur) != MDB_SUCCESS))
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Lookup decision tree.
|
|
|
+ */
|
|
|
// s p o (all terms bound)
|
|
|
if (spok[0] != NULL_KEY && spok[1] != NULL_KEY && spok[2] != NULL_KEY) {
|
|
|
it->luk[0] = spok[0];
|
|
@@ -605,8 +634,13 @@ LSUP_mdbstore_lookup(
|
|
|
}
|
|
|
|
|
|
|
|
|
+/** @brief Get next iterator key.
|
|
|
+ *
|
|
|
+ * The ck pointer is filled with an array of contexts that the triple appears
|
|
|
+ * in, if not NULL.
|
|
|
+ */
|
|
|
inline static LSUP_rc
|
|
|
-mdbiter_next_key (LSUP_MDBIterator *it)
|
|
|
+mdbiter_next_key (LSUP_MDBIterator *it, KeySet **ck_p)
|
|
|
{
|
|
|
if (UNLIKELY (!it)) return LSUP_VALUE_ERR;
|
|
|
|
|
@@ -628,22 +662,15 @@ mdbiter_next_key (LSUP_MDBIterator *it)
|
|
|
"Found spok: {%lx, %lx, %lx}",
|
|
|
it->spok[0], it->spok[1], it->spok[2]);
|
|
|
|
|
|
- if (it->ck) {
|
|
|
- rc = LSUP_NORESULT; // Intermediary value, will never be returned.
|
|
|
+ MDB_val key, data;
|
|
|
+ int db_rc;
|
|
|
|
|
|
- MDB_cursor *cur;
|
|
|
- MDB_val key, data;
|
|
|
+ key.mv_size = TRP_KLEN;
|
|
|
+ data.mv_data = &it->ck;
|
|
|
+ data.mv_size = KLEN;
|
|
|
|
|
|
- int db_rc;
|
|
|
- db_rc = mdb_cursor_open (it->txn, it->store->dbi[IDX_SPO_C], &cur);
|
|
|
- if (UNLIKELY (db_rc != MDB_SUCCESS)) {
|
|
|
- log_error ("Database error: %s", LSUP_strerror (db_rc));
|
|
|
- return LSUP_DB_ERR;
|
|
|
- }
|
|
|
-
|
|
|
- key.mv_size = TRP_KLEN;
|
|
|
- data.mv_data = &it->ck;
|
|
|
- data.mv_size = KLEN;
|
|
|
+ if (it->ck) {
|
|
|
+ rc = LSUP_NORESULT; // Intermediary value, will never be returned.
|
|
|
|
|
|
while (rc == LSUP_NORESULT) {
|
|
|
//log_debug ("begin ctx loop.");
|
|
@@ -654,14 +681,13 @@ mdbiter_next_key (LSUP_MDBIterator *it)
|
|
|
// is an error (LSUP_DB_ERR).
|
|
|
key.mv_data = it->spok;
|
|
|
|
|
|
- db_rc = mdb_cursor_get (cur, &key, &data, MDB_GET_BOTH);
|
|
|
+ db_rc = mdb_cursor_get (it->ctx_cur, &key, &data, MDB_GET_BOTH);
|
|
|
|
|
|
if (db_rc == MDB_SUCCESS) {
|
|
|
rc = LSUP_OK;
|
|
|
log_trace ("Triple found for context.");
|
|
|
- }
|
|
|
|
|
|
- else if (db_rc == MDB_NOTFOUND) {
|
|
|
+ } else if (db_rc == MDB_NOTFOUND) {
|
|
|
log_trace ("No triples found for context.");
|
|
|
if (it->rc == MDB_NOTFOUND) rc = LSUP_END;
|
|
|
else it->iter_op_fn (it);
|
|
@@ -673,25 +699,60 @@ mdbiter_next_key (LSUP_MDBIterator *it)
|
|
|
|
|
|
}
|
|
|
|
|
|
- mdb_cursor_close (cur);
|
|
|
-
|
|
|
} else rc = LSUP_OK;
|
|
|
|
|
|
+ // Get all contexts for a triple if requested. Add up to previous
|
|
|
+ // iterations if the same pointer is passed.
|
|
|
+ if (ck_p) {
|
|
|
+ key.mv_data = it->spok;
|
|
|
+ db_rc = mdb_cursor_get (it->ctx_cur, &key, &data, MDB_SET_KEY);
|
|
|
+ if (db_rc == MDB_SUCCESS) {
|
|
|
+ do {
|
|
|
+ KeySet *entry;
|
|
|
+ HASH_FIND (hh, *ck_p, data.mv_data, KLEN, entry);
|
|
|
+ if (!entry) {
|
|
|
+ MALLOC_GUARD (entry, LSUP_MEM_ERR);
|
|
|
+ entry->key = *(LSUP_Key *) data.mv_data;
|
|
|
+ HASH_ADD (hh, *ck_p, key, KLEN, entry);
|
|
|
+ }
|
|
|
+ } while (
|
|
|
+ mdb_cursor_get (it->ctx_cur, &key, &data, MDB_NEXT_DUP)
|
|
|
+ == MDB_SUCCESS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
|
|
|
LSUP_rc
|
|
|
-LSUP_mdbiter_next (LSUP_MDBIterator *it, LSUP_SerTriple *sspo)
|
|
|
+LSUP_mdbiter_next (
|
|
|
+ LSUP_MDBIterator *it, LSUP_SerTriple *sspo, LSUP_Buffer **ctx_p)
|
|
|
{
|
|
|
- LSUP_rc rc = mdbiter_next_key (it);
|
|
|
+ LSUP_rc rc;
|
|
|
+ KeySet *ck = NULL;
|
|
|
+
|
|
|
+ rc = (ctx_p) ? mdbiter_next_key (it, &ck) : mdbiter_next_key (it, NULL);
|
|
|
+
|
|
|
+ if (rc == LSUP_OK) {
|
|
|
+ if (sspo) {
|
|
|
+ key_to_sterm (it, it->spok[0], sspo->s);
|
|
|
+ key_to_sterm (it, it->spok[1], sspo->p);
|
|
|
+ key_to_sterm (it, it->spok[2], sspo->o);
|
|
|
|
|
|
- if (sspo && rc == LSUP_OK) {
|
|
|
- key_to_sterm (it->store, it->spok[0], sspo->s, it->txn);
|
|
|
- key_to_sterm (it->store, it->spok[1], sspo->p, it->txn);
|
|
|
- key_to_sterm (it->store, it->spok[2], sspo->o, it->txn);
|
|
|
+ // TODO error handling.
|
|
|
+ }
|
|
|
|
|
|
- // TODO error handling.
|
|
|
+ // One-shot contexts for current triple.
|
|
|
+ if (ctx_p) {
|
|
|
+ KeySet *ccur;
|
|
|
+ LSUP_Buffer *ctx = malloc (HASH_COUNT (ck) * sizeof (*ctx));
|
|
|
+ size_t i = 0;
|
|
|
+ for (ccur = ck; ccur != NULL; ccur = ccur->hh.next)
|
|
|
+ key_to_sterm (it, ccur->key, ctx + (i++));
|
|
|
+
|
|
|
+ // TODO error handling.
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return rc;
|
|
@@ -708,6 +769,7 @@ LSUP_mdbiter_free (MDBIterator *it)
|
|
|
{
|
|
|
if (it) {
|
|
|
if (it->cur) mdb_cursor_close (it->cur);
|
|
|
+ if (it->ctx_cur) mdb_cursor_close (it->ctx_cur);
|
|
|
if (it->store->txn != it->txn) mdb_txn_abort (it->txn);
|
|
|
|
|
|
free (it);
|
|
@@ -747,7 +809,7 @@ LSUP_mdbstore_remove(
|
|
|
if (UNLIKELY (!it)) return LSUP_DB_ERR;
|
|
|
if (ct) log_debug ("Found %lu triples to remove.", *ct);
|
|
|
|
|
|
- while (mdbiter_next_key (it) == LSUP_OK) {
|
|
|
+ while (mdbiter_next_key (it, NULL) == LSUP_OK) {
|
|
|
spok_v.mv_data = it->spok;
|
|
|
|
|
|
rc = mdb_cursor_get (dcur, &spok_v, &ck_v, MDB_GET_BOTH);
|
|
@@ -803,6 +865,35 @@ _remove_abort:
|
|
|
}
|
|
|
|
|
|
|
|
|
+LSUP_Buffer **
|
|
|
+LSUP_mdbstore_lookup_contexts (
|
|
|
+ LSUP_MDBStore *store, const LSUP_Buffer *ss, const LSUP_Buffer *sp,
|
|
|
+ const LSUP_Buffer *so)
|
|
|
+{
|
|
|
+ LSUP_MDBIterator *it = LSUP_mdbstore_lookup (
|
|
|
+ store, ss, sp, so, NULL, NULL);
|
|
|
+
|
|
|
+ LSUP_rc rc = LSUP_NORESULT;
|
|
|
+ KeySet *ckey, *ckeys = NULL, *tmp;
|
|
|
+ while (rc != LSUP_END)
|
|
|
+ rc = mdbiter_next_key (it, &ckeys);
|
|
|
+
|
|
|
+ size_t i = 0;
|
|
|
+ LSUP_Buffer **ctx_a = calloc (HASH_COUNT (ckeys) + 1, sizeof (*ctx_a));
|
|
|
+ if (UNLIKELY (!ctx_a)) return NULL;
|
|
|
+
|
|
|
+ HASH_ITER (hh, ckeys, ckey, tmp) {
|
|
|
+ ctx_a[i] = BUF_DUMMY;
|
|
|
+ key_to_sterm (it, ckey->key, ctx_a[i++]);
|
|
|
+ HASH_DEL (ckeys, ckey);
|
|
|
+ free (ckey);
|
|
|
+ }
|
|
|
+ LSUP_mdbiter_free (it);
|
|
|
+
|
|
|
+ return ctx_a;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
LSUP_rc
|
|
|
LSUP_mdbstore_nsm_get (LSUP_MDBStore *store, LSUP_NSMap **nsm_p)
|
|
|
{
|
|
@@ -848,16 +939,20 @@ finally:
|
|
|
LSUP_rc
|
|
|
LSUP_mdbstore_nsm_store (LSUP_MDBStore *store, const LSUP_NSMap *nsm)
|
|
|
{
|
|
|
+ MDB_txn *txn;
|
|
|
+ if (!store->txn) {
|
|
|
+ RCCK (mdb_txn_begin (store->env, NULL, 0, &txn));
|
|
|
+ }
|
|
|
+ else txn = store->txn;
|
|
|
+
|
|
|
LSUP_rc rc = LSUP_NOACTION;
|
|
|
int db_rc;
|
|
|
|
|
|
MDB_cursor *dcur = NULL, *icur = NULL;
|
|
|
if (
|
|
|
- mdb_cursor_open (
|
|
|
- store->txn, store->dbi[IDX_PFX_NS], &dcur) != MDB_SUCCESS
|
|
|
+ mdb_cursor_open (txn, store->dbi[IDX_PFX_NS], &dcur) != MDB_SUCCESS
|
|
|
||
|
|
|
- mdb_cursor_open (
|
|
|
- store->txn, store->dbi[IDX_NS_PFX], &icur) != MDB_SUCCESS
|
|
|
+ mdb_cursor_open (txn, store->dbi[IDX_NS_PFX], &icur) != MDB_SUCCESS
|
|
|
) {
|
|
|
rc = LSUP_DB_ERR;
|
|
|
goto finally;
|
|
@@ -896,6 +991,8 @@ LSUP_mdbstore_nsm_store (LSUP_MDBStore *store, const LSUP_NSMap *nsm)
|
|
|
finally:
|
|
|
if (icur) mdb_cursor_close (icur);
|
|
|
if (dcur) mdb_cursor_close (dcur);
|
|
|
+ free (nsm_data);
|
|
|
+ if (txn != store->txn) mdb_txn_commit (txn);
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
@@ -1128,15 +1225,6 @@ lookup_0bound (MDBIterator *it, size_t *ct)
|
|
|
{
|
|
|
log_debug ("Looking up 0 bound terms.");
|
|
|
|
|
|
- if (it->store->txn) it->txn = it->store->txn;
|
|
|
- else {
|
|
|
- it->rc = mdb_txn_begin (it->store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
- if (it->rc != MDB_SUCCESS) {
|
|
|
- log_error ("Database error: %s", LSUP_strerror (it->rc));
|
|
|
- return LSUP_DB_ERR;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
if (ct) {
|
|
|
if (it->ck != NULL_KEY) {
|
|
|
// Look up by given context.
|
|
@@ -1192,18 +1280,6 @@ lookup_1bound (uint8_t idx0, MDBIterator *it, size_t *ct)
|
|
|
|
|
|
log_debug ("Looking up 1 bound term: %lx", it->luk[0]);
|
|
|
|
|
|
- if (!it->txn) {
|
|
|
- if (it->store->txn) it->txn = it->store->txn;
|
|
|
- else {
|
|
|
- it->rc = mdb_txn_begin (
|
|
|
- it->store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
- if (it->rc != MDB_SUCCESS) {
|
|
|
- log_error ("Database error: %s", LSUP_strerror (it->rc));
|
|
|
- return LSUP_DB_ERR;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
mdb_cursor_open (it->txn, it->store->dbi[lookup_indices[idx0]], &it->cur);
|
|
|
|
|
|
it->key.mv_data = it->luk;
|
|
@@ -1214,27 +1290,24 @@ lookup_1bound (uint8_t idx0, MDBIterator *it, size_t *ct)
|
|
|
// the context is to loop over them.
|
|
|
if (it->ck != NULL_KEY) {
|
|
|
log_debug ("Counting in context: %lx", it->ck);
|
|
|
- MDBIterator *ct_it;
|
|
|
+ MDBIterator *ct_it = NULL;
|
|
|
MALLOC_GUARD (ct_it, LSUP_MEM_ERR);
|
|
|
|
|
|
ct_it->luk[0] = it->luk[0];
|
|
|
- /*
|
|
|
- LSUP_TripleKey ct_spok;
|
|
|
- memcpy (ct_it->spok, ct_spok, sizeof (LSUP_TripleKey));
|
|
|
- */
|
|
|
ct_it->ck = it->ck;
|
|
|
ct_it->store = it->store;
|
|
|
ct_it->txn = it->txn;
|
|
|
ct_it->key = it->key;
|
|
|
ct_it->data = it->data;
|
|
|
ct_it->i = 0;
|
|
|
+ ct_it->ctx_cur = it->ctx_cur;
|
|
|
|
|
|
LSUP_rc rc = lookup_1bound (idx0, ct_it, NULL);
|
|
|
if (rc < 0) return rc;
|
|
|
|
|
|
- while (LSUP_mdbiter_next (ct_it, NULL) != LSUP_END) {
|
|
|
+ while (LSUP_mdbiter_next (ct_it, NULL, NULL) != LSUP_END) {
|
|
|
(*ct)++;
|
|
|
- log_debug ("Counter increased to %lu.", *ct);
|
|
|
+ log_trace ("Counter increased to %lu.", *ct);
|
|
|
}
|
|
|
|
|
|
// Free the counter iterator without freeing the shared txn.
|
|
@@ -1289,7 +1362,7 @@ lookup_2bound(uint8_t idx0, uint8_t idx1, MDBIterator *it, size_t *ct)
|
|
|
luk2_offset = 0;
|
|
|
}
|
|
|
dbi = it->store->dbi[lookup_indices[i + 3]];
|
|
|
- log_debug(
|
|
|
+ log_debug (
|
|
|
"Looking up 2 bound in %s",
|
|
|
db_labels[lookup_indices[i + 3]]);
|
|
|
|
|
@@ -1298,7 +1371,7 @@ lookup_2bound(uint8_t idx0, uint8_t idx1, MDBIterator *it, size_t *ct)
|
|
|
}
|
|
|
|
|
|
if (dbi == 0) {
|
|
|
- log_debug(
|
|
|
+ log_error (
|
|
|
"Values %d and %d not found in lookup keys.",
|
|
|
idx0, idx1);
|
|
|
return LSUP_VALUE_ERR;
|
|
@@ -1309,18 +1382,6 @@ lookup_2bound(uint8_t idx0, uint8_t idx1, MDBIterator *it, size_t *ct)
|
|
|
luk[luk1_offset] = it->luk[0];
|
|
|
luk[luk2_offset] = it->luk[1];
|
|
|
|
|
|
- if (!it->txn) {
|
|
|
- if (it->store->txn) it->txn = it->store->txn;
|
|
|
- else {
|
|
|
- it->rc = mdb_txn_begin (
|
|
|
- it->store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
- if (it->rc != MDB_SUCCESS) {
|
|
|
- log_error ("Database error: %s", LSUP_strerror (it->rc));
|
|
|
- return LSUP_DB_ERR;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
it->key.mv_data = luk;
|
|
|
it->key.mv_size = DBL_KLEN;
|
|
|
|
|
@@ -1336,16 +1397,13 @@ lookup_2bound(uint8_t idx0, uint8_t idx1, MDBIterator *it, size_t *ct)
|
|
|
|
|
|
ct_it->luk[0] = it->luk[0];
|
|
|
ct_it->luk[1] = it->luk[1];
|
|
|
- /*
|
|
|
- LSUP_TripleKey ct_spok;
|
|
|
- memcpy (ct_it->spok, ct_spok, sizeof (LSUP_TripleKey));
|
|
|
- */
|
|
|
ct_it->ck = it->ck;
|
|
|
ct_it->store = it->store;
|
|
|
ct_it->txn = it->txn;
|
|
|
+ ct_it->ctx_cur = it->ctx_cur;
|
|
|
lookup_2bound (idx0, idx1, ct_it, NULL);
|
|
|
|
|
|
- while (LSUP_mdbiter_next (ct_it, NULL) != LSUP_END) {
|
|
|
+ while (LSUP_mdbiter_next (ct_it, NULL, NULL) != LSUP_END) {
|
|
|
ct[0] ++;
|
|
|
}
|
|
|
|
|
@@ -1382,15 +1440,6 @@ lookup_3bound (MDBIterator *it, size_t *ct)
|
|
|
"Looking up 3 bound: {%lx, %lx, %lx}",
|
|
|
it->luk[0], it->luk[1], it->luk[2]);
|
|
|
|
|
|
- if (it->store->txn) it->txn = it->store->txn;
|
|
|
- else {
|
|
|
- it->rc = mdb_txn_begin (it->store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
- if (it->rc != MDB_SUCCESS) {
|
|
|
- log_error ("Database error: %s", LSUP_strerror (it->rc));
|
|
|
- return LSUP_DB_ERR;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
it->key.mv_data = it->luk;
|
|
|
|
|
|
if (it->ck != NULL_KEY) {
|