]> git.sur5r.net Git - openldap/commitdiff
Add mdb_get for sorted dups
authorHoward Chu <hyc@symas.com>
Thu, 11 Aug 2011 03:17:06 +0000 (20:17 -0700)
committerHoward Chu <hyc@symas.com>
Thu, 1 Sep 2011 23:17:07 +0000 (16:17 -0700)
libraries/libmdb/mdb.c

index 979d9c0df20376aeaf6d01e48bd705c57b1c5e5f..95db54a2c76c28a36df5c60efbc6efa6f90ab865 100644 (file)
@@ -385,6 +385,10 @@ static int          mdb_cursor_first(MDB_cursor *cursor,
 static int              mdb_cursor_last(MDB_cursor *cursor,
                            MDB_val *key, MDB_val *data);
 
+static void            mdb_xcursor_init0(MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx);
+static void            mdb_xcursor_init1(MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx, MDB_db *db);
+static void            mdb_xcursor_fini(MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx);
+
 static size_t           mdb_leaf_size(MDB_env *env, MDB_val *key,
                            MDB_val *data);
 static size_t           mdb_branch_size(MDB_env *env, MDB_val *key);
@@ -1472,6 +1476,8 @@ mdb_get_page(MDB_txn *txn, pgno_t pgno)
                }
        }
        if (!found) {
+               if (pgno > txn->mt_env->me_meta->mm_last_pg)
+                       return NULL;
                p = (MDB_page *)(txn->mt_env->me_map + txn->mt_env->me_psize * pgno);
        }
        return p;
@@ -1653,9 +1659,20 @@ mdb_get(MDB_txn *txn, MDB_dbi dbi,
                return rc;
 
        leaf = mdb_search_node(txn, dbi, mpp.mp_page, key, &exact, NULL);
-       if (leaf && exact)
+       if (leaf && exact) {
+               /* Return first duplicate data item */
+               if (F_ISSET(txn->mt_dbs[dbi].md_flags, MDB_DUPSORT)) {
+                       MDB_xcursor mx;
+
+                       mdb_xcursor_init0(txn, dbi, &mx);
+                       mdb_xcursor_init1(txn, dbi, &mx, NODEDATA(leaf));
+                       rc = mdb_search_page(&mx.mx_txn, mx.mx_txn.mt_numdbs-1, NULL, NULL, 0, &mpp);
+                       if (rc != MDB_SUCCESS)
+                               return rc;
+                       leaf = NODEPTR(mpp.mp_page, 0);
+               }
                rc = mdb_read_data(txn, leaf, data);
-       else {
+       else {
                rc = ENOENT;
        }
 
@@ -2607,7 +2624,7 @@ mdb_del(MDB_txn *txn, MDB_dbi dbi,
                                                parent = SLIST_NEXT(top, mp_entry);
                                        } else {
                                                ni = NODEPTR(parent->mp_page, parent->mp_ki);
-                                               top = mdb_get_page(mc.mc_txn, ni->mn_pgno);
+                                               top->mp_page = mdb_get_page(mc.mc_txn, ni->mn_pgno);
                                        }
                                }
                        }