]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
ITS#8582 MDB_LOCK_VERSION = 2 due to format change
[openldap] / libraries / liblmdb / mdb.c
index bb2068fe8de36e2652f77f1458132b507c819045..21f50f2a880778f7587db20fe36c2db248e309d3 100644 (file)
@@ -5,7 +5,7 @@
  *     BerkeleyDB API, but much simplified.
  */
 /*
- * Copyright 2011-2016 Howard Chu, Symas Corp.
+ * Copyright 2011-2017 Howard Chu, Symas Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -620,7 +620,7 @@ static txnid_t mdb_debug_start;
        /**     The version number for a database's datafile format. */
 #define MDB_DATA_VERSION        ((MDB_DEVEL) ? 999 : 1)
        /**     The version number for a database's lockfile format. */
-#define MDB_LOCK_VERSION        ((MDB_DEVEL) ? 999 : 1)
+#define MDB_LOCK_VERSION        ((MDB_DEVEL) ? 999 : 2)
 
        /**     @brief The max size of a key we can write, or 0 for computed max.
         *
@@ -809,6 +809,16 @@ typedef struct MDB_txbody {
        uint32_t        mtb_magic;
                /** Format of this lock file. Must be set to #MDB_LOCK_FORMAT. */
        uint32_t        mtb_format;
+               /**     The ID of the last transaction committed to the database.
+                *      This is recorded here only for convenience; the value can always
+                *      be determined by reading the main database meta pages.
+                */
+       volatile txnid_t                mtb_txnid;
+               /** The number of slots that have been used in the reader table.
+                *      This always records the maximum count, it is not decremented
+                *      when readers release their slots.
+                */
+       volatile unsigned       mtb_numreaders;
 #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM)
        char    mtb_rmname[MNAME_LEN];
 #elif defined(MDB_USE_SYSV_SEM)
@@ -820,16 +830,6 @@ typedef struct MDB_txbody {
                 */
        mdb_mutex_t     mtb_rmutex;
 #endif
-               /**     The ID of the last transaction committed to the database.
-                *      This is recorded here only for convenience; the value can always
-                *      be determined by reading the main database meta pages.
-                */
-       volatile txnid_t                mtb_txnid;
-               /** The number of slots that have been used in the reader table.
-                *      This always records the maximum count, it is not decremented
-                *      when readers release their slots.
-                */
-       volatile unsigned       mtb_numreaders;
 } MDB_txbody;
 
        /** The actual reader table definition. */
@@ -2006,13 +2006,15 @@ static void
 mdb_cursor_unref(MDB_cursor *mc)
 {
        int i;
-       if (!mc->mc_snum || !mc->mc_pg[0] || IS_SUBP(mc->mc_pg[0]))
-               return;
-       for (i=0; i<mc->mc_snum; i++)
-               mdb_page_unref(mc->mc_txn, mc->mc_pg[i]);
-       if (mc->mc_ovpg) {
-               mdb_page_unref(mc->mc_txn, mc->mc_ovpg);
-               mc->mc_ovpg = 0;
+       if (mc->mc_txn->mt_rpages[0].mid) {
+               if (!mc->mc_snum || !mc->mc_pg[0] || IS_SUBP(mc->mc_pg[0]))
+                       return;
+               for (i=0; i<mc->mc_snum; i++)
+                       mdb_page_unref(mc->mc_txn, mc->mc_pg[i]);
+               if (mc->mc_ovpg) {
+                       mdb_page_unref(mc->mc_txn, mc->mc_ovpg);
+                       mc->mc_ovpg = 0;
+               }
        }
        mc->mc_snum = mc->mc_top = 0;
        mc->mc_pg[0] = NULL;
@@ -6604,8 +6606,11 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
 
        mp = mc->mc_pg[mc->mc_top];
 
-       if ((mc->mc_flags & C_EOF) && mc->mc_ki[mc->mc_top] >= NUMKEYS(mp)-1)
-               return MDB_NOTFOUND;
+       if (mc->mc_flags & C_EOF) {
+               if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mp)-1)
+                       return MDB_NOTFOUND;
+               mc->mc_flags ^= C_EOF;
+       }
 
        if (mc->mc_db->md_flags & MDB_DUPSORT) {
                leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
@@ -8436,9 +8441,15 @@ mdb_cursor_count(MDB_cursor *mc, mdb_size_t *countp)
        if (!(mc->mc_flags & C_INITIALIZED))
                return EINVAL;
 
-       if (!mc->mc_snum || (mc->mc_flags & C_EOF))
+       if (!mc->mc_snum)
                return MDB_NOTFOUND;
 
+       if (mc->mc_flags & C_EOF) {
+               if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top]))
+                       return MDB_NOTFOUND;
+               mc->mc_flags ^= C_EOF;
+       }
+
        leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
        if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
                *countp = 1;