]> git.sur5r.net Git - openldap/commitdiff
ITS#8557 fix mdb_cursor_last
authorHoward Chu <hyc@openldap.org>
Wed, 11 Jan 2017 09:51:43 +0000 (09:51 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 11 Jan 2017 11:21:34 +0000 (11:21 +0000)
Optimize mdb_page_search_root(PS_LAST) when cursor is already near
last position, ignoring C_EOF flag for now.

libraries/liblmdb/mdb.c

index 23c1f009b01dd75b8d4d6c212d360238f65e19ae..1644953047600913e5b768d441c3be5d4519c43d 100644 (file)
@@ -5459,8 +5459,17 @@ mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags)
 
                if (flags & (MDB_PS_FIRST|MDB_PS_LAST)) {
                        i = 0;
-                       if (flags & MDB_PS_LAST)
+                       if (flags & MDB_PS_LAST) {
                                i = NUMKEYS(mp) - 1;
+                               /* if already init'd, see if we're already in right place */
+                               if (mc->mc_flags & C_INITIALIZED) {
+                                       if (mc->mc_ki[mc->mc_top] == i) {
+                                               mc->mc_top = mc->mc_snum++;
+                                               mp = mc->mc_pg[mc->mc_top];
+                                               goto ready;
+                                       }
+                               }
+                       }
                } else {
                        int      exact;
                        node = mdb_node_search(mc, key, &exact);
@@ -5486,6 +5495,7 @@ mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags)
                if ((rc = mdb_cursor_push(mc, mp)))
                        return rc;
 
+ready:
                if (flags & MDB_PS_MODIFY) {
                        if ((rc = mdb_page_touch(mc)) != 0)
                                return rc;
@@ -6224,16 +6234,13 @@ mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data)
        if (mc->mc_xcursor)
                mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
 
-       if (!(mc->mc_flags & C_EOF)) {
-
-               if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) {
-                       rc = mdb_page_search(mc, NULL, MDB_PS_LAST);
-                       if (rc != MDB_SUCCESS)
-                               return rc;
-               }
-               mdb_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]));
-
+       if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) {
+               rc = mdb_page_search(mc, NULL, MDB_PS_LAST);
+               if (rc != MDB_SUCCESS)
+                       return rc;
        }
+       mdb_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]));
+
        mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]) - 1;
        mc->mc_flags |= C_INITIALIZED|C_EOF;
        leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);