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;
 }
 

Reply via email to