[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: (ITS#7594) incomplete MDB subdb cursor cleanup
- To: openldap-its@OpenLDAP.org
- Subject: Re: (ITS#7594) incomplete MDB subdb cursor cleanup
- From: hyc@symas.com
- Date: Thu, 23 May 2013 19:25:30 GMT
- Auto-submitted: auto-generated (OpenLDAP-ITS)
h.b.furuseth@usit.uio.no wrote:
> Full_Name: Hallvard B Furuseth
> Version: mdb.master 0cdd9dffddf66c730a35f48db2bb02d8bb3e5731
> OS: Linux x86_64
> URL:
> Submission from: (NULL) (193.69.163.163)
> Submitted by: hallvard
>
>
> If a cursor is at a clean subDB page, and its current item is deleted
> by another cursor, then MDB_GET_CURRENT returns the deleted item.
Fixed now in mdb.master. The subcursor on the clean page will be invalidated
when the page is touched.
> Test program below, run with no args, the "m2/del" output line.
>
> If the page was dirty, I instead got (key = old, data = size 0).
> I don't know if it should give MDB_NOTFOUND instead.
> That's the test program run with one arg.
> I did not check what happens if the other cursor rearranged
> the pages, e.g. split the item off to another page.
>
> #include "lmdb.h"
> #include <assert.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> int main(int argc, char **argv)
> {
> char *fname = "test.mdb";
> MDB_env *env;
> MDB_txn *txn;
> MDB_dbi dbi;
> MDB_cursor *mc, *m2;
> MDB_val key, data;
> int rc;
> # define STR2VAL(s) (&(MDB_val){sizeof(s), s}) /* includes final \0 */
> # define SHOW(name) printf("%s:\t%s[%zd] -> %s[%zd]\n", name, \
> (char*)key.mv_data, key.mv_size, (char*)data.mv_data, data.mv_size)
> # define E(e) { rc = (e); if (rc) { fprintf(stderr, "%s:%d: %s: %s\n",\
> __FILE__, __LINE__, #e, mdb_strerror(rc)); abort(); } }
>
> remove(fname);
> E(mdb_env_create(&env));
> E(mdb_env_open(env, fname, MDB_NOSUBDIR, 0666));
> E(mdb_txn_begin(env, NULL, 0, &txn));
> E(mdb_dbi_open(txn, NULL, MDB_DUPSORT, &dbi));
>
> E(mdb_cursor_open(txn, dbi, &mc));
> E(mdb_cursor_put(mc, STR2VAL("a"), STR2VAL("x"), 0));
> E(mdb_cursor_put(mc, STR2VAL("a"), STR2VAL("y"), 0));
>
> if (argc < 2) {
> E(mdb_txn_commit(txn));
> E(mdb_txn_begin(env, NULL, 0, &txn));
> E(mdb_cursor_open(txn, dbi, &mc));
> puts("With clean page:");
> }
> E(mdb_cursor_open(txn, dbi, &m2));
>
> E(mdb_cursor_get(mc, &key, &data, MDB_FIRST));
> E(mdb_cursor_get(m2, &key, &data, MDB_FIRST));
> SHOW("Name:\tKey -> Data (mv_data[mv_len]):\n" "m2");
>
> E(mdb_cursor_del(mc, 0));
> E(mdb_cursor_get(m2, &key, &data, MDB_GET_CURRENT));
> SHOW("m2/del"); /* Should output the same as... */
> E(mdb_cursor_get(mc, &key, &data, MDB_GET_CURRENT));
> SHOW("mc/del"); /* ...this: "a[2] -> [0]". */
>
> mdb_txn_abort(txn);
> mdb_env_close(env);
> return 0;
> }
>
>
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/