summaryrefslogtreecommitdiff
path: root/libraries/liblmdb/mdb.c
diff options
context:
space:
mode:
authorHoward Chu <hyc@openldap.org>2016-04-18 18:07:56 +0100
committerHoward Chu <hyc@openldap.org>2016-04-18 18:07:56 +0100
commit37081325f7356587c5e6ce4c1f36c3b303fa718c (patch)
tree17ae58dda6399b9e88210cf5fd6bbae281ba3b74 /libraries/liblmdb/mdb.c
parentc8dbd772f751471fd2824bbb27ac9b8b392af465 (diff)
downloadlmdb-37081325f7356587c5e6ce4c1f36c3b303fa718c.tar.gz
lmdb-37081325f7356587c5e6ce4c1f36c3b303fa718c.tar.bz2
lmdb-37081325f7356587c5e6ce4c1f36c3b303fa718c.zip
ITS#8406 fix xcursors after cursor_del
Don't leave them uninit'd if they now point at a valid DUP node
Diffstat (limited to 'libraries/liblmdb/mdb.c')
-rw-r--r--libraries/liblmdb/mdb.c50
1 files changed, 25 insertions, 25 deletions
diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c
index 2d8e458..e62ca62 100644
--- a/libraries/liblmdb/mdb.c
+++ b/libraries/liblmdb/mdb.c
@@ -6420,8 +6420,8 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
if (mc->mc_flags & C_EOF) {
return MDB_NOTFOUND;
}
-
- mdb_cassert(mc, mc->mc_flags & C_INITIALIZED);
+ if (!(mc->mc_flags & C_INITIALIZED))
+ return mdb_cursor_first(mc, key, data);
mp = mc->mc_pg[mc->mc_top];
@@ -6507,7 +6507,12 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
MDB_node *leaf;
int rc;
- mdb_cassert(mc, mc->mc_flags & C_INITIALIZED);
+ if (!(mc->mc_flags & C_INITIALIZED)) {
+ rc = mdb_cursor_last(mc, key, data);
+ if (rc)
+ return rc;
+ mc->mc_ki[mc->mc_top]++;
+ }
mp = mc->mc_pg[mc->mc_top];
@@ -6979,10 +6984,7 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
rc = MDB_INCOMPATIBLE;
break;
}
- if (!(mc->mc_flags & C_INITIALIZED))
- rc = mdb_cursor_first(mc, key, data);
- else
- rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP);
+ rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP);
if (rc == MDB_SUCCESS) {
if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) {
MDB_cursor *mx;
@@ -7024,21 +7026,11 @@ fetchm:
case MDB_NEXT:
case MDB_NEXT_DUP:
case MDB_NEXT_NODUP:
- if (!(mc->mc_flags & C_INITIALIZED))
- rc = mdb_cursor_first(mc, key, data);
- else
- rc = mdb_cursor_next(mc, key, data, op);
+ rc = mdb_cursor_next(mc, key, data, op);
break;
case MDB_PREV:
case MDB_PREV_DUP:
case MDB_PREV_NODUP:
- if (!(mc->mc_flags & C_INITIALIZED)) {
- rc = mdb_cursor_last(mc, key, data);
- if (rc)
- break;
- mc->mc_flags |= C_INITIALIZED;
- mc->mc_ki[mc->mc_top]++;
- }
rc = mdb_cursor_prev(mc, key, data, op);
break;
case MDB_FIRST:
@@ -9050,8 +9042,6 @@ mdb_cursor_del0(MDB_cursor *mc)
if (m3->mc_pg[mc->mc_top] == mp) {
if (m3->mc_ki[mc->mc_top] == ki) {
m3->mc_flags |= C_DEL;
- 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]--;
}
@@ -9085,11 +9075,21 @@ mdb_cursor_del0(MDB_cursor *mc)
continue;
if (m3->mc_pg[mc->mc_top] == mp) {
/* if m3 points past last node in page, find next sibling */
- if (m3->mc_ki[mc->mc_top] >= nkeys) {
- rc = mdb_cursor_sibling(m3, 1);
- if (rc == MDB_NOTFOUND) {
- m3->mc_flags |= C_EOF;
- rc = MDB_SUCCESS;
+ if (m3->mc_ki[mc->mc_top] >= mc->mc_ki[mc->mc_top]) {
+ if (m3->mc_ki[mc->mc_top] >= nkeys) {
+ rc = mdb_cursor_sibling(m3, 1);
+ if (rc == MDB_NOTFOUND) {
+ m3->mc_flags |= C_EOF;
+ rc = MDB_SUCCESS;
+ continue;
+ }
+ }
+ if (mc->mc_db->md_flags & MDB_DUPSORT) {
+ MDB_node *node = NODEPTR(m3->mc_pg[m3->mc_top], m3->mc_ki[m3->mc_top]);
+ if (node->mn_flags & F_DUPDATA) {
+ mdb_xcursor_init1(m3, node);
+ m3->mc_xcursor->mx_cursor.mc_flags |= C_DEL;
+ }
}
}
}