[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: (ITS#7844) LMDB Delete Cursor inconsistencies



This is a multi-part message in MIME format.
--------------010403060500020806080002
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

armon.dadgar@gmail.com wrote:
> --5372ac85_8edbdab_1271
> Content-Type: text/plain; charset="utf-8"
> Content-Transfer-Encoding: quoted-printable
> Content-Disposition: inline
>
> =46or now, we have application code to retry the delete until no further =
> rows are removed.
> Still, it would be nice to have this resolved (and tested) in master=21

Unable to reproduce the issue. I've attached my test program based on your 
description.

-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

--------------010403060500020806080002
Content-Type: text/plain; charset=UTF-8;
 name="7844.c.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="7844.c.txt"

/* 7844.c - memory-mapped database tester/toy */
/*
 * Copyright 2014 Howard Chu, Symas Corp.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uuid/uuid.h>
#include "lmdb.h"

#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
	"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))

#define UUID_LEN	36

typedef char kval[UUID_LEN*2+2];

char sval[100];

int main(int argc,char * argv[])
{
	int i = 0, j = 0, rc;
	MDB_env *env;
	MDB_dbi kdbi, ddbi;
	MDB_val key, ikey, data;
	MDB_txn *txn;
	MDB_stat mst;
	MDB_cursor *cursor, *cur2;
	int count;
	unsigned long lastid = 0;
	kval *keys;
	char prefix[UUID_LEN+1], *ptr;
	uuid_t uuid;

	count = 128;
	keys = (kval *)malloc(count*sizeof(kval));
	
	E(mdb_env_create(&env));
	E(mdb_env_set_mapsize(env, 128*1024*1024));
	E(mdb_env_set_maxdbs(env, 4));
	E(mdb_env_open(env, "./testdb", MDB_NOSYNC, 0664));
	E(mdb_txn_begin(env, NULL, 0, &txn));
	E(mdb_open(txn, "kvs", MDB_CREATE|MDB_INTEGERKEY, &ddbi));
	E(mdb_open(txn, "kvs_id_idx", MDB_CREATE, &kdbi));
   
	key.mv_size = UUID_LEN*2+1;
	data.mv_size = sizeof(sval);
	data.mv_data = sval;
	ikey.mv_size = sizeof(lastid);
	ikey.mv_data = &lastid;

	uuid_generate(uuid);
	uuid_unparse(uuid, prefix);
	printf("Adding %d values\n", count);
    for (i=0;i<count;i++) {	
		uuid_generate(uuid);
		ptr = (char *)&keys[i];
		memcpy(ptr, prefix, UUID_LEN);
		ptr[UUID_LEN] = '/';
		uuid_unparse(uuid, ptr+UUID_LEN+1);
		ptr[UUID_LEN*2+1] = '\0';
		printf("\t%s\n", ptr);
		key.mv_data = ptr;
		sprintf(sval, "Some stuff for key %s", ptr);
		lastid++;
		if (RES(MDB_KEYEXIST, mdb_put(txn, kdbi, &key, &ikey, MDB_NOOVERWRITE))) {
			j++;
			ikey.mv_size = sizeof(lastid);
			ikey.mv_data = &lastid;
		}
		E(mdb_put(txn, ddbi, &ikey, &data, MDB_NOOVERWRITE));
    }
	if (j) printf("%d duplicates skipped\n", j);
	E(mdb_txn_commit(txn));
	E(mdb_env_stat(env, &mst));

	uuid_generate(uuid);
	uuid_unparse(uuid, prefix);
	printf("Adding %d values\n", count);
	E(mdb_txn_begin(env, NULL, 0, &txn));
    for (i=0;i<count;i++) {	
		uuid_generate(uuid);
		ptr = (char *)&keys[i];
		memcpy(ptr, prefix, UUID_LEN);
		ptr[UUID_LEN] = '/';
		uuid_unparse(uuid, ptr+UUID_LEN+1);
		ptr[UUID_LEN*2+1] = '\0';
		printf("\t%s\n", ptr);
		key.mv_data = ptr;
		sprintf(sval, "Some stuff for key %s", ptr);
		lastid++;
		if (RES(MDB_KEYEXIST, mdb_put(txn, kdbi, &key, &ikey, MDB_NOOVERWRITE))) {
			j++;
			ikey.mv_size = sizeof(lastid);
			ikey.mv_data = &lastid;
		}
		E(mdb_put(txn, ddbi, &ikey, &data, MDB_NOOVERWRITE));
    }
	if (j) printf("%d duplicates skipped\n", j);
	E(mdb_txn_commit(txn));

	E(mdb_txn_begin(env, NULL, 0, &txn));
	E(mdb_cursor_open(txn, kdbi, &cursor));
	E(mdb_cursor_open(txn, ddbi, &cur2));
	key.mv_size = UUID_LEN;
	key.mv_data = prefix;
	j = 0;
	i = count;
	rc = mdb_cursor_get(cursor, &key, &ikey, MDB_SET_RANGE);
	while (rc == 0) {
#if 0
		printf("key: %p %.*s, data: %p %.*s\n",
			key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
			data.mv_data, (int) data.mv_size, (char *) data.mv_data);
#endif
		E(mdb_cursor_get(cur2, &ikey, &data, MDB_SET));
		E(mdb_cursor_del(cur2, 0));
		E(mdb_cursor_del(cursor, 0));
		j++;
		i--;
		if (i == 0) break;
		rc = mdb_cursor_get(cursor, &key, &ikey, MDB_NEXT);
	}
	mdb_cursor_close(cursor);
	mdb_cursor_close(cur2);
	E(mdb_txn_commit(txn));
	printf("Deleted %d values\n", j);

	mdb_env_close(env);

	return 0;
}

--------------010403060500020806080002--