|
@@ -256,7 +256,7 @@ finally:
|
|
|
|
|
|
|
|
|
static LSUP_rc
|
|
|
-nsm_put (MDB_env *env, MDB_txn *p_txn, const LSUP_NSMap *nsm)
|
|
|
+nsm_update (MDB_env *env, const char *pfx, const char *ns, MDB_txn *p_txn)
|
|
|
{
|
|
|
LSUP_rc rc = LSUP_NOACTION;
|
|
|
int db_rc;
|
|
@@ -274,53 +274,43 @@ nsm_put (MDB_env *env, MDB_txn *p_txn, const LSUP_NSMap *nsm)
|
|
|
RCCK (mdb_cursor_open (txn, idbi, &icur));
|
|
|
|
|
|
MDB_val pfx_v, ns_v;
|
|
|
- const char ***nsm_data = LSUP_nsmap_dump (nsm);
|
|
|
|
|
|
- for (size_t i = 0; nsm_data[i] != NULL; i++) {
|
|
|
- // At least 1 action. If not OK, it will change during the iteration.
|
|
|
- if (i == 0) rc = LSUP_OK;
|
|
|
- // On previous error, just clean up the NSM data array.
|
|
|
- if (rc < 0) goto loop_end;
|
|
|
+ pfx_v.mv_data = (void *) pfx;
|
|
|
+ pfx_v.mv_size = strlen (pfx) + 1;
|
|
|
|
|
|
- pfx_v.mv_data = (void *) nsm_data[i][0];
|
|
|
- pfx_v.mv_size = strlen (nsm_data[i][0]) + 1;
|
|
|
- ns_v.mv_data = (void *) nsm_data[i][1];
|
|
|
- ns_v.mv_size = strlen (nsm_data[i][1]) + 1;
|
|
|
+ if (ns) {
|
|
|
+ // Add or update prefix mapping.
|
|
|
+ ns_v.mv_data = (void *) ns;
|
|
|
+ ns_v.mv_size = strlen (ns) + 1;
|
|
|
|
|
|
- // If either ns or pfx exist, skip.
|
|
|
- if (
|
|
|
- mdb_cursor_get (dcur, &pfx_v, &ns_v, MDB_SET) != MDB_NOTFOUND
|
|
|
- ||
|
|
|
- mdb_cursor_get (icur, &ns_v, &pfx_v, MDB_SET) != MDB_NOTFOUND
|
|
|
- ) {
|
|
|
- rc = LSUP_CONFLICT;
|
|
|
- goto loop_end;
|
|
|
- }
|
|
|
+ CHECK ((rc = mdb_cursor_put (dcur, &pfx_v, &ns_v, 0)), fail);
|
|
|
+ CHECK ((rc = mdb_cursor_put (icur, &ns_v, &pfx_v, 0)), fail);
|
|
|
|
|
|
- db_rc = mdb_cursor_put (dcur, &pfx_v, &ns_v, 0);
|
|
|
- db_rc |= mdb_cursor_put (icur, &ns_v, &pfx_v, 0);
|
|
|
- if (db_rc != MDB_SUCCESS) {
|
|
|
- log_error ("DB error: %s", LSUP_strerror (db_rc));
|
|
|
- rc = LSUP_DB_ERR;
|
|
|
- }
|
|
|
-loop_end:
|
|
|
- free (nsm_data[i]);
|
|
|
+ } else {
|
|
|
+ // Delete prefix.
|
|
|
+ if (mdb_cursor_get (dcur, &pfx_v, &ns_v, MDB_SET_KEY) == MDB_NOTFOUND)
|
|
|
+ goto success;
|
|
|
+ CHECK ((rc = mdb_cursor_del (dcur, 0)), fail);
|
|
|
+ if (mdb_cursor_get (icur, &ns_v, &pfx_v, MDB_GET_BOTH) == MDB_NOTFOUND)
|
|
|
+ goto success;
|
|
|
+ CHECK ((rc = mdb_cursor_del (icur, 0)), fail);
|
|
|
}
|
|
|
- free (nsm_data);
|
|
|
|
|
|
- if (UNLIKELY (rc != LSUP_OK)) mdb_txn_abort (txn);
|
|
|
- else if (UNLIKELY (mdb_txn_commit (txn) != MDB_SUCCESS)) {
|
|
|
- mdb_txn_abort (txn);
|
|
|
- rc = LSUP_TXN_ERR;
|
|
|
- }
|
|
|
+success:
|
|
|
+ CHECK (mdb_txn_commit (txn), fail);
|
|
|
+
|
|
|
+ return rc;
|
|
|
+
|
|
|
+fail:
|
|
|
+ mdb_txn_abort (txn);
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
|
|
|
static LSUP_rc
|
|
|
-mdbstore_nsm_put (void *h, const LSUP_NSMap *nsm, void *th)
|
|
|
-{ return nsm_put (((MDBStore *)h)->env, (MDB_txn *)th, nsm); }
|
|
|
+mdbstore_nsm_update (void *h, const char *pfx, const char *ns, void *th)
|
|
|
+{ return nsm_update (((MDBStore *)h)->env, pfx, ns, (MDB_txn *)th); }
|
|
|
|
|
|
|
|
|
static const char *
|
|
@@ -384,10 +374,22 @@ mdbstore_setup (const char *id, bool clear)
|
|
|
CHECK (mdb_dbi_open (
|
|
|
txn, db_labels[IDX_PFX_NS], db_flags[IDX_PFX_NS], &dbi), fail);
|
|
|
CHECK (mdb_stat (txn, dbi, &stat), fail);
|
|
|
+
|
|
|
+ const char ***nsm_data = NULL;
|
|
|
if (stat.ms_entries == 0) {
|
|
|
- LOG_DEBUG ("Loading initial data into %s", id);
|
|
|
+ LOG_DEBUG ("Loading initial data into %s", path);
|
|
|
// Load initial NS map.
|
|
|
- PCHECK (nsm_put (env, txn, LSUP_default_nsm), fail);
|
|
|
+ nsm_data = LSUP_nsmap_dump (LSUP_default_nsm);
|
|
|
+ if (UNLIKELY (!nsm_data)) {
|
|
|
+ rc = LSUP_ERROR;
|
|
|
+ goto loop_fail;
|
|
|
+ }
|
|
|
+ for (size_t i = 0; nsm_data[i] != NULL; i++)
|
|
|
+ PCHECK (nsm_update (
|
|
|
+ env, nsm_data[i][0], nsm_data[i][1], txn), loop_fail);
|
|
|
+ for (size_t i = 0; nsm_data[i] != NULL; i++)
|
|
|
+ free (nsm_data[i]);
|
|
|
+ free (nsm_data);
|
|
|
|
|
|
// Index default context.
|
|
|
CHECK (mdb_dbi_open (
|
|
@@ -412,7 +414,12 @@ mdbstore_setup (const char *id, bool clear)
|
|
|
|
|
|
return clear ? LSUP_OK : rc;
|
|
|
|
|
|
+loop_fail:
|
|
|
+ for (size_t i = 0; nsm_data[i] != NULL; i++)
|
|
|
+ free (nsm_data[i]);
|
|
|
+ free (nsm_data);
|
|
|
fail:
|
|
|
+ if (rc >= 0) rc = LSUP_DB_ERR;
|
|
|
mdb_txn_abort (txn);
|
|
|
return rc;
|
|
|
}
|
|
@@ -445,9 +452,9 @@ mdbstore_new (const char *id, size_t _unused)
|
|
|
size_t mapsize;
|
|
|
char *env_mapsize = getenv ("LSUP_MDB_MAPSIZE");
|
|
|
if (env_mapsize == NULL) mapsize = DEFAULT_MAPSIZE;
|
|
|
- else sscanf (env_mapsize, "%lu", &mapsize);
|
|
|
+ else sscanf (env_mapsize, "%zu", &mapsize);
|
|
|
log_info (
|
|
|
- "Setting environment map size at %s to %lu Mb.",
|
|
|
+ "Setting environment map size at %s to %zu Mb.",
|
|
|
path, mapsize / 1024 / 1024);
|
|
|
CHECK (mdb_env_set_mapsize (store->env, mapsize), fail);
|
|
|
CHECK (mdb_env_set_maxdbs (store->env, N_DB), fail);
|
|
@@ -1337,7 +1344,7 @@ fail:
|
|
|
const LSUP_StoreInt mdbstore_int = {
|
|
|
.name = "MDB Store",
|
|
|
.features = LSUP_STORE_PERM | LSUP_STORE_CTX | LSUP_STORE_IDX
|
|
|
- | LSUP_STORE_TXN | LSUP_STORE_COW,
|
|
|
+ | LSUP_STORE_TXN | LSUP_STORE_COW | LSUP_STORE_OWN_NSM,
|
|
|
|
|
|
.setup_fn = mdbstore_setup,
|
|
|
.new_fn = mdbstore_new,
|
|
@@ -1364,10 +1371,10 @@ const LSUP_StoreInt mdbstore_int = {
|
|
|
|
|
|
.remove_fn = mdbstore_remove,
|
|
|
|
|
|
- .nsm_put_fn = mdbstore_nsm_put,
|
|
|
+ .nsm_update_fn = mdbstore_nsm_update,
|
|
|
.nsm_get_fn = mdbstore_nsm_get,
|
|
|
|
|
|
- .ctx_list_fn = mdbstore_ctx_list,
|
|
|
+ .ctx_list_fn = mdbstore_ctx_list,
|
|
|
};
|
|
|
|
|
|
|