|
@@ -40,27 +40,13 @@ typedef enum {
|
|
|
|
|
|
struct MDBStore {
|
|
|
MDB_env * env; // Environment handle.
|
|
|
- MDB_txn * txn; // Current transaction. If RW, it may have
|
|
|
- // nested transactions.
|
|
|
+ MDB_txn * txn; // Current transaction.
|
|
|
MDB_dbi dbi[N_DB]; // DB handles. Refer to DbIdx enum.
|
|
|
LSUP_Buffer * default_ctx;// Default context as a serialized URI.
|
|
|
StoreState state; // Store state (initialized, open etc.)
|
|
|
};
|
|
|
|
|
|
|
|
|
-/** @brief Common match callback arguments.
|
|
|
- */
|
|
|
-typedef struct LookupArgs {
|
|
|
- LSUP_Key luks[3]; // 0÷3 lookup keys.
|
|
|
- uint8_t idx0, idx1; // Which term in the triple the lookup keys
|
|
|
- // represent, respectively.
|
|
|
- LSUP_Key ck; // Context key to restrict results to.
|
|
|
- size_t *ct; // Result count.
|
|
|
- struct MDBIterator *it; // Iterator returned on matches.
|
|
|
- void *data; // Arbitrary data usable by the callback.
|
|
|
-} LookupArgs;
|
|
|
-
|
|
|
-
|
|
|
/** @brief Iterator operation.
|
|
|
*
|
|
|
* Function executed for each iteration of a #MDBIterator.
|
|
@@ -72,13 +58,14 @@ typedef LSUP_rc (*iter_op_fn_t)(struct MDBIterator *it);
|
|
|
*/
|
|
|
struct MDBIterator {
|
|
|
struct MDBStore *store; // MDB store pointer.
|
|
|
+ MDB_txn *txn; // MDB transaction.
|
|
|
MDB_cursor *cur; // MDB cursor.
|
|
|
- MDB_val *key, *data; // Internal data handlers.
|
|
|
+ MDB_val key, data; // Internal data handlers.
|
|
|
LSUP_TripleKey *spok; // Triple to be populated with match.
|
|
|
LSUP_Key ck; // Context key to filter by. May be NULL_TRP.
|
|
|
iter_op_fn_t iter_op_fn; // Function used to look up next match.
|
|
|
- uint8_t term_order[3]; // Term order used in 1-2bound look-ups.
|
|
|
- LSUP_Key luks[3]; // 0÷3 lookup keys.
|
|
|
+ const uint8_t *term_order; // Term order used in 1-2bound look-ups.
|
|
|
+ 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.
|
|
|
};
|
|
@@ -207,13 +194,15 @@ static int index_triple(
|
|
|
LSUP_TripleKey spok, LSUP_Key ck);
|
|
|
|
|
|
inline static LSUP_rc lookup_0bound(
|
|
|
- struct MDBStore *store, LookupArgs *args);
|
|
|
+ struct MDBStore *store, struct MDBIterator *it, size_t *ct);
|
|
|
inline static LSUP_rc lookup_1bound(
|
|
|
- struct MDBStore *store, LookupArgs *args);
|
|
|
+ struct MDBStore *store, uint8_t idx0,
|
|
|
+ struct MDBIterator *it, size_t *ct);
|
|
|
inline static LSUP_rc lookup_2bound(
|
|
|
- struct MDBStore *store, LookupArgs *args);
|
|
|
+ struct MDBStore *store, uint8_t idx0, uint8_t idx1,
|
|
|
+ struct MDBIterator *it, size_t *ct);
|
|
|
inline static LSUP_rc lookup_3bound(
|
|
|
- struct MDBStore *store, LookupArgs *args);
|
|
|
+ struct MDBStore *store, struct MDBIterator *it, size_t *ct);
|
|
|
/* TODO
|
|
|
inline static int check_txn_open(MDB_txn *txn, bool write);
|
|
|
*/
|
|
@@ -522,7 +511,7 @@ LSUP_store_key_to_sterm(
|
|
|
LSUP_rc
|
|
|
LSUP_store_lookup(
|
|
|
LSUP_MDBStore *store, LSUP_SerTerm *sspoc[],
|
|
|
- struct MDBIterator **it, size_t *ct)
|
|
|
+ struct MDBIterator **itp, size_t *ct)
|
|
|
{
|
|
|
LSUP_TripleKey spok = {
|
|
|
LSUP_sterm_to_key(sspoc[0]),
|
|
@@ -530,64 +519,64 @@ LSUP_store_lookup(
|
|
|
LSUP_sterm_to_key(sspoc[2]),
|
|
|
};
|
|
|
|
|
|
- LookupArgs args_s;
|
|
|
- LookupArgs *args = &args_s;
|
|
|
+ LSUP_MDBIterator *it;
|
|
|
+ CRITICAL(it = malloc(sizeof(struct MDBIterator)));
|
|
|
+ *itp = it;
|
|
|
|
|
|
- args->ck = store->default_ctx ? LSUP_sterm_to_key(sspoc[3]) : NULL_KEY;
|
|
|
+ it->store = store;
|
|
|
+ it->ck = store->default_ctx ? LSUP_sterm_to_key(sspoc[3]) : NULL_KEY;
|
|
|
|
|
|
- args->ct = ct;
|
|
|
- *args->ct = 0;
|
|
|
+ if(ct) *ct = 0;
|
|
|
|
|
|
- CRITICAL(args->it = *it = malloc(sizeof(struct MDBIterator)));
|
|
|
- args->it->store = store;
|
|
|
+ uint8_t idx0, idx1;
|
|
|
|
|
|
// s p o (all terms bound)
|
|
|
if (spok[0] != NULL_KEY && spok[1] != NULL_KEY && spok[2] != NULL_KEY) {
|
|
|
- args->luks[0] = spok[0];
|
|
|
- args->luks[1] = spok[1];
|
|
|
- args->luks[2] = spok[2];
|
|
|
- return lookup_3bound(store, args);
|
|
|
- }
|
|
|
-
|
|
|
- else if (spok[0] != NULL_KEY) {
|
|
|
- args->luks[0] = spok[0];
|
|
|
- args->idx0 = 0;
|
|
|
-
|
|
|
- if (spok[1] != NULL_KEY) { // s p ?
|
|
|
- args->luks[1] = spok[1];
|
|
|
- args->idx1 = 1;
|
|
|
- return lookup_2bound(store, args);
|
|
|
-
|
|
|
- } else if (spok[2] != NULL_KEY) { // s ? o
|
|
|
- args->luks[1] = spok[2];
|
|
|
- args->idx1 = 2;
|
|
|
- return lookup_2bound(store, args);
|
|
|
-
|
|
|
- } else { // s ? ?
|
|
|
- return lookup_1bound(store, args);
|
|
|
- }
|
|
|
+ it->luk[0] = spok[0];
|
|
|
+ it->luk[1] = spok[1];
|
|
|
+ it->luk[2] = spok[2];
|
|
|
+ return lookup_3bound(store, it, ct);
|
|
|
+
|
|
|
+ } else if (spok[0] != NULL_KEY) {
|
|
|
+ it->luk[0] = spok[0];
|
|
|
+ idx0 = 0;
|
|
|
+
|
|
|
+ // s p ?
|
|
|
+ if (spok[1] != NULL_KEY) {
|
|
|
+ it->luk[1] = spok[1];
|
|
|
+ idx1 = 1;
|
|
|
+ return lookup_2bound(store, idx0, idx1, it, ct);
|
|
|
+
|
|
|
+ // s ? o
|
|
|
+ } else if (spok[2] != NULL_KEY) {
|
|
|
+ it->luk[1] = spok[2];
|
|
|
+ idx1 = 2;
|
|
|
+ return lookup_2bound(store, idx0, idx1, it, ct);
|
|
|
+
|
|
|
+ // s ? ?
|
|
|
+ } else return lookup_1bound(store, idx0, it, ct);
|
|
|
|
|
|
} else if (spok[1] != NULL_KEY) {
|
|
|
- args->luks[0] = spok[1];
|
|
|
- args->idx0 = 1;
|
|
|
-
|
|
|
- if (spok[2] != NULL_KEY) { // ? p o
|
|
|
- args->luks[1] = spok[2];
|
|
|
- args->idx1 = 2;
|
|
|
- return lookup_2bound(store, args);
|
|
|
-
|
|
|
- } else { // ? p ?
|
|
|
- return lookup_1bound(store, args);
|
|
|
- }
|
|
|
-
|
|
|
- } else if (spok[2] != NULL_KEY) { // ? ? o
|
|
|
- args->luks[0] = spok[2];
|
|
|
- args->idx0 = 2;
|
|
|
- return lookup_1bound(store, args);
|
|
|
-
|
|
|
- } else { // ? ? ? (all terms unbound)
|
|
|
- return lookup_0bound(store, args);
|
|
|
- }
|
|
|
+ it->luk[0] = spok[1];
|
|
|
+ idx0 = 1;
|
|
|
+
|
|
|
+ // ? p o
|
|
|
+ if (spok[2] != NULL_KEY) {
|
|
|
+ it->luk[1] = spok[2];
|
|
|
+ idx1 = 2;
|
|
|
+ return lookup_2bound(store, idx0, idx1, it, ct);
|
|
|
+
|
|
|
+ // ? p ?
|
|
|
+ } else return lookup_1bound(store, idx0, it, ct);
|
|
|
+
|
|
|
+ // ? ? o
|
|
|
+ } else if (spok[2] != NULL_KEY) {
|
|
|
+ it->luk[0] = spok[2];
|
|
|
+ idx0 = 2;
|
|
|
+ return lookup_1bound(store, idx0, it, ct);
|
|
|
+
|
|
|
+ // ? ? ? (all terms unbound)
|
|
|
+ } else return lookup_0bound(store, it, ct);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -646,10 +635,8 @@ void
|
|
|
LSUP_store_it_free(struct MDBIterator *it)
|
|
|
{
|
|
|
if (it) {
|
|
|
- MDB_txn *cur_txn = mdb_cursor_txn(it->cur);
|
|
|
-
|
|
|
mdb_cursor_close(it->cur);
|
|
|
- if(it->store->txn != cur_txn) mdb_txn_abort(cur_txn);
|
|
|
+ if(it->store->txn != it->txn) mdb_txn_abort(it->txn);
|
|
|
|
|
|
free(it);
|
|
|
it = NULL;
|
|
@@ -877,13 +864,13 @@ index_triple(
|
|
|
inline static LSUP_rc
|
|
|
it_next_0bound(struct MDBIterator *it)
|
|
|
{
|
|
|
- LSUP_Key *spok = (LSUP_Key*)it->data->mv_data;
|
|
|
+ LSUP_Key *spok = (LSUP_Key*)it->data.mv_data;
|
|
|
|
|
|
*it->spok[0] = spok[0];
|
|
|
*it->spok[1] = spok[1];
|
|
|
*it->spok[2] = spok[2];
|
|
|
|
|
|
- it->rc = mdb_cursor_get(it->cur, it->key, NULL, MDB_NEXT);
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, NULL, MDB_NEXT);
|
|
|
|
|
|
return LSUP_OK;
|
|
|
}
|
|
@@ -898,20 +885,20 @@ it_next_0bound(struct MDBIterator *it)
|
|
|
inline static LSUP_rc
|
|
|
it_next_1bound(struct MDBIterator *it)
|
|
|
{
|
|
|
- LSUP_Key **lu_dset = it->data->mv_data;
|
|
|
+ LSUP_Key **lu_dset = it->data.mv_data;
|
|
|
|
|
|
- *it->spok[it->term_order[0]] = it->luks[0];
|
|
|
+ *it->spok[it->term_order[0]] = it->luk[0];
|
|
|
*it->spok[it->term_order[1]] = lu_dset[it->i][0];
|
|
|
*it->spok[it->term_order[2]] = lu_dset[it->i][1];
|
|
|
|
|
|
// Ensure next block within the same page is not beyond the last.
|
|
|
- if(it->i < it->data->mv_size / DBL_KLEN - 1)
|
|
|
+ if(it->i < it->data.mv_size / DBL_KLEN - 1)
|
|
|
it->i ++;
|
|
|
else {
|
|
|
// If the last block in the page is being yielded,
|
|
|
// move cursor to beginning of next page.
|
|
|
it->i = 0;
|
|
|
- it->rc = mdb_cursor_get(it->cur, it->key, it->data, MDB_NEXT_MULTIPLE);
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_NEXT_MULTIPLE);
|
|
|
}
|
|
|
|
|
|
return LSUP_OK;
|
|
@@ -927,20 +914,20 @@ it_next_1bound(struct MDBIterator *it)
|
|
|
inline static LSUP_rc
|
|
|
it_next_2bound(struct MDBIterator *it)
|
|
|
{
|
|
|
- LSUP_Key *lu_dset = it->data->mv_data;
|
|
|
+ LSUP_Key *lu_dset = it->data.mv_data;
|
|
|
|
|
|
- *it->spok[it->term_order[0]] = it->luks[0];
|
|
|
- *it->spok[it->term_order[1]] = it->luks[1];
|
|
|
+ *it->spok[it->term_order[0]] = it->luk[0];
|
|
|
+ *it->spok[it->term_order[1]] = it->luk[1];
|
|
|
*it->spok[it->term_order[2]] = lu_dset[it->i];
|
|
|
|
|
|
// Ensure next block within the same page is not beyond the last.
|
|
|
- if(it->i < it->data->mv_size / DBL_KLEN - 1)
|
|
|
+ if(it->i < it->data.mv_size / DBL_KLEN - 1)
|
|
|
it->i ++;
|
|
|
else {
|
|
|
// If the last block in the page is being yielded,
|
|
|
// move cursor to beginning of next page.
|
|
|
it->i = 0;
|
|
|
- it->rc = mdb_cursor_get(it->cur, it->key, it->data, MDB_NEXT_MULTIPLE);
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_NEXT_MULTIPLE);
|
|
|
}
|
|
|
|
|
|
return LSUP_OK;
|
|
@@ -964,149 +951,110 @@ it_next_3bound(struct MDBIterator *it)
|
|
|
/* * * Term-specific lookups. * * */
|
|
|
|
|
|
inline static LSUP_rc
|
|
|
-lookup_0bound(struct MDBStore *store, LookupArgs *args)
|
|
|
+lookup_0bound(struct MDBStore *store, struct MDBIterator *it, size_t *ct)
|
|
|
{
|
|
|
- int rc = LSUP_NORESULT, db_rc;
|
|
|
-
|
|
|
- MDB_txn *txn;
|
|
|
- if(store->txn) txn = store->txn;
|
|
|
- else mdb_txn_begin(store->env, NULL, MDB_RDONLY, &txn);
|
|
|
-
|
|
|
- MDB_val key_v;
|
|
|
-
|
|
|
- MDB_cursor *cur;
|
|
|
+ if(store->txn) it->txn = store->txn;
|
|
|
+ else {
|
|
|
+ it->rc = mdb_txn_begin(store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
+ if (it->rc != MDB_SUCCESS) abort();
|
|
|
+ }
|
|
|
|
|
|
- if(args->ct) {
|
|
|
- if(args->ck != NULL_KEY) {
|
|
|
+ if(ct) {
|
|
|
+ if(it->ck != NULL_KEY) {
|
|
|
// Look up by given context.
|
|
|
- db_rc = mdb_cursor_open(txn, store->dbi[IDX_C_SPO], &cur);
|
|
|
+ it->rc = mdb_cursor_open(it->txn, store->dbi[IDX_C_SPO], &it->cur);
|
|
|
|
|
|
- key_v.mv_data = &args->ck;
|
|
|
- key_v.mv_size = KLEN;
|
|
|
+ it->key.mv_data = &it->ck;
|
|
|
+ it->key.mv_size = KLEN;
|
|
|
|
|
|
- db_rc = mdb_cursor_get(cur, &key_v, NULL, MDB_SET);
|
|
|
- if (db_rc != MDB_SUCCESS) return rc;
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, NULL, MDB_SET);
|
|
|
+ if (it->rc == MDB_SUCCESS) mdb_cursor_count(it->cur, ct);
|
|
|
|
|
|
- db_rc = mdb_cursor_count(cur, args->ct);
|
|
|
+ mdb_cursor_close(it->cur);
|
|
|
|
|
|
} else {
|
|
|
// Look up all contexts.
|
|
|
MDB_stat stat;
|
|
|
- mdb_stat(txn, store->dbi[IDX_S_PO], &stat);
|
|
|
+ mdb_stat(it->txn, store->dbi[IDX_S_PO], &stat);
|
|
|
|
|
|
- *args->ct = stat.ms_entries;
|
|
|
+ *ct = stat.ms_entries;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- args->it->ck = args->ck;
|
|
|
- memcpy(args->it->key, &key_v, sizeof(MDB_val));
|
|
|
-
|
|
|
- mdb_cursor_open(txn, store->dbi[IDX_SPO_C], &args->it->cur);
|
|
|
+ mdb_cursor_open(it->txn, store->dbi[IDX_SPO_C], &it->cur);
|
|
|
|
|
|
- args->it->rc = mdb_cursor_get(
|
|
|
- args->it->cur, args->it->key, args->it->data, MDB_FIRST);
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_FIRST);
|
|
|
+ it->iter_op_fn = it_next_0bound;
|
|
|
|
|
|
- args->it->iter_op_fn = it_next_0bound;
|
|
|
-
|
|
|
- return args->it->rc == MDB_SUCCESS ? LSUP_OK : LSUP_NORESULT;
|
|
|
-
|
|
|
- mdb_cursor_close(cur);
|
|
|
- if (txn != store->txn) mdb_txn_abort(txn);
|
|
|
-
|
|
|
- return rc;
|
|
|
+ return it->rc == MDB_SUCCESS ? LSUP_OK : LSUP_NORESULT;
|
|
|
}
|
|
|
|
|
|
|
|
|
inline static LSUP_rc
|
|
|
-lookup_1bound(struct MDBStore *store, LookupArgs *args)
|
|
|
+lookup_1bound(
|
|
|
+ struct MDBStore *store, uint8_t idx0,
|
|
|
+ struct MDBIterator *it, size_t *ct)
|
|
|
{
|
|
|
- int rc = LSUP_NORESULT, db_rc;
|
|
|
-
|
|
|
- const uint8_t *term_order = lookup_ordering_1bound[args->idx0];
|
|
|
+ it->term_order = (const uint8_t*)lookup_ordering_1bound[idx0];
|
|
|
|
|
|
- TRACE("Looking up 1 bound term: %lx\n", args->luks[0]);
|
|
|
+ TRACE("Looking up 1 bound term: %lx\n", it->luk[0]);
|
|
|
|
|
|
- MDB_txn *txn;
|
|
|
- if(store->txn) txn = store->txn;
|
|
|
+ if(store->txn) it->txn = store->txn;
|
|
|
else {
|
|
|
- db_rc = mdb_txn_begin(store->env, NULL, MDB_RDONLY, &txn);
|
|
|
- if (db_rc != MDB_SUCCESS) abort();
|
|
|
+ it->rc = mdb_txn_begin(store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
+ if (it->rc != MDB_SUCCESS) abort();
|
|
|
}
|
|
|
|
|
|
|
|
|
- MDB_cursor *cur;
|
|
|
- mdb_cursor_open(txn, store->dbi[lookup_indices[args->idx0]], &cur);
|
|
|
+ mdb_cursor_open(it->txn, store->dbi[lookup_indices[idx0]], &it->cur);
|
|
|
|
|
|
- MDB_val key_v, data_v;
|
|
|
- key_v.mv_data = args->luks;
|
|
|
- key_v.mv_size = KLEN;
|
|
|
+ it->key.mv_data = it->luk;
|
|
|
+ it->key.mv_size = KLEN;
|
|
|
|
|
|
- if(args->ct) {
|
|
|
- if (args->ck != NULL_KEY) {
|
|
|
- db_rc = mdb_cursor_get(cur, &key_v, &data_v, MDB_GET_MULTIPLE);
|
|
|
- while (db_rc != MDB_NOTFOUND) {
|
|
|
+ if(ct) {
|
|
|
+ if (it->ck != NULL_KEY) {
|
|
|
+ it->rc = mdb_cursor_get(
|
|
|
+ it->cur, &it->key, &it->data, MDB_GET_MULTIPLE);
|
|
|
+ while (it->rc != MDB_NOTFOUND) {
|
|
|
}
|
|
|
} else {
|
|
|
- db_rc = mdb_cursor_get(cur, &key_v, &data_v, MDB_SET);
|
|
|
- if (db_rc != MDB_SUCCESS) return rc;
|
|
|
-
|
|
|
- db_rc = mdb_cursor_count(cur, args->ct);
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_SET);
|
|
|
+ if (it->rc == MDB_SUCCESS) mdb_cursor_count(it->cur, ct);
|
|
|
}
|
|
|
-
|
|
|
- if (!args->it && *args->ct > 0) rc = LSUP_OK;
|
|
|
}
|
|
|
|
|
|
- if(args->it) {
|
|
|
- args->it->ck = args->ck;
|
|
|
- args->it->cur = cur;
|
|
|
- memcpy(args->it->key, &key_v, sizeof(MDB_val));
|
|
|
- memcpy(args->it->data, &data_v, sizeof(MDB_val));
|
|
|
- args->it->term_order[0] = term_order[0];
|
|
|
- args->it->term_order[1] = term_order[1];
|
|
|
- args->it->term_order[2] = term_order[2];
|
|
|
- args->it->luks[0] = args->luks[0];
|
|
|
- args->it->i = 0;
|
|
|
- args->it->iter_op_fn = it_next_1bound;
|
|
|
-
|
|
|
- args->it->rc = mdb_cursor_get(
|
|
|
- args->it->cur, args->it->key, args->it->data, MDB_SET);
|
|
|
- if (args->it->rc == MDB_SUCCESS)
|
|
|
- args->it->rc = mdb_cursor_get(
|
|
|
- args->it->cur, args->it->key, args->it->data,
|
|
|
- MDB_GET_MULTIPLE);
|
|
|
-
|
|
|
- return args->it->rc == MDB_SUCCESS ? LSUP_OK : LSUP_NORESULT;
|
|
|
- }
|
|
|
+ it->i = 0;
|
|
|
+ it->iter_op_fn = it_next_1bound;
|
|
|
|
|
|
- mdb_cursor_close(cur);
|
|
|
- if (txn != store->txn) mdb_txn_abort(txn);
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_SET);
|
|
|
+ if (it->rc == MDB_SUCCESS)
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_GET_MULTIPLE);
|
|
|
|
|
|
- return rc;
|
|
|
+ return it->rc == MDB_SUCCESS ? LSUP_OK : LSUP_NORESULT;
|
|
|
}
|
|
|
|
|
|
|
|
|
inline static LSUP_rc
|
|
|
-lookup_2bound(struct MDBStore *store, LookupArgs *args)
|
|
|
+lookup_2bound(
|
|
|
+ struct MDBStore *store, uint8_t idx0, uint8_t idx1,
|
|
|
+ struct MDBIterator *it, size_t *ct)
|
|
|
{
|
|
|
- int rc = LSUP_NORESULT;
|
|
|
-
|
|
|
uint8_t luk1_offset, luk2_offset;
|
|
|
- const uint8_t *term_order;
|
|
|
MDB_dbi dbi = 0;
|
|
|
|
|
|
// Establish lookup ordering with some awkward offset math.
|
|
|
for(int i = 0; i < 3; i++) {
|
|
|
if (
|
|
|
(
|
|
|
- args->idx0 == lookup_ordering_2bound[i][0] &&
|
|
|
- args->idx1 == lookup_ordering_2bound[i][1]
|
|
|
+ idx0 == lookup_ordering_2bound[i][0] &&
|
|
|
+ idx1 == lookup_ordering_2bound[i][1]
|
|
|
) || (
|
|
|
- args->idx0 == lookup_ordering_2bound[i][1] &&
|
|
|
- args->idx1 == lookup_ordering_2bound[i][0]
|
|
|
+ idx0 == lookup_ordering_2bound[i][1] &&
|
|
|
+ idx1 == lookup_ordering_2bound[i][0]
|
|
|
)
|
|
|
) {
|
|
|
- term_order = lookup_ordering_2bound[i];
|
|
|
- if (term_order[0] == args->idx0) {
|
|
|
+ it->term_order = (const uint8_t*)lookup_ordering_2bound[i];
|
|
|
+ if (it->term_order[0] == idx0) {
|
|
|
luk1_offset = 0;
|
|
|
luk2_offset = 1;
|
|
|
} else {
|
|
@@ -1125,113 +1073,69 @@ lookup_2bound(struct MDBStore *store, LookupArgs *args)
|
|
|
if (dbi == 0) {
|
|
|
TRACE(
|
|
|
"Values %d and %d not found in lookup keys.",
|
|
|
- args->idx0, args->idx1);
|
|
|
+ idx0, idx1);
|
|
|
return LSUP_VALUE_ERR;
|
|
|
}
|
|
|
|
|
|
// Compose term keys in lookup key.
|
|
|
LSUP_DoubleKey luk;
|
|
|
- luk[luk1_offset] = args->luks[0];
|
|
|
- luk[luk2_offset] = args->luks[1];
|
|
|
+ luk[luk1_offset] = it->luk[0];
|
|
|
+ luk[luk2_offset] = it->luk[1];
|
|
|
|
|
|
- MDB_txn *txn;
|
|
|
- if(store->txn) txn = store->txn;
|
|
|
- else mdb_txn_begin(store->env, NULL, MDB_RDONLY, &txn);
|
|
|
-
|
|
|
- MDB_cursor *cur;
|
|
|
- mdb_cursor_open(txn, dbi, &cur);
|
|
|
+ if(store->txn) it->txn = store->txn;
|
|
|
+ else mdb_txn_begin(store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
|
|
|
- MDB_val key_v, data_v;
|
|
|
- key_v.mv_data = luk;
|
|
|
- key_v.mv_size = DBL_KLEN;
|
|
|
+ it->key.mv_data = luk;
|
|
|
+ it->key.mv_size = DBL_KLEN;
|
|
|
|
|
|
- if(args->ct) {
|
|
|
- mdb_cursor_get(cur, &key_v, &data_v, MDB_SET);
|
|
|
- mdb_cursor_count(cur, args->ct);
|
|
|
+ mdb_cursor_open(it->txn, dbi, &it->cur);
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_SET);
|
|
|
|
|
|
- if (!args->it && *args->ct > 0) rc = LSUP_OK;
|
|
|
- }
|
|
|
+ if(ct && it->rc == MDB_SUCCESS) mdb_cursor_count(it->cur, ct);
|
|
|
|
|
|
- if(args->it) {
|
|
|
- args->it->ck = args->ck;
|
|
|
- args->it->cur = cur;
|
|
|
- memcpy(args->it->key, &key_v, sizeof(MDB_val));
|
|
|
- memcpy(args->it->data, &data_v, sizeof(MDB_val));
|
|
|
- args->it->term_order[0] = term_order[0];
|
|
|
- args->it->term_order[1] = term_order[1];
|
|
|
- args->it->term_order[2] = term_order[2];
|
|
|
- args->it->luks[0] = args->luks[0];
|
|
|
- args->it->luks[1] = args->luks[1];
|
|
|
- args->it->i = 0;
|
|
|
- args->it->iter_op_fn = it_next_2bound;
|
|
|
-
|
|
|
- args->it->rc = mdb_cursor_get(
|
|
|
- args->it->cur, args->it->key, args->it->data, MDB_SET);
|
|
|
- if (args->it->rc == MDB_SUCCESS)
|
|
|
- args->it->rc = mdb_cursor_get(
|
|
|
- args->it->cur, args->it->key, args->it->data,
|
|
|
- MDB_GET_MULTIPLE);
|
|
|
-
|
|
|
- return args->it->rc == MDB_SUCCESS ? LSUP_OK : LSUP_NORESULT;
|
|
|
- }
|
|
|
+ it->i = 0;
|
|
|
+ it->iter_op_fn = it_next_2bound;
|
|
|
|
|
|
- mdb_cursor_close(cur);
|
|
|
- if (txn != store->txn) mdb_txn_abort(txn);
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_SET);
|
|
|
+ if (it->rc == MDB_SUCCESS)
|
|
|
+ it->rc = mdb_cursor_get(it->cur, &it->key, &it->data, MDB_GET_MULTIPLE);
|
|
|
|
|
|
- return rc;
|
|
|
+ return it->rc == MDB_SUCCESS ? LSUP_OK : LSUP_NORESULT;
|
|
|
}
|
|
|
|
|
|
|
|
|
inline static LSUP_rc
|
|
|
-lookup_3bound(struct MDBStore *store, LookupArgs *args)
|
|
|
+lookup_3bound(struct MDBStore *store, struct MDBIterator *it, size_t *ct)
|
|
|
{
|
|
|
TRACE(
|
|
|
"Looking up 3 bound: {%lx, %lx, %lx}",
|
|
|
- args->luks[0], args->luks[1], args->luks[2]);
|
|
|
+ it->luk[0], it->luk[1], it->luk[2]);
|
|
|
LSUP_rc rc = LSUP_NORESULT;
|
|
|
|
|
|
- MDB_txn *txn;
|
|
|
- if(store->txn) txn = store->txn;
|
|
|
- else mdb_txn_begin(store->env, NULL, MDB_RDONLY, &txn);
|
|
|
+ if(store->txn) it->txn = store->txn;
|
|
|
+ else mdb_txn_begin(store->env, NULL, MDB_RDONLY, &it->txn);
|
|
|
|
|
|
MDB_cursor *cur;
|
|
|
- int db_rc = mdb_cursor_open(txn, store->dbi[IDX_S_PO], &cur);
|
|
|
-
|
|
|
- MDB_val key_v, data_v;
|
|
|
- key_v.mv_data = args->luks;
|
|
|
- key_v.mv_size = KLEN;
|
|
|
- data_v.mv_data = args->luks + 1;
|
|
|
- data_v.mv_size = DBL_KLEN;
|
|
|
-
|
|
|
- db_rc = mdb_cursor_get(cur, &key_v, &data_v, MDB_GET_BOTH);
|
|
|
-
|
|
|
- if(args->ct) {
|
|
|
- if (db_rc == MDB_SUCCESS) {
|
|
|
- *args->ct = 1;
|
|
|
- if (!args->it) rc = LSUP_OK;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(args->it) {
|
|
|
- args->it->rc = db_rc;
|
|
|
- if (args->it->rc == MDB_NOTFOUND) {
|
|
|
- rc = LSUP_NORESULT;
|
|
|
- } else {
|
|
|
- args->it->ck = args->ck;
|
|
|
- args->it->iter_op_fn = it_next_3bound;
|
|
|
- *args->it->spok[0] = args->luks[0];
|
|
|
- *args->it->spok[1] = args->luks[1];
|
|
|
- *args->it->spok[2] = args->luks[2];
|
|
|
- args->it->rc = LSUP_OK;
|
|
|
- rc = LSUP_OK;
|
|
|
- }
|
|
|
-
|
|
|
- return rc;
|
|
|
+ it->rc = mdb_cursor_open(it->txn, store->dbi[IDX_S_PO], &cur);
|
|
|
+
|
|
|
+ it->key.mv_data = it->luk;
|
|
|
+ it->key.mv_size = KLEN;
|
|
|
+ it->data.mv_data = it->luk + 1;
|
|
|
+ it->data.mv_size = DBL_KLEN;
|
|
|
+
|
|
|
+ it->rc = mdb_cursor_get(cur, &it->key, &it->data, MDB_GET_BOTH);
|
|
|
+ if(ct && it->rc == MDB_SUCCESS) *ct = 1;
|
|
|
+
|
|
|
+ if (it->rc == MDB_NOTFOUND) {
|
|
|
+ rc = LSUP_NORESULT;
|
|
|
+ } else {
|
|
|
+ it->iter_op_fn = it_next_3bound;
|
|
|
+ *it->spok[0] = it->luk[0];
|
|
|
+ *it->spok[1] = it->luk[1];
|
|
|
+ *it->spok[2] = it->luk[2];
|
|
|
+ rc = LSUP_OK;
|
|
|
}
|
|
|
|
|
|
- mdb_cursor_close(cur);
|
|
|
- if (txn != store->txn) mdb_txn_abort(txn);
|
|
|
-
|
|
|
return rc;
|
|
|
}
|
|
|
|