[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?!

#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);


        return 0;