title: Embedded database with concurrent read and write
body: <p>I am looking at a database solution for a <strong>concurrent writer and reader problem</strong>. I need an <strong>embedded database</strong> which will be <strong>written by a single writer process</strong>. The same database will be <strong>read by a single reader process</strong> and these processes run simultaneously. </p>
  
  <p>I have looked at solutions like <strong>RocksDB</strong> but where we can have multiple readers and a single writer but the <em>reader does not have the latest view of the database after opening it once</em> and hence has to open the DB again.</p>
  
  <p>Any help would be great.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>The code I wrote for RocksDB - </p>
  
  <p><strong><em>writer.cc</em></strong></p>
  
  <pre><code>#include &lt;cstdio&gt;
  #include &lt;string&gt;
  #include &lt;unistd.h&gt;
  #include &lt;iostream&gt;
  
  #include "rocksdb/db.h"
  #include "rocksdb/slice.h"
  #include "rocksdb/options.h"
  
  using namespace rocksdb;
  
  std::string kDBPath = "./db";
  
  int main() {
    DB* db;
    Options options;
    options.IncreaseParallelism();
    options.OptimizeLevelStyleCompaction();
    options.create_if_missing = true;
  
    Status s = DB::Open(options, kDBPath, &amp;db);
    assert(s.ok());
  
    for (int i = 0 ; ; i++) {
      int key = i;
      Slice kslice((char*)&amp;key, sizeof(int));
      int value = i*i;
      Slice vslice((char*)&amp;value, sizeof(value));
      s = db-&gt;Put(WriteOptions(), kslice, vslice);
      std::cout &lt;&lt;  "writing " &lt;&lt; i &lt;&lt; " : " &lt;&lt; i*i &lt;&lt; std::endl;
      assert(s.ok());
      sleep(1);
    }
    delete db;
    return 0;
  }
  </code></pre>
  
  <p>The output is as expected:</p>
  
  <pre><code>writing 0 : 0
  writing 1 : 1
  writing 2 : 4
  writing 3 : 9
  writing 4 : 16
  writing 5 : 25
  writing 6 : 36
  writing 7 : 49
  writing 8 : 64
  writing 9 : 81
  ...
  </code></pre>
  
  <p><strong><em>reader.cc</em></strong></p>
  
  <pre><code>#include &lt;cstdio&gt;
  #include &lt;string&gt;
  #include &lt;unistd.h&gt;
  #include &lt;iostream&gt;
  
  #include "rocksdb/db.h"
  #include "rocksdb/slice.h"
  #include "rocksdb/options.h"
  
  using namespace rocksdb;
  using namespace std;
  
  std::string kDBPath = "./db";
  
  int main() {
    DB* db;
    Options options;
    options.IncreaseParallelism();
    options.OptimizeLevelStyleCompaction();
  
    Status s = DB::OpenForReadOnly(options, kDBPath, &amp;db);
    assert(s.ok());
    int i = 0;
  
    while(true) {
      sleep(1);
      std::string value;
      Slice kslice((char*)&amp;i, sizeof(int));
      Status s = db-&gt;Get(ReadOptions(), kslice, &amp;value);
      if (!s.ok()) {
        std::cout &lt;&lt; i &lt;&lt; " " &lt;&lt; s.ToString() &lt;&lt; std::endl;
        break;
      }
      int a;
      memcpy(&amp;a, value.c_str(), sizeof(a));
      std::cout &lt;&lt; i &lt;&lt; ":" &lt;&lt; a &lt;&lt; std::endl;
      i++;
    }
    delete db;
    return 0;
  }
  </code></pre>
  
  <p>The output is (starting after key 3 has been added and not key 4)</p>
  
  <pre><code>0:0
  1:1
  2:4
  3:9
  4 NotFound: 
  </code></pre>
  
  <p>One possible solution which I tried is:</p>
  
  <pre><code>  Iterator* it = db-&gt;NewIterator(ReadOptions());
    int start = 0;
    Slice kslice((char*)&amp;start, sizeof(int));
    it-&gt;Seek(kslice);
    bool flag = true;
  
    while (true) {
      int key, value;
      for ( ; it-&gt;Valid() ; it-&gt;Next()) {
        memcpy(&amp;key, it-&gt;key().ToString().c_str(), sizeof(int));
        memcpy(&amp;value,  it-&gt;value().ToString().c_str(), sizeof(int));
        cout &lt;&lt; key &lt;&lt; " - " &lt;&lt; value &lt;&lt; endl;
        if (!it-&gt;status().ok()) {
          cout &lt;&lt; s.ToString() &lt;&lt; endl;
          flag = false;
        }
      }
      if (!flag)
        break;
      sleep(1);
      Status s = DB::OpenForReadOnly(options, kDBPath, &amp;db);
      assert(s.ok());
      Slice kslice((char*)&amp;key, sizeof(int));
      it = db-&gt;NewIterator(ReadOptions());
      it-&gt;Seek(kslice);
      it-&gt;Next();
    }
  </code></pre>
  
  <p>And the output is as expected:</p>
  
  <pre><code>writing 0 : 0
  writing 1 : 1
  writing 2 : 4
  writing 3 : 9
  writing 4 : 16
  writing 5 : 25
  writing 6 : 36
  writing 7 : 49
  writing 8 : 64
  writing 9 : 81
  ...
  </code></pre>
  
  <p>However, I want to avoid reading the database again and again for every update.</p>