]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
ITS#7736 fix regression in ITS#7733 patch
[openldap] / libraries / liblmdb / mdb.c
index e33b383af67ca92ae0da5895c49af67e3851930b..9ade333ed951e459ce623b1c1ca0b29169494cf9 100644 (file)
@@ -67,7 +67,6 @@
 
 #if defined(__APPLE__) || defined (BSD)
 # define MDB_USE_POSIX_SEM     1
-# define MDB_USE_HASH          1
 # define MDB_FDATASYNC         fsync
 #elif defined(ANDROID)
 # define MDB_FDATASYNC         fsync
@@ -76,6 +75,7 @@
 #ifndef _WIN32
 #include <pthread.h>
 #ifdef MDB_USE_POSIX_SEM
+# define MDB_USE_HASH          1
 #include <semaphore.h>
 #endif
 #endif
@@ -3283,14 +3283,17 @@ mdb_env_map(MDB_env *env, void *addr, int newsize)
                env->me_map = NULL;
                return ErrCode();
        }
-       /* Turn off readahead. It's harmful when the DB is larger than RAM. */
+
+       if (flags & MDB_NORDAHEAD) {
+               /* Turn off readahead. It's harmful when the DB is larger than RAM. */
 #ifdef MADV_RANDOM
-       madvise(env->me_map, env->me_mapsize, MADV_RANDOM);
+               madvise(env->me_map, env->me_mapsize, MADV_RANDOM);
 #else
 #ifdef POSIX_MADV_RANDOM
-       posix_madvise(env->me_map, env->me_mapsize, POSIX_MADV_RANDOM);
+               posix_madvise(env->me_map, env->me_mapsize, POSIX_MADV_RANDOM);
 #endif /* POSIX_MADV_RANDOM */
 #endif /* MADV_RANDOM */
+       }
 #endif /* _WIN32 */
 
        /* Can happen because the address argument to mmap() is just a
@@ -3926,7 +3929,7 @@ fail:
         *      environment and re-opening it with the new flags.
         */
 #define        CHANGEABLE      (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC)
-#define        CHANGELESS      (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY|MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK)
+#define        CHANGELESS      (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY|MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD)
 
 int
 mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
@@ -5417,8 +5420,9 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
                        rc = EINVAL;
                } else {
                        MDB_page *mp = mc->mc_pg[mc->mc_top];
-                       if (!NUMKEYS(mp)) {
-                               mc->mc_ki[mc->mc_top] = 0;
+                       int nkeys = NUMKEYS(mp);
+                       if (!nkeys || mc->mc_ki[mc->mc_top] >= nkeys) {
+                               mc->mc_ki[mc->mc_top] = nkeys;
                                rc = MDB_NOTFOUND;
                                break;
                        }
@@ -6066,6 +6070,7 @@ int
 mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
 {
        MDB_node        *leaf;
+       MDB_page        *mp;
        int rc;
 
        if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
@@ -6074,6 +6079,9 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
        if (!(mc->mc_flags & C_INITIALIZED))
                return EINVAL;
 
+       if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top]))
+               return MDB_NOTFOUND;
+
        if (!(flags & MDB_NOSPILL) && (rc = mdb_page_spill(mc, NULL, NULL)))
                return rc;
 
@@ -6081,9 +6089,10 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
        if (rc)
                return rc;
 
-       leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
+       mp = mc->mc_pg[mc->mc_top];
+       leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
 
-       if (!IS_LEAF2(mc->mc_pg[mc->mc_top]) && F_ISSET(leaf->mn_flags, F_DUPDATA)) {
+       if (!IS_LEAF2(mp) && F_ISSET(leaf->mn_flags, F_DUPDATA)) {
                if (!(flags & MDB_NODUPDATA)) {
                        if (!F_ISSET(leaf->mn_flags, F_SUBDATA)) {
                                mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
@@ -6098,13 +6107,13 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
                                } else {
                                        MDB_cursor *m2;
                                        /* shrink fake page */
-                                       mdb_node_shrink(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
-                                       leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
+                                       mdb_node_shrink(mp, mc->mc_ki[mc->mc_top]);
+                                       leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
                                        mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
                                        /* fix other sub-DB cursors pointed at this fake page */
                                        for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) {
                                                if (m2 == mc || m2->mc_snum < mc->mc_snum) continue;
-                                               if (m2->mc_pg[mc->mc_top] == mc->mc_pg[mc->mc_top] &&
+                                               if (m2->mc_pg[mc->mc_top] == mp &&
                                                        m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top])
                                                        m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
                                        }
@@ -7379,13 +7388,13 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
        int              rc = MDB_SUCCESS, new_root = 0, did_split = 0;
        indx_t           newindx;
        pgno_t           pgno = 0;
-       unsigned int     i, j, split_indx, nkeys, pmax;
+       int      i, j, split_indx, nkeys, pmax;
        MDB_env         *env = mc->mc_txn->mt_env;
        MDB_node        *node;
        MDB_val  sepkey, rkey, xdata, *rdata = &xdata;
-       MDB_page        *copy;
+       MDB_page        *copy = NULL;
        MDB_page        *mp, *rp, *pp;
-       unsigned int ptop;
+       int ptop;
        MDB_cursor      mn;
        DKBUF;
 
@@ -7487,8 +7496,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
                                mc->mc_pg[mc->mc_top] = rp;
                        }
                } else {
-                       unsigned int psize, nsize;
-                       int k;
+                       int psize, nsize, k;
                        /* Maximum free space in an empty page */
                        pmax = env->me_psize - PAGEHDRSZ;
                        if (IS_LEAF(mp))
@@ -7815,6 +7823,16 @@ mdb_env_get_path(MDB_env *env, const char **arg)
        return MDB_SUCCESS;
 }
 
+int
+mdb_env_get_fd(MDB_env *env, mdb_filehandle_t *arg)
+{
+       if (!env || !arg)
+               return EINVAL;
+
+       *arg = env->me_fd;
+       return MDB_SUCCESS;
+}
+
 /** Common code for #mdb_stat() and #mdb_env_stat().
  * @param[in] env the environment to operate in.
  * @param[in] db the #MDB_db record containing the stats to return.