mdbx: refine mdbx_dkey() API.

This commit is contained in:
Leo Yuriev 2017-05-17 22:17:24 +03:00
parent c479c5ff15
commit 4481555c90
2 changed files with 54 additions and 46 deletions

3
mdbx.h
View File

@ -1463,7 +1463,8 @@ LIBMDBX_API int mdbx_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx);
* Returns 0 on success, non-zero on failure. */ * Returns 0 on success, non-zero on failure. */
LIBMDBX_API int mdbx_reader_check(MDB_env *env, int *dead); LIBMDBX_API int mdbx_reader_check(MDB_env *env, int *dead);
LIBMDBX_API char *mdbx_dkey(MDB_val *key, char *buf, const size_t bufsize); LIBMDBX_API char *mdbx_dkey(const MDB_val *key, char *const buf,
const size_t bufsize);
LIBMDBX_API int mdbx_env_close_ex(MDB_env *env, int dont_sync); LIBMDBX_API int mdbx_env_close_ex(MDB_env *env, int dont_sync);

View File

@ -324,16 +324,19 @@ txnid_t mdbx_debug_edge;
/** The version number for a database's lockfile format. */ /** The version number for a database's lockfile format. */
#define MDB_LOCK_VERSION ((MDB_DEVEL) ? 999 : 1) #define MDB_LOCK_VERSION ((MDB_DEVEL) ? 999 : 1)
/* Key size which fits in a #DKBUF. */
#define DKBUF_MAXKEYSIZE 511 /* FIXME */ #define DKBUF_MAXKEYSIZE 511 /* FIXME */
/** Key size which fits in a #DKBUF.
* @ingroup debug #if MDB_DEBUG
*/ #define DKBUF char _kbuf[DKBUF_MAXKEYSIZE * 4 + 2]
#define DKBUF char kbuf[DKBUF_MAXKEYSIZE] #define DKEY(x) mdbx_dkey(x, _kbuf, DKBUF_MAXKEYSIZE * 2 + 1)
/** Display a key in hex. #define DVAL(x) \
* @ingroup debug mdbx_dkey(x, _kbuf + DKBUF_MAXKEYSIZE * 2 + 1, DKBUF_MAXKEYSIZE * 2 + 1)
* Invoke a function to display a key in hex. #else
*/ #define DKBUF ((void)(0))
#define DKEY(x) mdbx_dkey(x, kbuf, sizeof(kbuf)) #define DKEY(x) ("-")
#define DVAL(x) ("-")
#endif
/** An invalid page number. /** An invalid page number.
* Mainly used to denote an empty tree. * Mainly used to denote an empty tree.
@ -837,43 +840,46 @@ static __inline pgno_t mdbx_dbg_pgno(MDB_page *mp) {
return ret; return ret;
} }
/** Display a key in hexadecimal and return the address of the result. /* Dump a key in ascii or hexadecimal. */
* @param[in] key the key to display char *mdbx_dkey(const MDB_val *key, char *const buf, const size_t bufsize) {
* @param[in] buf the buffer to write into. Should always be #DKBUF.
* @return The key in hexadecimal form.
*/
char *mdbx_dkey(MDB_val *key, char *buf, const size_t bufsize) {
#ifdef _MSC_VER
(void)key;
(void)buf;
return "FIXME: mdbx_dkey()";
#else
char *ptr = buf;
unsigned i;
if (!key) if (!key)
return ""; return "<null>";
if (!buf || bufsize < 4)
return nullptr;
if (!key->iov_len)
return "<empty>";
const uint8_t *const data = key->mv_data; const uint8_t *const data = key->mv_data;
bool is_ascii = true; bool is_ascii = true;
unsigned i;
for (i = 0; is_ascii && i < key->mv_size; i++) for (i = 0; is_ascii && i < key->mv_size; i++)
if (data[i] < ' ' || data[i] > 127) if (data[i] < ' ' || data[i] > 127)
is_ascii = false; is_ascii = false;
if (is_ascii) if (is_ascii) {
snprintf(buf, bufsize, "%.*s", int len =
(key->mv_size > INT_MAX) ? INT_MAX : (int)key->mv_size, data); snprintf(buf, bufsize, "%.*s",
else { (key->mv_size > INT_MAX) ? INT_MAX : (int)key->mv_size, data);
buf[0] = '\0'; assert(len > 0 && (unsigned)len < bufsize);
(void)len;
} else {
char *const detent = buf + bufsize - 2;
char *ptr = buf;
*ptr++ = '<';
for (i = 0; i < key->mv_size; i++) { for (i = 0; i < key->mv_size; i++) {
int len = snprintf(ptr, bufsize - (ptr - buf), "%02x", data[i]); const ptrdiff_t left = detent - ptr;
if (len < 1) assert(left > 0);
int len = snprintf(ptr, left, "%02x", data[i]);
if (len < 0 || len >= left)
break; break;
ptr += len; ptr += len;
} }
if (ptr < detent) {
ptr[0] = '>';
ptr[1] = '\0';
}
} }
return buf; return buf;
#endif /* _MSC_VER */
} }
#if 0 /* LY: debug stuff */ #if 0 /* LY: debug stuff */
@ -4660,7 +4666,7 @@ static int mdbx_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) {
} }
mdbx_debug("found leaf page %" PRIuPTR " for key [%s]", mp->mp_pgno, mdbx_debug("found leaf page %" PRIuPTR " for key [%s]", mp->mp_pgno,
key ? DKEY(key) : "null"); DKEY(key));
mc->mc_flags |= C_INITIALIZED; mc->mc_flags |= C_INITIALIZED;
mc->mc_flags &= ~C_EOF; mc->mc_flags &= ~C_EOF;
@ -5318,8 +5324,8 @@ set1:
/* The key already matches in all other cases */ /* The key already matches in all other cases */
if (op == MDB_SET_RANGE || op == MDB_SET_KEY) if (op == MDB_SET_RANGE || op == MDB_SET_KEY)
MDB_GET_KEY(leaf, key); MDB_GET_KEY(leaf, key);
mdbx_debug("==> cursor placed on key [%s]", DKEY(key));
mdbx_debug("==> cursor placed on key [%s], data [%s]", DKEY(key), DVAL(data));
return rc; return rc;
} }
@ -5627,9 +5633,7 @@ int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
env = mc->mc_txn->mt_env; env = mc->mc_txn->mt_env;
/* Check this first so counter will always be zero on any /* Check this first so counter will always be zero on any early failures. */
* early failures.
*/
if (flags & MDB_MULTIPLE) { if (flags & MDB_MULTIPLE) {
dcount = data[1].mv_size; dcount = data[1].mv_size;
data[1].mv_size = 0; data[1].mv_size = 0;
@ -5640,6 +5644,7 @@ int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
if (flags & MDB_RESERVE) { if (flags & MDB_RESERVE) {
if (unlikely(mc->mc_db->md_flags & (MDB_DUPSORT | MDB_REVERSEDUP))) if (unlikely(mc->mc_db->md_flags & (MDB_DUPSORT | MDB_REVERSEDUP)))
return MDB_INCOMPATIBLE; return MDB_INCOMPATIBLE;
data->mv_data = nullptr;
} }
nospill = flags & MDB_NOSPILL; nospill = flags & MDB_NOSPILL;
@ -5670,9 +5675,10 @@ int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
return MDB_BAD_VALSIZE; return MDB_BAD_VALSIZE;
} }
mdbx_debug("==> put db %d key [%s], size %" PRIuPTR ", data size %" PRIuPTR mdbx_debug("==> put db %d key [%s], size %" PRIuPTR
"", ", data [%s] size %" PRIuPTR,
DDBI(mc), DKEY(key), key ? key->mv_size : 0, data->mv_size); DDBI(mc), DKEY(key), key ? key->mv_size : 0,
DVAL((flags & MDB_RESERVE) ? nullptr : data), data->mv_size);
int dupdata_flag = 0; int dupdata_flag = 0;
if (flags & MDB_CURRENT) { if (flags & MDB_CURRENT) {
@ -6151,8 +6157,8 @@ new_sub:
} }
return rc; return rc;
bad_sub: bad_sub:
if (unlikely(rc == if (unlikely(rc == MDB_KEYEXIST))
MDB_KEYEXIST)) /* should not happen, we deleted that item */ /* should not happen, we deleted that item */
rc = MDB_PROBLEM; rc = MDB_PROBLEM;
} }
mc->mc_txn->mt_flags |= MDB_TXN_ERROR; mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
@ -6391,7 +6397,7 @@ static int mdbx_node_add(MDB_cursor *mc, indx_t indx, MDB_val *key,
" key size %" PRIuPTR " [%s]", " key size %" PRIuPTR " [%s]",
IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "", IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "",
mdbx_dbg_pgno(mp), indx, data ? data->mv_size : 0, mdbx_dbg_pgno(mp), indx, data ? data->mv_size : 0,
key ? key->mv_size : 0, key ? DKEY(key) : "null"); key ? key->mv_size : 0, DKEY(key));
if (IS_LEAF2(mp)) { if (IS_LEAF2(mp)) {
mdbx_cassert(mc, key); mdbx_cassert(mc, key);
@ -6891,7 +6897,7 @@ static int mdbx_update_key(MDB_cursor *mc, MDB_val *key) {
mp = mc->mc_pg[mc->mc_top]; mp = mc->mc_pg[mc->mc_top];
node = NODEPTR(mp, indx); node = NODEPTR(mp, indx);
ptr = mp->mp_ptrs[indx]; ptr = mp->mp_ptrs[indx];
{ if (MDB_DEBUG) {
MDB_val k2; MDB_val k2;
char kbuf2[DKBUF_MAXKEYSIZE * 2 + 1]; char kbuf2[DKBUF_MAXKEYSIZE * 2 + 1];
k2.mv_data = NODEKEY(node); k2.mv_data = NODEKEY(node);
@ -7658,7 +7664,8 @@ static int mdbx_del0(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data,
int rc, exact = 0; int rc, exact = 0;
DKBUF; DKBUF;
mdbx_debug("====> delete db %u key [%s]", dbi, DKEY(key)); mdbx_debug("====> delete db %u key [%s], data [%s]", dbi, DKEY(key),
DVAL(data));
mdbx_cursor_init(&mc, txn, dbi, &mx); mdbx_cursor_init(&mc, txn, dbi, &mx);