mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-30 22:47:16 +08:00
mdbx: add MDBX_SET_LOWERBOUND
for mdbx_cursor_get()
.
Change-Id: I3638fdd10be8dfe128c43b465e9ca71f89175b3e
This commit is contained in:
parent
9ea6922a2f
commit
5e02e7fb56
15
mdbx.h
15
mdbx.h
@ -1505,7 +1505,20 @@ enum MDBX_cursor_op {
|
|||||||
|
|
||||||
/** \ref MDBX_DUPFIXED -only: Position at previous page and return up to
|
/** \ref MDBX_DUPFIXED -only: Position at previous page and return up to
|
||||||
* a page of duplicate data items. */
|
* a page of duplicate data items. */
|
||||||
MDBX_PREV_MULTIPLE
|
MDBX_PREV_MULTIPLE,
|
||||||
|
|
||||||
|
/** Position at first key-value pair greater than or equal to specified,
|
||||||
|
* return both key and data, and the return code depends on a exact match.
|
||||||
|
*
|
||||||
|
* For non DUPSORT-ed collections this work the same to \ref MDBX_SET_RANGE,
|
||||||
|
* but returns \ref MDBX_SUCCESS if key found exactly and
|
||||||
|
* \ref MDBX_RESULT_TRUE if greater key was found.
|
||||||
|
*
|
||||||
|
* For DUPSORT-ed a data value is taken into account for duplicates,
|
||||||
|
* i.e. for a pairs/tuples of a key and an each data value of duplicates.
|
||||||
|
* Returns \ref MDBX_SUCCESS if key-value pair found exactly and
|
||||||
|
* \ref MDBX_RESULT_TRUE if the next pair was returned. */
|
||||||
|
MDBX_SET_LOWERBOUND
|
||||||
};
|
};
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
/** \ingroup c_cursors */
|
/** \ingroup c_cursors */
|
||||||
|
27
src/core.c
27
src/core.c
@ -12575,6 +12575,33 @@ int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
case MDBX_LAST_DUP:
|
case MDBX_LAST_DUP:
|
||||||
mfunc = mdbx_cursor_last;
|
mfunc = mdbx_cursor_last;
|
||||||
goto mmove;
|
goto mmove;
|
||||||
|
case MDBX_SET_LOWERBOUND: {
|
||||||
|
if (unlikely(key == NULL || data == NULL))
|
||||||
|
return MDBX_EINVAL;
|
||||||
|
MDBX_val save_data = *data;
|
||||||
|
rc = mdbx_cursor_set(mc, key, data, MDBX_SET_RANGE, &exact);
|
||||||
|
if (rc == MDBX_SUCCESS && exact && mc->mc_xcursor) {
|
||||||
|
mc->mc_flags &= ~C_DEL;
|
||||||
|
if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) {
|
||||||
|
*data = save_data;
|
||||||
|
exact = 0;
|
||||||
|
rc = mdbx_cursor_set(&mc->mc_xcursor->mx_cursor, data, NULL,
|
||||||
|
MDBX_SET_RANGE, &exact);
|
||||||
|
if (rc == MDBX_NOTFOUND) {
|
||||||
|
mdbx_cassert(mc, !exact);
|
||||||
|
rc = mdbx_cursor_next(mc, key, data, MDBX_NEXT_NODUP);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int cmp = mc->mc_dbx->md_dcmp(&save_data, data);
|
||||||
|
exact = (cmp == 0);
|
||||||
|
if (cmp > 0)
|
||||||
|
rc = mdbx_cursor_next(mc, key, data, MDBX_NEXT_NODUP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rc == MDBX_SUCCESS && !exact)
|
||||||
|
rc = MDBX_RESULT_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
mdbx_debug("unhandled/unimplemented cursor operation %u", op);
|
mdbx_debug("unhandled/unimplemented cursor operation %u", op);
|
||||||
return MDBX_EINVAL;
|
return MDBX_EINVAL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user