mdbx: explicit overwrite support for mdbx_put().

This commit is contained in:
Leo Yuriev 2016-12-06 20:08:08 +03:00
parent 787aeea162
commit f9f132671c
2 changed files with 20 additions and 4 deletions

3
lmdb.h
View File

@ -349,7 +349,8 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel
* For mdb_cursor_del: remove all duplicate data items.
*/
#define MDB_NODUPDATA 0x20
/** For mdb_cursor_put: overwrite the current key/data pair */
/** For mdb_cursor_put: overwrite the current key/data pair
* MDBX allows this flag for mdb_put() for explicit overwrite/update without insertion. */
#define MDB_CURRENT 0x40
/** For put: Just reserve space for data, don't copy it. Return a
* pointer to the reserved space.

21
mdb.c
View File

@ -9032,7 +9032,6 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
{
MDB_cursor mc;
MDB_xcursor mx;
int rc;
if (unlikely(!key || !data || !txn))
return EINVAL;
@ -9043,17 +9042,33 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
if (unlikely(!TXN_DBI_EXIST(txn, dbi, DB_USRVALID)))
return EINVAL;
if (unlikely(flags & ~(MDB_NOOVERWRITE|MDB_NODUPDATA|MDB_RESERVE|MDB_APPEND|MDB_APPENDDUP)))
if (unlikely(flags & ~(MDB_NOOVERWRITE|MDB_NODUPDATA|MDB_RESERVE|MDB_APPEND|MDB_APPENDDUP
/* LY: MDB_CURRENT indicates explicit overwrite (update) for MDBX */
| (MDBX_MODE_ENABLED ? MDB_CURRENT : 0))))
return EINVAL;
if (unlikely(txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED)))
return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
#if MDBX_MODE_ENABLED
/* LY: allows update (explicit overwrite) only for unique keys */
if ((flags & MDB_CURRENT) && (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT))
return EINVAL;
#endif /* MDBX_MODE_ENABLED */
mdb_cursor_init(&mc, txn, dbi, &mx);
mc.mc_next = txn->mt_cursors[dbi];
txn->mt_cursors[dbi] = &mc;
rc = mdb_cursor_put(&mc, key, data, flags);
int rc = MDB_SUCCESS;
#if MDBX_MODE_ENABLED
/* LY: support for update (explicit overwrite) */
if (flags & MDB_CURRENT)
rc = mdb_cursor_get(&mc, key, NULL, MDB_SET);
#endif /* MDBX_MODE_ENABLED */
if (likely(rc == MDB_SUCCESS))
rc = mdb_cursor_put(&mc, key, data, flags);
txn->mt_cursors[dbi] = mc.mc_next;
return rc;
}