diff --git a/mdb.c b/mdb.c index c130d1d8..8cac1718 100644 --- a/mdb.c +++ b/mdb.c @@ -5641,8 +5641,8 @@ mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) /* 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++; + mp = mc->mc_pg[mc->mc_top]; goto ready; } } @@ -6005,15 +6005,20 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) MDB_node *leaf; int rc; - if ((mc->mc_flags & C_EOF) || - ((mc->mc_flags & C_DEL) && op == MDB_NEXT_DUP)) { + if ((mc->mc_flags & C_DEL) && op == MDB_NEXT_DUP) return MDB_NOTFOUND; - } + if (!(mc->mc_flags & C_INITIALIZED)) return mdb_cursor_first(mc, key, data); mp = mc->mc_pg[mc->mc_top]; + if (mc->mc_flags & C_EOF) { + if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mp)-1) + return MDB_NOTFOUND; + mc->mc_flags ^= C_EOF; + } + if (mc->mc_db->md_flags & MDB_DUPSORT) { leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { @@ -6532,9 +6537,16 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data, break; } rc = MDB_SUCCESS; - if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) || - (mc->mc_xcursor->mx_cursor.mc_flags & C_EOF)) + if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) break; + if (mc->mc_xcursor->mx_cursor.mc_flags & C_EOF) { + MDB_cursor *mx = &mc->mc_xcursor->mx_cursor; + if (mx->mc_ki[mx->mc_top] >= NUMKEYS(mx->mc_pg[mx->mc_top])-1) { + rc = MDB_NOTFOUND; + break; + } + mx->mc_flags ^= C_EOF; + } goto fetchm; case MDB_NEXT_MULTIPLE: if (unlikely(data == NULL)) { @@ -7878,14 +7890,23 @@ mdb_cursor_count(MDB_cursor *mc, size_t *countp) return EINVAL; #if MDBX_MODE_ENABLED - MDB_page *mp = mc->mc_pg[mc->mc_top]; - int nkeys = NUMKEYS(mp); - if (!nkeys || mc->mc_ki[mc->mc_top] >= nkeys) { + if (!mc->mc_snum) { *countp = 0; return MDB_NOTFOUND; - } else if (mc->mc_xcursor == NULL || IS_LEAF2(mp)) { + } + + MDB_page *mp = mc->mc_pg[mc->mc_top]; + if (mc->mc_flags & C_EOF) { + if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mp)) { + *countp = 0; + return MDB_NOTFOUND; + } + mc->mc_flags ^= C_EOF; + } + + if (mc->mc_xcursor == NULL || IS_LEAF2(mp)) { *countp = 1; - } else { + } else { MDB_node *leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) *countp = 1; @@ -7895,12 +7916,18 @@ mdb_cursor_count(MDB_cursor *mc, size_t *countp) *countp = mc->mc_xcursor->mx_db.md_entries; } #else - if (unlikely(mc->mc_xcursor == NULL)) + if (unlikely(mc->mc_xcursor == NULL)) return MDB_INCOMPATIBLE; - if (unlikely(!mc->mc_snum || (mc->mc_flags & C_EOF))) + if (!mc->mc_snum) return MDB_NOTFOUND; + if (mc->mc_flags & C_EOF) { + if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top])) + return MDB_NOTFOUND; + mc->mc_flags ^= C_EOF; + } + MDB_node *leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) { *countp = 1;