Skip to content
This repository has been archived by the owner on Sep 22, 2022. It is now read-only.

MDBX_SET_UPPERBOUND #251

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
*.[ao]
*.err
*.log
*.bak
*.exe
*.gcda
Expand Down
7 changes: 6 additions & 1 deletion mdbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,12 @@ enum MDBX_cursor_op {
* 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
MDBX_SET_LOWERBOUND,

/** Position at first key-value pair lesser than or equal to specified,
* return same as MDBX_SET_LOWERBOUND
*/
MDBX_SET_UPPERBOUND
};
#ifndef __cplusplus
/** \ingroup c_cursors */
Expand Down
44 changes: 44 additions & 0 deletions src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -14542,6 +14542,50 @@ int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
rc = MDBX_RESULT_TRUE;
break;
}
case MDBX_SET_UPPERBOUND: {
if (unlikely(key == NULL || data == NULL))
return MDBX_EINVAL;
MDBX_val save_data = *data;
struct cursor_set_result csr =
mdbx_cursor_set(mc, key, data, MDBX_SET_RANGE);
rc = csr.err;
if (rc == MDBX_NOTFOUND) {
rc = mdbx_cursor_last(mc, key, data);
if (rc == MDBX_SUCCESS) {
rc = MDBX_RESULT_TRUE;
}
} else if ( rc == MDBX_SUCCESS ){
if (csr.exact) {
if (mc->mc_xcursor) {
mc->mc_flags &= ~C_DEL;
csr.exact = false;
if (!save_data.iov_base && (mc->mc_db->md_flags & MDBX_DUPFIXED)) {
mfunc = mdbx_cursor_last;
goto mmove;
} else if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) {
*data = save_data;
csr = mdbx_cursor_set(&mc->mc_xcursor->mx_cursor, data, NULL,
MDBX_SET_RANGE);
rc = csr.err;
if (rc == MDBX_NOTFOUND) {
mdbx_cassert(mc, !csr.exact);
rc = mdbx_cursor_prev(mc, key, data, MDBX_PREV_NODUP);
}
} else {
int cmp = mc->mc_dbx->md_dcmp(&save_data, data);
csr.exact = (cmp == 0);
if (cmp > 0)
rc = mdbx_cursor_prev(mc, key, data, MDBX_PREV_NODUP);
}
}
} else {
rc = mdbx_cursor_prev(mc, key, data, MDBX_PREV);
}
if (rc == MDBX_SUCCESS && !csr.exact)
rc = MDBX_RESULT_TRUE;
}
break;
}
default:
mdbx_debug("unhandled/unimplemented cursor operation %u", op);
return MDBX_EINVAL;
Expand Down