Symisc Vedis

An Embeddable Datastore Engine




Vedis in 5 Minutes or Less.

Here is what you do to start experimenting with Vedis without having to do a lot of tedious reading and configuration:

download The Code

Get a copy of the last public release of Vedis. Visit the download page for additional information.


Some C/C++ samples to start experimenting with:

Write Programs That Use Vedis

The principal task of a datastore engine is to store and retrieve records as fast as possible. Vedis support both structured and raw data storage.


Structured data storage is presented to clients via the command execution interface (CEI). Basically, you execute one or more commands ala Redis (i.e. SET key value; GET key, HSET...) via vedis_exec() and you extract the execution result (The return value of the command) via vedis_exec_result(). Refer to the following page for the list of built-in commands.


Raw data storage is presented to clients via the Key/Value store interfaces. Vedis is a standard key/value store similar to Berkeley DB, Tokyo Cabinet, LevelDB, etc. but with a rich feature set including support for transactions (ACID), concurrent reader, etc.

Under the KV store, both keys and values are treated as simple arrays of bytes, so content can be anything from ASCII strings, binary blob and even disk files. The KV store layer is presented to clients via a set of interfaces, these includes: vedis_kv_store(), vedis_kv_append(), vedis_kv_fetch_callback(), vedis_kv_append_fmt(), etc.


Introduction to the command Execution interfaces (CEI)

Below is a simple C program that demonstrates how to use the Command Execution C/C++ interface to Vedis.



  1. vedis *pStore; /* Datastore handle */
  2. int rc;

  3. /* Create our datastore */
  4. rc = vedis_open(&pStore,argc > 1 ? argv[1] /* On-disk DB */ : ":mem:"/* In-mem DB */);
  5. if( rc != VEDIS_OK ){  /* Seriously? */  return; }

  6. /* Execute the simplest command */
  7. rc = vedis_exec(pStore,"SET test 'Hello World'",-1);
  8. if( rc != VEDIS_OK ){ /* Handle error */ }

  9. /* Another simple command (Multiple set) */
  10. rc = vedis_exec(pStore,"MSET username james age 27 mail dude@example.com",-1);
  11. if( rc != VEDIS_OK ){ /* Handle error */ }

  12. /* A quite complex command (Multiple hash set) using foreign data */
  13. rc = vedis_exec_fmt(pStore,
  14.      "HMSET config pid %d user %s os %s scm %s",
  15.       1024    /* pid */,
  16.       "dean", /* user */
  17.       "FreeBSD", /* OS */
  18.       "Git"      /* SCM */
  19.    );
  20. if( rc != VEDIS_OK ){ /* Handle error */ }

  21. /* Fetch some data */
  22. rc = vedis_exec(pStore,"GET test",-1);
  23. if( rc != VEDIS_OK ){ /* Seriously? */ }

  24. /* Extract the return value of the last executed command (i.e. 'GET test') " */
  25. vedis_exec_result(pStore,&pResult);
  26. {
  27.     const char *zResponse;
  28.      /* Cast the vedis object to a string */
  29.      zResponse = vedis_value_to_string(pResult,0);
  30.      /* Output */
  31.      printf(" test ==> %s\n",zResponse); /* test ==> 'Hello world' */
  32. }

  33. vedis_exec(pStore,"GET mail",-1);
  34. /* 'GET mail' return value */
  35. vedis_exec_result(pStore,&pResult);
  36. {
  37.    const char *zResponse;
  38.    /* Cast the vedis object to a string */
  39.    zResponse = vedis_value_to_string(pResult,0);
  40.    /* Output */
  41.    printf(" mail ==> %s\n",zResponse); /* Should be 'dude@example.com' */
  42. }

  43. /*
  44.  * A command which return multiple value in array.
  45.  */
  46. vedis_exec(pStore,"MGET username age",-1); /* james 27*/
  47. vedis_exec_result(pStore,&pResult);

  48. if( vedis_value_is_array(pResult) ){
  49.    /* Iterate over the elements of the returned array */
  50.    vedis_value *pEntry;
  51.    puts("Array entries:");
  52.    while((pEntry = vedis_array_next_elem(pResult)) != 0 ){
  53.      const char *zEntry;
  54.      /* Cast to string and output */
  55.      zEntry = vedis_value_to_string(pEntry,0);
  56.      /* Output */
  57.      printf("\t%s\n",zEntry);
  58.   }
  59. }

  60. /* Extract hashtable data */
  61. vedis_exec(pStore,"HGET config pid",-1); /* 1024 */
  62. vedis_exec_result(pStore,&pResult);
  63. {
  64.   int pid;
  65.   /* Cast to integer */
  66.   pid = vedis_value_to_int(pResult);
  67.   /* Output */
  68.   printf("pid ==> %d\n",pid); /* Should be 1024 */
  69. }
  70. /* Finally, auto-commit the transaction and close our datastore */
  71. vedis_close(pStore);



Get the C File

Enhancing Vedis with foreign (i.e. User defined) commands is pretty simple and involve only a single call to vedis_register_command(). All of the built-in commands are installed using exactly this interface.



Introduction to the Key/Value Store Interfaces 

By far, the Vedis Key/Value store layer is the simplest, yet the most flexible since it does not impose any structure or schema to the database records.

The Key/Value store layer is presented to clients via a set of interfaces, these includes: vedis_kv_store(), vedis_kv_append(), vedis_kv_fetch(), vedis_kv_append_fmt(), and many more.


Below is a simple C program that demonstrates how to use the Key/Value C/C++ interface to Vedis.

  1. vedis *pStore; /* Datastore handle */
  2. int rc;

  3. /* Create our datastore */
  4. rc = vedis_open(&pStore,argc > 1 ? argv[1] /* On-disk DB */ : ":mem:" /* In-mem DB */);
  5. if( rc != VEDIS_OK ){  /* Seriously? */  return; }

  6. /* Store some records */
  7. rc = vedis_kv_store(pStore,"test",-1,"Hello World",11); /* test => 'Hello World' */
  8. if( rc != VEDIS_OK ){ /* Handle error */ }

  9. /* A small formatted string */
  10. rc = vedis_kv_store_fmt(pStore,"date",-1,"dummy date: %d:%d:%d",2013,9,17); /* Dummy date */
  11. if( rc != VEDIS_OK ){ /* Handle error */ }

  12. /* Switch to the append interface */
  13. rc = vedis_kv_append(pStore,"msg",-1,"Hello, ",7); //msg => 'Hello, '
  14. if( rc != VEDIS_OK ){ /* Handle error */ }

  15. /* The second chunk */
  16. rc = vedis_kv_append(pStore,
  17.    "msg",-1,"dummy time is: ",17 /* msg => 'Hello, Current time is: '*/
  18.  ); 
  19. if( rc != VEDIS_OK ){ /* Handle error */ }

  20. rc = vedis_kv_append_fmt(pStore,
  21.         "msg",-1,"%d:%d:%d",
  22.             1,12,42); /* msg => 'Hello, Current time is: 10:16:53' */


  23. /* Store 20 random records.*/
  24. for(i = 0 ; i < 20 ; ++i ){
  25.   char zKey[12]; /* Random generated key */
  26.   char zData[34]; /* Dummy data */

  27.   /* Generate the random key */
  28.    vedis_util_random_string(pStore,zKey,sizeof(zKey));
  29.  
  30.    /* Perform the insertion */
  31.    rc = vedis_kv_store(pStore,zKey,sizeof(zKey),zData,sizeof(zData));
  32.    if( rc != VEDIS_OK ){
  33.     break;
  34.   }
  35. }

  36. /* Fetch some data and invoke the supplied callback for each retrieved record* /
  37. rc = vedis_kv_fetch_callback(pStore,"test",-1,DataConsumerCallback,0);
  38. if( rc != VEDIS_OK ){/* Can't happen */ }

  39. rc = vedis_kv_fetch_callback(pStore,"msg",-1,DataConsumerCallback,0);
  40. if( rc != VEDIS_OK ){/* Can't happen */ }

  41. /* Delete a record */
  42. vedis_kv_delete(pStore,"test",-1);

  43. /* Finally, auto-commit the transaction and close our datastore */
  44. vedis_close(pStore);

Get the C File
Fetching data under the KV store is straightforward and involve only a single call to: vedis_kv_fetch_callback() or vedis_kv_fetch(). The vedis_kv_fetch_callback() interface is the recommended one where the caller supply a simple callback responsible of consuming the record data perhaps redirecting it (i.e. Record data) to its standard output (STDOUT) or to the connected peer. The vedis_kv_fetch() interface should be familiar to everyone where ther caller supply its own (either statistically or dynamically allocated) buffer in which data is copied in.

Other useful Links to start with

Check out the Introduction To The Vedis C/C++ Interface for an introductory overview and roadmap to the dozens of Vedis interface functions. A separate document, The Vedis C/C++ Interface, provides detailed specifications for all of the various C/C++ APIs for Vedis.

Once the reader understands the basic principles of operation for Vedis, that document should be used as a reference guide.

Any questions, visit the Support Page for additional information.



Symisc Systems
Copyright © Symisc Systems