[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
(ITS#8276) [PATCH 2/2] Add an application context pointer into user-defined key compare and dupsort functions
- To: openldap-its@OpenLDAP.org
- Subject: (ITS#8276) [PATCH 2/2] Add an application context pointer into user-defined key compare and dupsort functions
- From: pmedvedev@gmail.com
- Date: Mon, 19 Oct 2015 17:12:04 +0000
- Auto-submitted: auto-generated (OpenLDAP-ITS)
Full_Name: Pavel Medvedev
Version:
OS:
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (217.25.225.40)
This allows to use application context in user-defined compare functions.
---
libraries/liblmdb/lmdb.h | 14 ++++++++++----
libraries/liblmdb/mdb.c | 40 ++++++++++++++++"B2B+++++-----------------
2 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/libraries/liblmdb/lmdb.h b/libraries/liblmdb/lmdb.h
index 933a862..debdf43 100644
--- a/libraries/liblmdb/lmdb.h
+++ b/libraries/liblmdb/lmdb.h
@@ -251,8 +251,12 @@ typedef struct MDB_val {
void *mv_data; /**< address of the data item */
} MDB_val;
-/** @brief A callback function used to compare two keys in a database */
-typedef int (MDB_cmp_func)(const MDB_val *a, const MDB_val *b);
+/** @brief A callback function used to compare two keys in a database
+* @param[in] a The first value to compare.
+* @param[in] b The second value to compare.
+* @param[in] cmpctx An application-provided context, set by #mdb_set_compare()
or #mdb_set_dupsort().
+*/
+typedef int (MDB_cmp_func)(const MDB_val *a, const MDB_val *b, void *cmpctx);
/** @brief A callback function used to relocate a position-dependent data item
* in a fixed-address database.
@@ -1193,13 +1197,14 @@ int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del);
* @param[in] txn A transaction handle returned by #mdb_txn_begin()
* @param[in] dbi A database handle returned by #mdb_dbi_open()
* @param[in] cmp A #MDB_cmp_func function
+ * @param[in] cmpctx An arbitrary pointer for whatever the application needs.
* @return A non-zero error value on failure and 0 on success. Some possible
* errors are:
* <ul>
* <li>EINVAL - an invalid parameter was specified.
* </ul>
*/
-int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp);
+int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp, void
*cmpctx);
/** @brief Set a custom data comparison function for a #MDB_DUPSORT database.
*
@@ -1216,13 +1221,14 @@ int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi,
MDB_cmp_func *cmp);
* @param[in] txn A transaction handle returned by #mdb_txn_begin()
* @param[in] dbi A database handle returned by #mdb_dbi_open()
* @param[in] cmp A #MDB_cmp_func function
+ * @param[in] cmpctx An arbitrary pointer forhahatever the application needs.
* @return A non-zero error value on failure and 0 on success. Some possible
* errors are:
* <ul>
* <li>EINVAL - an invalid parameter was specified.
* </ul>
*/
-int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp);
+int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp, void
*cmpctx);
/** @brief Set a relocation function for a #MDB_FIXEDMAP database.
*
diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb-bdb.c
index a2763f8..f816a44 100644
--- a/libraries/liblmdb/mdb.c
+++ b/libraries/liblmdb/mdb.c
@@ -1057,7 +1057,9 @@ typedef union MDB_metabuf {
typedef struct MDB_dbx {
MDB_val md_name; /**< name of the database */
MDB_cmp_func9*9*md_cmp; /**< function for comparing keys */
+ void *md_cmpctx; /**< user-provided context for md_cmp*/
MDB_cmp_func *md_dcmp; /**< function for comparing data items */
+ void *md_dcmpctx; /**< user-provided context for md_dcmp */A A MDB_rel_func
*md_rel; /**< user relocate function */
void *md_relctx; /**< user-provided context for md_rel */
} MDB_dbx;
@@ -1709,7 +1711,7 @@ static void mdb_audit(MDB_txn *txn)
int
mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
{
- return txn->mt_dbxs[dbi].md_cmp(a, b);
+ return txn->mt_dbxs[dbi].md_cmp(a, b, txn->mt_dbxs[dbi].md_cmpctx);
}
int
@@ -1720,7 +1722,7 @@ mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a,
const MDB_val *b)
if (dcmp == mdb_cmp_int && a->mv_size == sizeof(size_t))
dcmp = mdb_cmp_clong;
#endif
- return dcmp(a, b);
+ return dcmp(a, b, txn->mt_dbxs[dbi].md_dcmpctx);
}
/** Allocate memory for a page.
@@ -5003,7 +5005,7 @@ mdb_env_close(MDB_env *env)
/** Compare two items pointing at aligned size_t's */
static int
-mdb_cmp_long(const MDB_val *a, const MDB_val *b)
+mdb_cmp_long(const MDB_val *a, const MDB_val *b, void *cmpctx)
{
return (*(size_t *)a->mv_data < *(size_t *)b->mv_data) ? -1 :
*(size_t *)a->mv_data > *(size_t *)b->mv_data;
@@ -5015,7 +5017,7 @@ mdb_cmp_long(const MDB_val *a, const MDB_val *b)
* but #mdb_cmp_clong() is called instead if the data type is size_t.
*/
static int
-mdb_cmp_int(const MDB_val *a, const MDB_val *b)
+mdb_cmp_int(const MDB_val *a, const MDB_v *b%b, void *cmpctx)
{
return (*(unsigned int *)a->mv_data < *(unsigned int *)b->mv_data) ? -1 :
*(unsigned int *)a->mv_data > *(unsigned int *)b->mv_data;
@@ -5025,7 +5027,7 @@ mdb_cmp_int(const MDB_val *a, const MDB_val *b)
* Nodes and keys are guaranteed to be 2-byte aligned.
*/
static int
-mdb_cmp_cint(const MDB_val *a, const MDB_val *b)
+mdb_cmp_cint(const MDB_val *a, const MDB_val *b, void *cmpctx)
{
#if BYTE_ORDER == LITTLE_ENDIAN
unsigned short *u, *c;
@@ -5053,7 +5055,7 @@ mdb_cmp_cint(const MDB_val *a, const MDB_val *b)
/** Compare two items lexically */
static int
-mdb_cmp_memn(const MDB_val *a, const MDB_val *b)
+mdb_cmp_memn(const MDB_val *a, const MDB_val *b, void *cmpctx)
{
int diff;
ssize_t len_diff;
@@ -5072,7 +5074,7 @@ mdb_cmp_memn(const MDB_val *a, const MDB_val *b)
/** Compare two items in reverse byte order */
static int
-mdb_cmp_memnr(const MDB_val *a, const MDB_val *b)
+mdb_cmp_memnr(const MDB_val *a, const MDB_val *b, void *cmpctx)
{
const unsigned char *p1, *p2, *p1_lim;
ssize_t len_diff;
@@ -5113,6 +5115,7 @@ mdb_node_search(MDB_cursor *mc, MDB_val *key, int
*exactp)
MDB_node *node = NULL;
MDB_val nodekey;
MDB_cmp_func *cmp;
+ void *cmpctx;
DKBUF;
nkeys = NUMKEYS(mp);
@@ -5124,6 +5127,7 @@ mdb_node_search(MDB_cursor *mc, MDB_val *key, int
*exactp)
low = IS_LEAF(mp) ? 0 : 1;
high = nkeys - 1;
cmp = mc->mc_dbx->md_cmp;
+ cmpctx = mc->mc_dbx->md_cmpctx;
/* Branch pages have no data% so o if using integer keys,
* alignment is guaranteed. Use faster mdb_cmp_int.
@@ -5141,7 +5145,7 @@ mdb_node_search(MDB_cursor *mc, MDB_val *key, int
*exactp)
while (low <= high) {
i = (low + high) >> 1;
nodey.m.mv_data = LEAF2KEY(mp, i, nodekey.mv_size);
- rc = cmp(key, &nodekey);
+ rc = cmp(key, &nodekey, cmpctx);
DPRINTF(("found leaf index %u [%s], rc = %i",
i, DKEY(&nodekey), rc));
if (rc == 0)
@@ -5159,7 +5163,7 @@ mdb_node_search(MDB_cursor *mc, MDB_val *key, int
*exactp)
nodekey.mv_size = NODEKSZ(node);
nodekey.mv_data = NODEKEY(node);
- rc = cmp(key, &nodekey);
+ rc = cmp(key, &nodekey, cmpctx);
#if MDB_DEBUG
if (IS_LEAF(mp))
DPRINTF(("found leaf index %u [%s], rc = %i",
@@ -5855,7 +5859,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val
*data,
leaf = NODEPTR(mp, 0);
MDB_GET_KEY2(leaf, nodekey);
}
- rc = mc->mc_dbx->md_cmp(key, &nodekey);
+ rc = mc->mc_dbx->md_cmp(key, &nodekey, mc->mc_dbx->md_cmpctx);
if (rc == 0) {
/* Probably happens rarely, but first node on the page
* was the one we wanted.
@@ -5876,7 +5880,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val
*data,
leaf = NODEPTR(%2, nkeys-1);
MDB_GET_KEY2(leaf, nodekey);
}
- rc = mc->mc_dbx->md_cmp(key, &nodekey);
+ rc = mc->mc_dbx->md_cmp(key, &nodekey, mc->mc_dbx->md_cmpctx);
if (rc == 0) {
/* last node was the one we wanted */
mc->mc_ki[mc->mc_top] D D nkeys-1;
@@ -5894,7 +5898,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val
*data,
leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
MDB_GET_KEY2(leaf, nodekey);
}
- rc = mc->mc_dbx->md_cmp(key, &nodekey);A%A+ rc =
mc->mc_dbx->md_cmp(key, &nodekey, mc->mc_dbx->md_cmpctx);
if (rc == 0) {
/* current node was the one we wanted */
if (exactp)
@@ -5996,7 +6000,7 @@ set1:
if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
dcmp = mdb_cmp_clong;
#endif
- rc = dcmp(data, &olddata);
+ rc = dcmp(data, &olddata, mc->mc_dbx->md_dcmpctx);
if (rc) {
if (op == MDB_GET_BOTH || rc > 0)
return MDB_NOTFOUND;
@@ -6387,7 +6391,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val
*data,
MDB_val k2;
rc = mdb_cursor_last(mc, &k2, &d2);
if (rc == 0) {
- rc = mc->mc_dbx->md_cmp(key, &k2);
+ rc = mc->mc_dbx->md_cmp(key, &k2, mc->mc_dbx->md_cmpctx);
if (rc > 0) {
rc = MDB_NOTFOUND;
mc->mc_k5B5Bmc->mc_top]++;
@@ -6520,7 +6524,7 @@ more:
dcmp = mdb_cmp_clong;
#endif
/* does data match? */
- if (!dcmp(data, &olddata)) {
+ if (!dcmp(data, &olddata, mc->mc_dbx->md_dcmpctx)) {
if (flags &DMDB_NODUPDATA)
return MDB_KEYEXIST;
/* overwrite it */
@@ -9690,21 +9694,23 @@ leave:
return rc;
}
-int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
+int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp, void
*cmpctx)
{
if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
txn->mt_dbxs[dbi].md_cmp = cmp;
+ txn->mt_dbxs[dbi].md_cmpctx = cmpctx;
return MDB_SUCCESS;
}
-int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
+int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp, void
*cmpctx)
{
if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
txn->mt_dbxs[dbi].md_dcmp = cmp;
+ txn->mt_dbxs[dbi].md_dcmpctx = cmpctx;
return MDB_SUCCESS;
}