2016-03-28 10 views
2

leveldbデータベースをC言語で反復する必要があります - https://github.com/google/leveldb/blob/master/include/leveldb/c.h。 $ & *#でLevelDB C iterator

key: value1 
key: value2 
key#&^$&*# value 
one1(*@(# value1 
two2%*@(value2 

、私はバイナリ出力、stackoverflowのは、ここでバイナリ出力を置くことを許可していませんが示されたなどの記号を:iterating.The結果は、いくつかのバイナリノイズデータで行く以外すべてが動作します。

コード:

#include <leveldb/c.h> 
#include <stdio.h> 

int main() { 
    leveldb_t *db; 
    leveldb_options_t *options; 
    leveldb_readoptions_t *roptions; 
    leveldb_writeoptions_t *woptions; 
    char *err = NULL; 
    char *read; 
    size_t read_len; 

    /******************************************/ 
    /* OPEN */ 

    options = leveldb_options_create(); 
    leveldb_options_set_create_if_missing(options, 1); 
    db = leveldb_open(options, "testdb", &err); 

    if (err != NULL) { 
     fprintf(stderr, "Open fail.\n"); 
     return(1); 
    } 

    /* reset error var */ 
    leveldb_free(err); err = NULL; 

    /******************************************/ 
    /* WRITE */ 

    woptions = leveldb_writeoptions_create(); 
    leveldb_put(db, woptions, "one", 3, "value1", 6, &err); 

    if (err != NULL) { 
     fprintf(stderr, "Write fail.\n"); 
     return(1); 
    } 

    leveldb_free(err); err = NULL; 

    /******************************************/ 
    /* WRITE 2 */ 

    woptions = leveldb_writeoptions_create(); 
    leveldb_put(db, woptions, "two", 3, "value2", 6, &err); 

    if (err != NULL) { 
     fprintf(stderr, "Write fail.\n"); 
     return(1); 
    } 

    leveldb_free(err); err = NULL; 

    /******************************************/ 
    /* READ */ 

    roptions = leveldb_readoptions_create(); 
    read = leveldb_get(db, roptions, "one", 3, &read_len, &err); 

    if (err != NULL) { 
     fprintf(stderr, "Read fail.\n"); 
     return(1); 
    } 

    printf("key: %s\n", read); 

    leveldb_free(err); err = NULL; 

    /******************************************/ 
    /* READ 2 */ 

    roptions = leveldb_readoptions_create(); 
    read = leveldb_get(db, roptions, "two", 3, &read_len, &err); 

    if (err != NULL) { 
     fprintf(stderr, "Read fail.\n"); 
     return(1); 
    } 

    printf("key: %s\n", read); 

    leveldb_free(err); err = NULL; 

    /******************************************/ 
    /* ITERATE */ 

    roptions = leveldb_readoptions_create(); 
    leveldb_iterator_t *iter = leveldb_create_iterator(db, roptions); 

    for (leveldb_iter_seek_to_first(iter); leveldb_iter_valid(iter); leveldb_iter_next(iter)) 
    { 
     size_t key_len, value_len; 
     const char *key_ptr = leveldb_iter_key(iter, &key_len); 
     const char *value_ptr = leveldb_iter_value(iter, &value_len); 

     /* Prints some binary noise with the data */ 
     printf("%s %s\n", key_ptr, value_ptr); 
    } 
    leveldb_iter_destroy(iter); 
    leveldb_free(err); err = NULL; 

    /******************************************/ 
    /* CLOSE */ 

    leveldb_close(db); 

    return(0); 
} 

正しくCでLevelDBを反復処理する方法?

答えて

2

leveldb_iter_keyleveldb_iter_valueによって返される値は、NULLで終わる正しい文字列ではないようです。

ので、汚れたソリューションは、しかし、IMOそれは、それらの長さに応じてそれらの値をコピーし、それらを使用することをお勧めします代わりに

printf("%s %s\n", key_ptr, value_ptr); 

printf("%.*s %.*s\n", (int) key_len, key_ptr, (int) value_len, value_ptr); 

を使うだろう。

あなたはhttps://github.com/google/leveldb/blob/master/db/c.cc#L197leveldb_getで見ることができるように、適切な長さ(L205上Slice(key, keylen))のスライスを作成し、リターンキー(L208上CopyString)のコピー。

追加:

私はvalgrindのを使用してコードをチェックしましたし、オプションでいくつかのメモリリークがあります。手動で解除する必要があります(例:woptionsの場合はleveldb_writeoptions_destroy)。 leveldb_get結果(read)も解放する必要があります。

例コード:

// allocate new strings 
char * key = (char *) malloc(key_len + 1); 
char * value = (char *) malloc(value_len + 1); 

// copy string content and ensure that string is null-terminated 
memcpy(key, key_ptr, key_len); 
key[key_len] = 0; 
memcpy(value, value_ptr, value_len); 
value[value_len] = 0; 

// print 
printf("%s %s\n", key, value); 

// free 
free(key); 
free(value); 
+0

https://github.com/google/leveldb/blob/master/db/c.cc#L197 - そのC++、私はCのバージョン –

+0

@SebastianRockefellerを必要としますLevelDBはC++で書かれていますが、Cで使用することができます。 – nightuser

+1

@SebastianRockefeller Cでは 'strncpy'または' memcpy'を使用して手動でNULL終了します。 – nightuser