]> 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 09:51:43 +0000 (09:51 +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 3e7af1188601627948a2995154b09109dc98c688..c30a96f4c6d40b9b033024177be93cfa3bdf1d09 100644 (file)
@@ -6204,8 +6204,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) {
+                                               mp = mc->mc_pg[mc->mc_top];
+                                               mc->mc_top = mc->mc_snum++;
+                                               goto ready;
+                                       }
+                               }
+                       }
                } else {
                        int      exact;
                        node = mdb_node_search(mc, key, &exact);
@@ -6231,6 +6240,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;
@@ -7009,16 +7019,13 @@ mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data)
                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]);