66610

LevelDB C iterator

I need to iterate through the leveldb database in c language - https://github.com/google/leveldb/blob/master/include/leveldb/c.h. Everything works except iterating.The result goes with some binary noise data:

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

With $&*#, etc. symbols I showed the binary output, stackoverflow does not allow to put here binary output.

The code:

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

How to correctly iterate through LevelDB in C?

Answer1:

It seems that values returned by leveldb_iter_key and leveldb_iter_value are not correct NULL-terminated strings.

So, the dirty solution would be use

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

instead of

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

However, IMO it's better to copy those values according to their length and then use them.

As you can see in https://github.com/google/leveldb/blob/master/db/c.cc#L197 leveldb_get creates slice of appropriate length (Slice(key, keylen) on L205) and returns copy of the key (CopyString on L208).

<strong>Additional:</strong>

I've checked your code with valgrind and there are some memory leaks with options. You should manually free them (e.g. leveldb_writeoptions_destroy for woptions). leveldb_get results (read) should also be freed.

<strong>Example code:</strong>

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

Recommend

  • GCC error: Cannot apply offsetof to member function MyClass::MyFunction
  • How to retrieve collisions of unordered map?
  • std::string::substr throws std::out_of_range but the arguments are in limit
  • Initializing a class using malloc
  • GRPC and types import error in App Engine Datastore
  • Nodejs bluebird promise fails while processing image
  • why my app based on boost::asio didn't accept new connection
  • NSMutableArray instance used in a block
  • Loading fixtures in sails tests
  • Regarding starting the threads on a condition
  • Unable to send e-mail through Java
  • NUnit 3.0 TestCase const custom object arguments
  • Undefined references when compiling gSOAP client
  • how does System.Web.HttpRequest::PathInfo work?
  • IE11 throwing “SCRIPT1014: invalid character” where all other browsers work
  • Login not working in Firefox in Meteor
  • Reading a file into a multidimensional array
  • How to remove a SwiftyJSON element?
  • RxJava debounce by arbitrary value
  • pyodbc doesn't report sql server error
  • NSScanner Loop Question
  • Display java JPanel in a JFrame
  • Needing to do .toArray() to get output of mongodb .find() on key name not value
  • MongoError: Incorrect arguments
  • why overloaded new operator is calling constructor even I am using malloc inside overloading functio
  • how to adjust image in a panel in Java swing?
  • Cannot connect to cassandra from Spark
  • Encrypt data by using a public key in c# and decrypt data by using a private key in php
  • Nant, Vault & Windows Integrated Authentication
  • How to make a tree having multiple type of nodes and each node can have multiple child nodes in java
  • Obtain ObjectIdHex value from mgo query
  • Javascript Callbacks with Object constructor
  • Return words with double consecutive letters
  • Linker errors when using intrinsic function via function pointer
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • InvalidAuthenticityToken between subdomains when logging in with Rails app
  • SQL merge duplicate rows and join values that are different
  • LevelDB C iterator
  • Can't mass-assign protected attributes when import data from csv file
  • How can i traverse a binary tree from right to left in java?