]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
ITS#7829 more for prev commit
[openldap] / libraries / liblmdb / mdb.c
index 0e5c3618874d083c67e643f8843fe6433abe7079..10a8358449d2333086daf00579f5b7dcc36fbc12 100644 (file)
@@ -2770,23 +2770,20 @@ mdb_freelist_save(MDB_txn *txn)
                mop += mop_len;
                rc = mdb_cursor_first(&mc, &key, &data);
                for (; !rc; rc = mdb_cursor_next(&mc, &key, &data, MDB_NEXT)) {
-                       unsigned flags = MDB_CURRENT;
                        txnid_t id = *(txnid_t *)key.mv_data;
                        ssize_t len = (ssize_t)(data.mv_size / sizeof(MDB_ID)) - 1;
                        MDB_ID save;
 
                        mdb_tassert(txn, len >= 0 && id <= env->me_pglast);
+                       key.mv_data = &id;
                        if (len > mop_len) {
                                len = mop_len;
                                data.mv_size = (len + 1) * sizeof(MDB_ID);
-                               /* Drop MDB_CURRENT when changing the data size */
-                               key.mv_data = &id;
-                               flags = 0;
                        }
                        data.mv_data = mop -= len;
                        save = mop[0];
                        mop[0] = len;
-                       rc = mdb_cursor_put(&mc, &key, &data, flags);
+                       rc = mdb_cursor_put(&mc, &key, &data, MDB_CURRENT);
                        mop[0] = save;
                        if (rc || !(mop_len -= len))
                                break;
@@ -5807,7 +5804,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
        unsigned int nflags;
        DKBUF;
 
-       if (mc == NULL)
+       if (mc == NULL || key == NULL)
                return EINVAL;
 
        env = mc->mc_txn->mt_env;
@@ -5828,16 +5825,8 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
        if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
                return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
 
-       if (flags != MDB_CURRENT) {
-               if (key == NULL)
-                       return EINVAL;
-               if (key->mv_size-1 >= ENV_MAXKEY(env))
-                       return MDB_BAD_VALSIZE;
-       } else {
-               /* Ignore key except in sub-cursor, where key holds the data */
-               if (!(mc->mc_flags & C_SUB))
-                       key = NULL;
-       }
+       if (flags != MDB_CURRENT && key->mv_size-1 >= ENV_MAXKEY(env))
+               return MDB_BAD_VALSIZE;
 
 #if SIZE_MAX > MAXDATASIZE
        if (data->mv_size > ((mc->mc_db->md_flags & MDB_DUPSORT) ? ENV_MAXKEY(env) : MAXDATASIZE))
@@ -6168,7 +6157,6 @@ current:
                        goto done;
                }
                mdb_node_del(mc, 0);
-               mc->mc_db->md_entries--;
        }
 
        rdata = data;
@@ -6261,7 +6249,7 @@ put_sub:
                /* sub-writes might have failed so check rc again.
                 * Don't increment count if we just replaced an existing item.
                 */
-               if (!rc && !(flags & MDB_CURRENT))
+               if (!rc && insert)
                        mc->mc_db->md_entries++;
                if (flags & MDB_MULTIPLE) {
                        if (!rc) {
@@ -7335,6 +7323,7 @@ mdb_rebalance(MDB_cursor *mc)
        int rc;
        unsigned int ptop, minkeys;
        MDB_cursor      mn;
+       indx_t oldki;
 
        minkeys = 1 + (IS_BRANCH(mc->mc_pg[mc->mc_top]));
        DPRINTF(("rebalancing %s page %"Z"u (has %u keys, %.1f%% full)",
@@ -7439,6 +7428,7 @@ mdb_rebalance(MDB_cursor *mc)
        mdb_cursor_copy(mc, &mn);
        mn.mc_xcursor = NULL;
 
+       oldki = mc->mc_ki[mc->mc_top];
        if (mc->mc_ki[ptop] == 0) {
                /* We're the leftmost leaf in our parent.
                 */
@@ -7472,17 +7462,25 @@ mdb_rebalance(MDB_cursor *mc)
         * (A branch page must never have less than 2 keys.)
         */
        minkeys = 1 + (IS_BRANCH(mn.mc_pg[mn.mc_top]));
-       if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= FILL_THRESHOLD && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys)
-               return mdb_node_move(&mn, mc);
-       else {
-               if (mc->mc_ki[ptop] == 0)
+       if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= FILL_THRESHOLD && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys) {
+               rc = mdb_node_move(&mn, mc);
+               if (mc->mc_ki[ptop] == 0) {
+                       mc->mc_ki[mc->mc_top] = oldki;
+               } else {
+                       mc->mc_ki[mc->mc_top] = oldki + 1;
+               }
+       } else {
+               if (mc->mc_ki[ptop] == 0) {
                        rc = mdb_page_merge(&mn, mc);
-               else {
+                       mc->mc_ki[mc->mc_top] = oldki;
+               } else {
+                       unsigned int nkeys = NUMKEYS(mn.mc_pg[mn.mc_top]);
                        mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1;
                        rc = mdb_page_merge(mc, &mn);
-                       mdb_cursor_copy(&mn, mc);
+                       mc->mc_pg[mc->mc_top] = mn.mc_pg[mn.mc_top];
+                       mc->mc_ki[mc->mc_top] = oldki + nkeys;
                }
-               mc->mc_flags &= ~(C_INITIALIZED|C_EOF);
+               mc->mc_flags &= ~C_EOF;
        }
        return rc;
 }