[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: Issues arising from creating powerdns backend based on LMDB
I've found another weird - I have now converted the database to use
duplicates. Typically when I do mdb_cursor_get(... MDB_NEXT ) it will
set the key and value but I've found 1 place so far where I do it and on
the duplicate's second entry the value is set but the key is empty.
I don't see how this can happen; the only time we don't return the key
is if some operation actually failed. Can you send test code to
reproduce this?
Attached .c shows it - create 3 keys with 5 entries under each. Actually
my report was incorrect - cursor_get() with MDB_NEXT or MDB_NEXT_DUP
never seems to set the key unless it is the first entry read... Perhaps
this is intended?!
Mark
#include <stdio.h>
#include <stdlib.h>
#include "lmdb.h"
int main(int argc,char * argv[])
{
int i = 0, j = 0, rc;
MDB_env *env;
MDB_dbi dbi;
MDB_val key, data;
MDB_txn *txn;
MDB_cursor *cursor;
char buf[40];
char key_text[5];
int count = 5;
rc = mdb_env_create(&env);
rc = mdb_env_set_mapsize(env, (size_t)1024*1024*1024);
rc = mdb_env_open(env, "./testdb", MDB_NOSYNC, 0664);
rc = mdb_txn_begin(env, NULL, 0, &txn);
rc = mdb_dbi_open(txn, NULL, MDB_DUPSORT, &dbi);
for (i=0;i<count;i++) {
sprintf(buf, "%d", i);
data.mv_size = sizeof(buf);
data.mv_data = &buf;
for( j=0; j<3; j++ ) {
sprintf(key_text, "foo%d", j);
key.mv_size = sizeof(key_text);
key.mv_data = &key_text;
rc = mdb_put(txn, dbi, &key, &data, 0);
}
}
rc = mdb_cursor_open(txn, dbi, &cursor);
key.mv_size = 0;
mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
do {
// Uncomment this it all works
//mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT);
if( key.mv_size == 0 ) {
printf("WARNING 0 SIZE KEY\n");
} else {
printf("KEY OK: %s\n", key.mv_data);
}
printf("val: %s\n", data.mv_data);
key.mv_size = 0;
} while( !mdb_cursor_get(cursor, &key, &data, MDB_NEXT) );
rc = mdb_txn_commit(txn);
mdb_close(env, dbi);
mdb_env_close(env);
return 0;
}