]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
ITS#7992 cleanup
[openldap] / libraries / liblmdb / mdb.c
index 22c5d301863eea26ab7cc4893207ce56cc38a0d9..fa0c9e5b9ccd1f2ba6df9daba40bcf3258eee3aa 100644 (file)
@@ -256,8 +256,8 @@ typedef SSIZE_T     ssize_t;
 #  define MDB_USE_ROBUST       0
 # else
 #  define MDB_USE_ROBUST       1
-/* glibc < 2.10 only provided _np API */
-#  if defined(__GLIBC__) && GLIBC_VER < 0x02000a
+/* glibc < 2.12 only provided _np API */
+#  if defined(__GLIBC__) && GLIBC_VER < 0x02000c
 #   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)
@@ -1613,6 +1613,13 @@ mdb_cursor_chk(MDB_cursor *mc)
        }
        if (mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i]))
                printf("ack!\n");
+       if (mc->mc_xcursor && (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) {
+               node = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
+               if (((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) &&
+                       mc->mc_xcursor->mx_cursor.mc_pg[0] != NODEDATA(node)) {
+                       printf("blah!\n");
+               }
+       }
 }
 #endif
 
@@ -2423,10 +2430,10 @@ done:
                                m2->mc_pg[mc->mc_top] = np;
                                if ((mc->mc_db->md_flags & MDB_DUPSORT) &&
                                        IS_LEAF(np) &&
-                                       m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top])
+                                       (m2->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED))
                                {
-                                       MDB_node *leaf = NODEPTR(np, mc->mc_ki[mc->mc_top]);
-                                       if (!(leaf->mn_flags & F_SUBDATA))
+                                       MDB_node *leaf = NODEPTR(np, m2->mc_ki[mc->mc_top]);
+                                       if ((leaf->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA)
                                                m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
                                }
                        }
@@ -4463,7 +4470,9 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
 
 #ifdef _WIN32
        wchar_t *wlpath;
-       utf8_to_utf16(lpath, -1, &wlpath, NULL);
+       rc = utf8_to_utf16(lpath, -1, &wlpath, NULL);
+       if (rc)
+               return rc;
        env->me_lfd = CreateFileW(wlpath, GENERIC_READ|GENERIC_WRITE,
                FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
                FILE_ATTRIBUTE_NORMAL, NULL);
@@ -4751,7 +4760,9 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
                len = OPEN_ALWAYS;
        }
        mode = FILE_ATTRIBUTE_NORMAL;
-       utf8_to_utf16(dpath, -1, &wpath, NULL);
+       rc = utf8_to_utf16(dpath, -1, &wpath, NULL);
+       if (rc)
+               goto leave;
        env->me_fd = CreateFileW(wpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE,
                NULL, len, mode, NULL);
        free(wpath);
@@ -4783,7 +4794,9 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
                         */
 #ifdef _WIN32
                        len = OPEN_EXISTING;
-                       utf8_to_utf16(dpath, -1, &wpath, NULL);
+                       rc = utf8_to_utf16(dpath, -1, &wpath, NULL);
+                       if (rc)
+                               goto leave;
                        env->me_mfd = CreateFileW(wpath, oflags,
                                FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len,
                                mode | FILE_FLAG_WRITE_THROUGH, NULL);
@@ -6098,8 +6111,6 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
                                MDB_GET_KEY(leaf, key);
                                if (data) {
                                        if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
-                                               if (mc->mc_flags & C_DEL)
-                                                       mdb_xcursor_init1(mc, leaf);
                                                rc = mdb_cursor_get(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_GET_CURRENT);
                                        } else {
                                                rc = mdb_node_read(mc->mc_txn, leaf, data);
@@ -6678,7 +6689,7 @@ new_sub:
        } else {
                /* There is room already in this leaf page. */
                rc = mdb_node_add(mc, mc->mc_ki[mc->mc_top], key, rdata, 0, nflags);
-               if (rc == 0 && insert_key) {
+               if (rc == 0) {
                        /* Adjust other cursors pointing to mp */
                        MDB_cursor *m2, *m3;
                        MDB_dbi dbi = mc->mc_dbi;
@@ -6690,10 +6701,15 @@ new_sub:
                                        m3 = &m2->mc_xcursor->mx_cursor;
                                else
                                        m3 = m2;
-                               if (m3 == mc || m3->mc_snum < mc->mc_snum) continue;
-                               if (m3->mc_pg[i] == mp && m3->mc_ki[i] >= mc->mc_ki[i]) {
+                               if (m3 == mc || m3->mc_snum < mc->mc_snum || m3->mc_pg[i] != mp) continue;
+                               if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) {
                                        m3->mc_ki[i]++;
                                }
+                               if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) {
+                                       MDB_node *n2 = NODEPTR(mp, m3->mc_ki[i]);
+                                       if ((n2->mn_flags & (F_SUBDATA|F_DUPDATA)) == F_DUPDATA)
+                                               m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2);
+                               }
                        }
                }
        }
@@ -6862,7 +6878,6 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
                                        }
                                }
                                mc->mc_db->md_entries--;
-                               mc->mc_flags |= C_DEL;
                                return rc;
                        } else {
                                mc->mc_xcursor->mx_cursor.mc_flags &= ~C_INITIALIZED;
@@ -7623,6 +7638,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft)
                data.mv_size = NODEDSZ(srcnode);
                data.mv_data = NODEDATA(srcnode);
        }
+       mn.mc_xcursor = NULL;
        if (IS_BRANCH(cdst->mc_pg[cdst->mc_top]) && cdst->mc_ki[cdst->mc_top] == 0) {
                unsigned int snum = cdst->mc_snum;
                MDB_node *s2;
@@ -7694,6 +7710,12 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft)
                                        m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top];
                                        m3->mc_ki[csrc->mc_top-1]++;
                                }
+                               if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) &&
+                                       IS_LEAF(mps)) {
+                                       MDB_node *node = NODEPTR(m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]);
+                                       if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA)
+                                               m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node);
+                               }
                        }
                } else
                /* Adding on the right, bump others down */
@@ -7714,6 +7736,12 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft)
                                        } else {
                                                m3->mc_ki[csrc->mc_top]--;
                                        }
+                                       if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) &&
+                                               IS_LEAF(mps)) {
+                                               MDB_node *node = NODEPTR(m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]);
+                                               if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA)
+                                                       m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node);
+                                       }
                                }
                        }
                }
@@ -7838,6 +7866,7 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst)
                                MDB_cursor mn;
                                MDB_node *s2;
                                mdb_cursor_copy(csrc, &mn);
+                               mn.mc_xcursor = NULL;
                                /* must find the lowest key below src */
                                rc = mdb_page_search_lowest(&mn);
                                if (rc)
@@ -7913,6 +7942,12 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst)
                                m3->mc_ki[top-1] > csrc->mc_ki[top-1]) {
                                m3->mc_ki[top-1]--;
                        }
+                       if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) &&
+                               IS_LEAF(psrc)) {
+                               MDB_node *node = NODEPTR(m3->mc_pg[top], m3->mc_ki[top]);
+                               if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA)
+                                       m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node);
+                       }
                }
        }
        {
@@ -8164,12 +8199,17 @@ mdb_cursor_del0(MDB_cursor *mc)
                        if (m3 == mc || m3->mc_snum < mc->mc_snum)
                                continue;
                        if (m3->mc_pg[mc->mc_top] == mp) {
-                               if (m3->mc_ki[mc->mc_top] >= ki) {
+                               if (m3->mc_ki[mc->mc_top] == ki) {
                                        m3->mc_flags |= C_DEL;
-                                       if (m3->mc_ki[mc->mc_top] > ki)
-                                               m3->mc_ki[mc->mc_top]--;
-                                       else if (mc->mc_db->md_flags & MDB_DUPSORT)
+                                       if (mc->mc_db->md_flags & MDB_DUPSORT)
                                                m3->mc_xcursor->mx_cursor.mc_flags &= ~C_INITIALIZED;
+                               } else if (m3->mc_ki[mc->mc_top] > ki) {
+                                       m3->mc_ki[mc->mc_top]--;
+                               }
+                               if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) {
+                                       MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]);
+                                       if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA)
+                                               m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node);
                                }
                        }
                }
@@ -8353,6 +8393,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
        }
 
        mdb_cursor_copy(mc, &mn);
+       mn.mc_xcursor = NULL;
        mn.mc_pg[mn.mc_top] = rp;
        mn.mc_ki[ptop] = mc->mc_ki[ptop]+1;
 
@@ -8683,6 +8724,12 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
                                m3->mc_ki[ptop] >= mc->mc_ki[ptop]) {
                                m3->mc_ki[ptop]++;
                        }
+                       if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) &&
+                               IS_LEAF(mp)) {
+                               MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]);
+                               if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA)
+                                       m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node);
+                       }
                }
        }
        DPRINTF(("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp)));
@@ -9240,7 +9287,9 @@ mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags)
         * already in the OS cache.
         */
 #ifdef _WIN32
-       utf8_to_utf16(lpath, -1, &wpath, NULL);
+       rc = utf8_to_utf16(lpath, -1, &wpath, NULL);
+       if (rc)
+               return rc;
        newfd = CreateFileW(wpath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
                                FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL);
        free(wpath);
@@ -9435,6 +9484,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
        MDB_db dummy;
        int rc, dbflag, exact;
        unsigned int unused = 0, seq;
+       char *namedup;
        size_t len;
 
        if (flags & ~VALID_FLAGS)
@@ -9496,8 +9546,16 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
                MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]);
                if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA)
                        return MDB_INCOMPATIBLE;
-       } else if (rc == MDB_NOTFOUND && (flags & MDB_CREATE)) {
-               /* Create if requested */
+       } else if (! (rc == MDB_NOTFOUND && (flags & MDB_CREATE))) {
+               return rc;
+       }
+
+       /* Done here so we cannot fail after creating a new DB */
+       if ((namedup = strdup(name)) == NULL)
+               return ENOMEM;
+
+       if (rc) {
+               /* MDB_NOTFOUND and MDB_CREATE: Create new DB */
                data.mv_size = sizeof(MDB_db);
                data.mv_data = &dummy;
                memset(&dummy, 0, sizeof(dummy));
@@ -9507,10 +9565,12 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
                dbflag |= DB_DIRTY;
        }
 
-       /* OK, got info, add to table */
-       if (rc == MDB_SUCCESS) {
+       if (rc) {
+               free(namedup);
+       } else {
+               /* Got info, register DBI in this txn */
                unsigned int slot = unused ? unused : txn->mt_numdbs;
-               txn->mt_dbxs[slot].md_name.mv_data = strdup(name);
+               txn->mt_dbxs[slot].md_name.mv_data = namedup;
                txn->mt_dbxs[slot].md_name.mv_size = len;
                txn->mt_dbxs[slot].md_rel = NULL;
                txn->mt_dbflags[slot] = dbflag;
@@ -9961,6 +10021,8 @@ static int utf8_to_utf16(const char *src, int srcsize, wchar_t **dst, int *dstsi
        if (need == 0)
                return EINVAL;
        result = malloc(sizeof(wchar_t) * need);
+       if (!result)
+               return ENOMEM;
        MultiByteToWideChar(CP_UTF8, 0, src, srcsize, result, need);
        if (dstsize)
                *dstsize = need;