]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
ITS#8311 add comment
[openldap] / libraries / liblmdb / mdb.c
index 98c73830e03dd0ec7c65c43421585c1501d852a7..fc0340c51e2e33fe22eb62adc3b5b779e13e9588 100644 (file)
@@ -238,7 +238,9 @@ typedef SSIZE_T     ssize_t;
 #define MDB_OWNERDEAD  EOWNERDEAD      /**< #LOCK_MUTEX0() result if dead owner */
 #endif
 
-
+#ifdef __GLIBC__
+#define        GLIBC_VER       ((__GLIBC__ << 16 )| __GLIBC_MINOR__)
+#endif
 /** Some platforms define the EOWNERDEAD error code
  * even though they don't support Robust Mutexes.
  * Compile with -DMDB_USE_ROBUST=0, or use some other
@@ -248,12 +250,19 @@ typedef SSIZE_T   ssize_t;
  * either.)
  */
 #ifndef MDB_USE_ROBUST
-/* Android currently lacks Robust Mutex support */
-#if defined(ANDROID) && defined(MDB_USE_POSIX_MUTEX) && !defined(MDB_USE_ROBUST)
-#define MDB_USE_ROBUST 0
-#else
-#define MDB_USE_ROBUST 1
-#endif
+/* Android currently lacks Robust Mutex support. So does glibc < 2.4. */
+# if defined(MDB_USE_POSIX_MUTEX) && (defined(ANDROID) || \
+       (defined(__GLIBC__) && GLIBC_VER < 0x020004))
+#  define MDB_USE_ROBUST       0
+# else
+#  define MDB_USE_ROBUST       1
+/* glibc < 2.10 only provided _np API */
+#  if defined(__GLIBC__) && GLIBC_VER < 0x02000a
+#   define PTHREAD_MUTEX_ROBUST        PTHREAD_MUTEX_ROBUST_NP
+#   define pthread_mutexattr_setrobust(attr, flag)     pthread_mutexattr_setrobust_np(attr, flag)
+#   define pthread_mutex_consistent(mutex)     pthread_mutex_consistent_np(mutex)
+#  endif
+# endif
 #endif /* MDB_USE_ROBUST */
 
 #if defined(MDB_OWNERDEAD) && MDB_USE_ROBUST
@@ -394,10 +403,13 @@ static int mdb_mutex_failed(MDB_env *env, mdb_mutexref_t mutex, int rc);
  *
  *     @note If O_DSYNC is undefined but exists in /usr/include,
  * preferably set some compiler flag to get the definition.
- * Otherwise compile with the less efficient -DMDB_DSYNC=O_SYNC.
  */
 #ifndef MDB_DSYNC
+# ifdef O_DSYNC
 # define MDB_DSYNC     O_DSYNC
+# else
+# define MDB_DSYNC     O_SYNC
+# endif
 #endif
 #endif
 
@@ -6379,16 +6391,18 @@ fix_parent:
                         * update branch key if there is a parent page
                         */
                        if (mc->mc_top && !mc->mc_ki[mc->mc_top]) {
-                               unsigned short top = mc->mc_top;
+                               unsigned short dtop = 1;
                                mc->mc_top--;
                                /* slot 0 is always an empty key, find real slot */
-                               while (mc->mc_top && !mc->mc_ki[mc->mc_top])
+                               while (mc->mc_top && !mc->mc_ki[mc->mc_top]) {
                                        mc->mc_top--;
+                                       dtop++;
+                               }
                                if (mc->mc_ki[mc->mc_top])
                                        rc2 = mdb_update_key(mc, key);
                                else
                                        rc2 = MDB_SUCCESS;
-                               mc->mc_top top;
+                               mc->mc_top += dtop;
                                if (rc2)
                                        return rc2;
                        }
@@ -7961,9 +7975,9 @@ mdb_rebalance(MDB_cursor *mc)
                                                m3 = &m2->mc_xcursor->mx_cursor;
                                        else
                                                m3 = m2;
-                                       if (m3 == mc || m3->mc_snum < mc->mc_snum) continue;
+                                       if (m3 == mc) continue;
                                        if (m3->mc_pg[0] == mp) {
-                                               for (i=0; i<m3->mc_snum; i++) {
+                                               for (i=0; i<mc->mc_db->md_depth; i++) {
                                                        m3->mc_pg[i] = m3->mc_pg[i+1];
                                                        m3->mc_ki[i] = m3->mc_ki[i+1];
                                                }
@@ -8237,12 +8251,19 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
        rp->mp_pad = mp->mp_pad;
        DPRINTF(("new right sibling: page %"Z"u", rp->mp_pgno));
 
-       if (mc->mc_snum < 2) {
+       /* Usually when splitting the root page, the cursor
+        * height is 1. But when called from mdb_update_key,
+        * the cursor height may be greater because it walks
+        * up the stack while finding the branch slot to update.
+        */
+       if (mc->mc_top < 1) {
                if ((rc = mdb_page_new(mc, P_BRANCH, 1, &pp)))
                        goto done;
                /* shift current top to make room for new parent */
-               mc->mc_pg[1] = mc->mc_pg[0];
-               mc->mc_ki[1] = mc->mc_ki[0];
+               for (i=mc->mc_snum; i>0; i--) {
+                       mc->mc_pg[i] = mc->mc_pg[i-1];
+                       mc->mc_ki[i] = mc->mc_ki[i-1];
+               }
                mc->mc_pg[0] = pp;
                mc->mc_ki[0] = 0;
                mc->mc_db->md_root = pp->mp_pgno;
@@ -8258,8 +8279,8 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
                        mc->mc_db->md_depth--;
                        goto done;
                }
-               mc->mc_snum = 2;
-               mc->mc_top = 1;
+               mc->mc_snum++;
+               mc->mc_top++;
                ptop = 0;
        } else {
                ptop = mc->mc_top-1;