<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="378017" data-post-id="378017">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zteln" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zteln
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/garrison" rel="nofollow">@garrison</a> Thanks for your reply! I have rewritten a large part of the code, focusing on making consistency and durability guarantees simpler and better. Main changes:</p>
<ul>
<li>MemTable implemented as an ETS table and the store putting SSTs into an ETS table, allowing concurrent readers</li>
<li>removed all conflict detection between writers and instead implemented one writer at a time and any pending writers are placed in a write queue. This is true serial execution.</li>
<li>the WAL syncs after every append</li>
</ul>
<p>Some other changes: CRC verification on SSTs on start, and data in SSTs are compressed for levels larger than 1.</p>
<p>Check the new version out if you have time, any more feedback is welcome and greatly appreciated!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378017" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/goblin-another-embedded-key-value-database-for-elixir/73169/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-378017" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378017"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="378124" data-post-id="378124">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Those changes all sound good to me. A single writer is a reasonable tradeoff for an embedded DB.</p>
<p>One thing you might want is read-only transactions that don’t have to take the write lock. You have a multi-get operation, but that’s not enough to do pointer chasing on a consistent snapshot:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">key1 = "foo"
key2 = get(key1)
key3 = get(key2)
</code></pre>
<p>This pattern is needed for many data structures that one would implement over a KV store. Without a transaction these reads will be performed at different versions, which will cause consistency issues.</p>
<p>If the transactions are read-only you don’t need any further concurrency control. All you need to do is get the latest seqno of the most recent committed write txn and perform reads at that version. That is enough for strict serializability (along with the single writer).</p>
<p>You do also need to be able to hold a snapshot of the manifest open (blocking SST deletion) for the duration of the read transaction, which we discussed previously. You will need that for backups as well.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378124" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/goblin-another-embedded-key-value-database-for-elixir/73169/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-378124" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378124"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="378558" data-post-id="378558">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zteln" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zteln
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for the feedback! I’ve released v0.3.0 now incorporating your suggestions:</p>
<ul>
<li>Read-only transactions (can be obtained by providing the option <code>read_only: true</code> to <code>Goblin.transaction/2</code>)</li>
<li>Added <code>Goblin.export/2</code> which exports a snapshot of the database into a <code>.tar.gz</code> file.</li>
</ul>
<p>The internal manifest format was changed for these changes. Let me know what you think!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378558" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/goblin-another-embedded-key-value-database-for-elixir/73169/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-378558" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378558"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="379356" data-post-id="379356">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zteln" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zteln
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Small update (v0.3.2):</p>
<ul>
<li>Flush and compactions are triggered by checking byte sizes instead of amount of keys. This changes the start options to <code>Goblin.start_link/1</code>. The default values are mirrored from RocksDB default values.</li>
<li>Fixed some tests, working on covering more tests</li>
<li>Working on optimizing as well.</li>
</ul>
<p>Let me know if anything doesn’t work!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379356" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/goblin-another-embedded-key-value-database-for-elixir/73169/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-379356" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379356"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="381471" data-post-id="381471">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zteln" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zteln
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yet another release (0.4.0) with some larger rewrites. Goblin has been redesigned almost from the ground up with consistency guarantees in mind. Some noticable changes:</p>
<ul>
<li><code>Goblin.read/2</code> is introduced as a read-only transaction (instead of previously providing <code>read_only: true</code> to <code>Goblin.transaction/3</code>, which is now deprecated in favour of <code>Goblin.transaction/2</code>).</li>
<li><code>Goblin.is_flushing/1</code> and <code>Goblin.is_compacting/1</code> have been renamed to <code>Goblin.is_flushing?/1</code> and <code>Goblin.is_compacting?/1</code>, respectively.</li>
<li>The file format which Goblin saves data to has been changed, making previous versions non-compatible with the new version.</li>
</ul>
<p>Any feedback is welcome!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381471" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/goblin-another-embedded-key-value-database-for-elixir/73169/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-381471" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381471"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="381483" data-post-id="381483">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="zteln" data-post="16" data-topic="73169">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/z/898d66/48.png" class="avatar"> zteln:</div>
<blockquote>
<p><code>Goblin.is_flushing/1</code> and <code>Goblin.is_compacting/1</code> have been renamed to <code>Goblin.is_flushing?/1</code> and <code>Goblin.is_compacting?/1</code>, respectively.</p>
</blockquote>
</aside>
<p>Just to make you aware: in the Elixir community people would do <em>either</em> <code>is_flushing</code> or <code>flushing?</code> but not both at the same time.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381483" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/goblin-another-embedded-key-value-database-for-elixir/73169/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-381483" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381483"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="381484" data-post-id="381484">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Asd" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Asd
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>+1 to that comment.</p>
<ul>
<li>names ending with <code>?</code> (like <code>flushing?</code>) are <strong>functions</strong> returning a boolean</li>
<li>names starting with <code>is_</code> (like <code>is_number</code>) are <strong>macros</strong> that compile to <strong>guards</strong></li>
</ul>
<p>You need to name functions just <code>flushing?</code></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381484" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/goblin-another-embedded-key-value-database-for-elixir/73169/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-381484" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381484"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="381496" data-post-id="381496">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zteln" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zteln
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Ah, thanks for the clarification!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381496" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/goblin-another-embedded-key-value-database-for-elixir/73169/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-381496" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381496"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>