<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="379923" data-post-id="379923">
  <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
                    <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">
								<aside class="quote no-group" data-username="dimitarvp" data-post="71" data-topic="73003">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>LLMs are a great way to overcome the blank canvas terror.</p>
</blockquote>
</aside>
<p>This is the claim I was referring to, and I’m not disputing its truth. What I’m suggesting is that there may be some dangerous second-order effects to look out for, particularly for junior programmers who do not yet have the skill set to design things themselves.</p>
<p>Obviously this is a spectrum, and at the far end of one side you have the most basic imaginable boilerplate. The stuff you get from <code>mix new</code>. Nobody needs to write that; we don’t even need <em>LLMs</em> to write that (we use <code>mix new</code>). But even then, there is probably some value to doing it at least once, just so you know where everything is.</p>
<p>As you move further down the spectrum, you might get something like <code>mix phx.new</code>. I still think these generators have some value, but even there it starts to get iffy and I know there are some who don’t like them. I don’t really like them either, to be honest. I think if I was designing a new framework (which, uh, maybe I am) I would probably not go generator-heavy. But it’s a personal choice.</p>
<p>However, on the far end of the <em>other</em> side of the spectrum you have green field designs. Stuff that you don’t actually know how to write because you’ve never done it before. Like, in my case, an LSM tree storage engine.</p>
<p>I cannot <code>mix new</code> an LSM tree. I have to figure out where the compaction goes, and where the k-way merge goes, and how the multiversion manifest is structured, and how they all fit together. This is <em>hard</em> because unfortunately there is no LSM instruction manual (believe me, I looked).</p>
<p>It’s <em>this</em> sort of scaffolding that I was referring to, not basic boilerplate. You have to figure out how to build these things one piece at a time. Like, you want to write the compaction, but first you need something to compact. So you write the memtable. Then you need a place to compact <em>to</em>, so you write the block store. <em>Now</em> you can write the compaction. Now you have tables, so you need the manifest, so you write that. Now you can compact tables into tables! But you need k-way merge for that. And so on.</p>
<p>If you’re an experienced programmer you probably think nothing of this, but the juniors (and realistically probably some “seniors”) don’t know how to do this. They think it’s magic. That’s what mitchellh’s article is about.</p>
<p>LLMs are much smarter than <code>mix new</code>, and they can actually produce somewhat plausible output if you tell them “write me an LSM tree in Elixir”. However, in doing so you will rob yourself of learning how to architect such a thing yourself. The model will make all of the most important architectural decisions for you, and it probably has no idea what it’s doing because there are not many LSMtrees in the training set. At least not <em>real</em> ones.</p>
<p>That last point is a bit funny: I have seen people ask a model to write them Paxos and have it reply with a version that has the actual implementation stubbed out. Hilarious!</p>
<p>But there are mistakes, deeper mistakes, that you won’t be able to spot unless you’re familiar with the problem space. And how do you become familiar, except by doing it yourself?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379923" data-batch-url="/posts/batch_likers">
                        3
                      </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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/72">Post #71</a>
	                </div>
	            </div>
              <div id="likers-container-379923" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379923"
                     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 #71"></div>
  </section>
</div>
    <div class="postbit" id="379924" data-post-id="379924">
  <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
                    <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">
								<aside class="quote no-group" data-username="dimitarvp" data-post="71" data-topic="73003">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>more… idiomatic? Easier to work with? Not quite sure but yeah, it’s a touch obscure code indeed.</p>
</blockquote>
</aside>
<p>It is more than a touch obscure. To be clear, this is the sort of code where if I saw it in another codebase I might not even waste my time trying to understand it. One thing I’ve learned from reading a lot of database code is that there are times when it’s easier to derive what something must be doing from first principles than to actually read the code. Reading code sucks.</p>
<p>In this case the salient point is that even I had no idea wtf the code was doing and I <em>just wrote it</em>, so it was uniquely garbage.</p>
<p>Anyway, I will try to explain it just for fun. That code builds the index blocks for an LSM table. Each table in an LSM is a two-level structure (like a degenerate, immutable btree) where the first level holds sorted pairs and the second level holds an index entry for every, say, 64 KiB of data. The key pairs are divided into subtables every 64 KiB (these are traditionally called “blocks” rather than “subtables” but in my case the term was overloaded) and each subtable gets an index entry.</p>
<p>The entries are accumulated such that they end up in a structure of <code>[{block_i, [{key, pointer}]}]</code>. The <code>block_i</code> here really is a block and is <em>not</em> a subtable but this is not worth explaining further. The point is, it’s a nested list. And we need a nested loop.</p>
<p>“Idiomatic” is a funny thing because <em>I</em> think the most idiomatic way to solve this would be to flatten the whole thing into one list. The problem is that, as <a class="mention" href="/u/schultzer" rel="nofollow">@Schultzer</a> will tell you, this will cause a huge number of completely wasted allocations. So we want to traverse the nested structure.</p>
<p>My first attempt at this was absolutely disgusting. There was, like, a function head that noticed when one level of the loop was finished and popped it out. Just really confusing to look at.</p>
<p>Informed by versions of this code I had to write elsewhere, I realized that this was much more readable (and indeed likely faster) when implemented as two sets of recursive functions, i.e. as the functional analog of a nested loop. In hindsight this is obvious. But that’s the funny thing about hindsight.</p>
<p>BTW, I am making no claims that this code is now “good” and I’m sure I’ll end up rewriting it again. I think it may not be garbage anymore, though.</p>
<p>I also gave the variables better names. The important takeaway if anything is that stuff like that <em>really</em> matters and is not bikeshedding. I was having trouble reverse-engineering my own code because the variable names were not clear enough. I even wrote a bug while refactoring because of this (and the tests quickly caught it). The minutiae really do make a big difference when it comes to not writing bugs.</p>
<p>WRT the fuzzers, they helped because they are tests. Any test suite would help, it’s just that fuzzers are the only viable path to test code like this. You have to generate too much data just to get the thing to work at all, let alone the edge cases. The LSM fuzzers are still very immature, but even the most basic fuzzer runs circles around unit tests.</p>
<p>I’m sure this code is still <em>loaded</em> with bugs as I haven’t fuzzed it very aggressively yet. It’s solidifying.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379924" data-batch-url="/posts/batch_likers">
                        3
                      </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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/73">Post #72</a>
	                </div>
	            </div>
              <div id="likers-container-379924" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379924"
                     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 #72"></div>
  </section>
</div>
    <div class="postbit" id="379930" data-post-id="379930">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ll say idiomatic to whom, if you where to follow Elixir own anti-patterns then you would get slow and unoptimized code, mostly because most of the anti patterns are not derived from hard science. To me that is an anti pattern itself. As it turns out every optimized code is always smaller and more readable due to only essential abstractions and allocations. But none of this matter if you do not benchmark your code.</p>
<p>What people forget is that all these allocations here and there adds up, and the compiler cannot magically make your code faster.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379930" 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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/74">Post #73</a>
	                </div>
	            </div>
              <div id="likers-container-379930" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379930"
                     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 #73"></div>
  </section>
</div>
    <div class="postbit" id="379933" data-post-id="379933">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>It’s strange <a href="https://github.com/krestenkrab/hanoidb" rel="noopener nofollow ugc">hanoidb</a> was not mentioned yet! I remember playing with it a long time ago <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379933" 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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/75">Post #74</a>
	                </div>
	            </div>
              <div id="likers-container-379933" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379933"
                     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 #74"></div>
  </section>
</div>
    <div class="postbit" id="379947" data-post-id="379947">
  <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
                    <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">
								<aside class="quote no-group" data-username="Schultzer" data-post="74" data-topic="73003">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/schultzer/48/4339_2.png" class="avatar"> Schultzer:</div>
<blockquote>
<p>I’ll say idiomatic to whom</p>
</blockquote>
</aside>
<p>That is the question I was hinting at. In this specific case I do think flattening the list and traversing it would probably make the code a bit easier to understand. I can’t say for sure if that difference is inherent or a result of pre-conceived notions of what such code should look like. Probably both.</p>
<p>But in this case it would be an unacceptable performance cost. I am not seriously benchmarking yet (I will be soon), but I am not blind and I know what the BEAM would be doing if I flattened that list. Those cons cells gotta come from somewhere.</p>
<aside class="quote no-group" data-username="Schultzer" data-post="74" data-topic="73003">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/schultzer/48/4339_2.png" class="avatar"> Schultzer:</div>
<blockquote>
<p>As it turns out every optimized code is always smaller and more readable due to only essential abstractions and allocations.</p>
</blockquote>
</aside>
<p>I am sympathetic to the idea that this is <em>often</em> true, but definitely not always. An extreme counter-example would be branchless algorithms, which are faster in many cases (because they fool the branch predictor) but are kinda inherently less intuitive.</p>
<p>Maybe that exception proves the rule, but in general I think if optimized code was always better we’d be writing assembly. Clearly there must be a tradeoff somewhere.</p>
<p>And that tradeoff is inherent to this project: if I wanted a database that was as fast as possible I would be writing it in Zig or something. But there are other factors: accessibility is very important, and running directly in the BEAM enables a level of extensibility that, to be honest, I think could be revolutionary. That wasn’t really my goal (I just wanted to store data lol) but the value proposition has slowly revealed itself.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379947" 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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/76">Post #75</a>
	                </div>
	            </div>
              <div id="likers-container-379947" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379947"
                     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 #75"></div>
  </section>
</div>
    <div class="postbit" id="379957" data-post-id="379957">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I believe a better analog is math, to a skilled mathematician then formals transfer way more information than English would ever do. But for someone unfamiliar with math then it’s just gibberish.</p>
<p>I don’t believe we all should write assembly, some minimal abstraction are great, the best I know is Erlang. I could never have built what I’m building if not all the hard problems where already solved for me and I just had to glue it together.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379957" 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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/77">Post #76</a>
	                </div>
	            </div>
              <div id="likers-container-379957" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379957"
                     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 #76"></div>
  </section>
</div>
    <div class="postbit" id="379961" data-post-id="379961">
  <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
                    <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>To use my favorite example, Lamport somewhat begrudgingly wrote Paxos Made Simple in plain English despite believing that algorithms like Paxos are best expressed through specs/code. The end result, of course, is that the name of the paper is widely mocked; as it turns out, no matter how you specify Paxos it remains extremely confusing. And to make matters worse the translation into English <a href="https://brooker.co.za/blog/2021/11/16/paxos.html" rel="noopener nofollow ugc">introduced a bug</a> into the spec!</p>
<aside class="quote no-group" data-username="Schultzer" data-post="77" data-topic="73003">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/schultzer/48/4339_2.png" class="avatar"> Schultzer:</div>
<blockquote>
<p>I could never have built what I’m building if not all the hard problems where already solved for me and I just had to glue it together.</p>
</blockquote>
</aside>
<p>Exactly! Unfortunately the intervening four decades have, in my view, led to a rather large “strong consistency”-shaped hole in Erlang/OTP.</p>
<p>This is hardly the designers’ faults, as you may notice that Erlang actually pre-dates the first solutions to distributed consensus by two years. Let alone the two decades it took for those results to become common practice.</p>
<p>Still, the fact remains that OTP contains no useful primitives for building distributed systems with strong consistency guarantees. No consensus, no replicated storage, no autosharding, no storage engine.</p>
<p>There is an (entirely valid) argument to be made that these things are out of scope, but unfortunately Erlang <em>does</em> provide weak/mediocre implementations of all of these things: <code>:global</code>, <code>:mnesia</code>, <code>:mnesia</code>, and <code>:dets</code> respectively. I think this is important because it shows that the motivation is sound, but the implementations have not kept up with the times. We can do so much better now.</p>
<p>That is essentially what I’m trying to <em>do</em> here with Hobbes. Except it turns out that instead of having separate primitives for “consensus” and “replication” and “storage” it’s way better to have one abstraction layer that provides all of those things at once. FoundationDB can do anything Etcd can do, and it can do it in heels (scale out).</p>
<p>The other big thing is testing. One of the reasons distributed systems have gotten a bad rap in the popular consensus (haha) is that building them properly necessitates a newer testing strategy that is not yet well-known, and here of course I am speaking of (deterministic) simulation testing. Simtests are an absolute game-changer for building distributed systems. Seriously, they make the impossible possible.</p>
<p>I have now proven the viability of simtesting on the BEAM (it 100% works in practice on a real codebase), and the next step is to try to improve the performance. I am working on a new design (a replacement for Construct) which I believe will do just that.</p>
<p>All combined, I hope that I can provide a similar value proposition to Erlang: solving the hard problems for you. Or at least for me, because I am not in the mood for having to do any of this again any time soon lol.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379961" data-batch-url="/posts/batch_likers">
                        3
                      </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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/78">Post #77</a>
	                </div>
	            </div>
              <div id="likers-container-379961" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379961"
                     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 #77"></div>
  </section>
</div>
    <div class="postbit" id="381722" data-post-id="381722">
  <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
                    <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 href="https://git.sr.ht/~garrisonc/hobbes/commit/0ce7fdc717b48c5c32935655c8ff79f9617e035f" rel="noopener nofollow ugc">Fuzzer caught a pretty good one today</a>.</p>
<p>This code builds blocks for the on-disk Manifest Log and rotates the current block when it fills up. Unfortunately there was a typo and instead of prepending the new block to the blocks acc it prepended the new block to the remaining <em>entries</em>.</p>
<p>I wonder if there is a name for this sort of bug, which is obviously wrong but survives due to sheer luck. It just so happens that, technically, a single entry is a valid block, so in the right circumstances this is not <em>completely</em> broken. The fuzzer was able to find the right circumstances, but only when enough entries were running through it to trigger the condition; ironically there was a comment right above it warning me to be careful to fuzz that line. Good call! lol</p>
<p>This is also a great example of why I’m trying to be a lot more careful about naming variables. If the other tail had been named <code>entries_rest</code> (a convention I have since adopted, but only after this code was written) such a typo would be much harder to miss. Naming things carefully and caring about code structure are actually very important!</p>
<p>The reason this was finally caught today (this code must be 1-2 months old) is that I finally added updates/deletes to the log, and therefore finally implied a dependency on order. There <a href="https://git.sr.ht/~garrisonc/hobbes/commit/f09a7619c38f19e3417a132df755f0a63831a164" rel="noopener nofollow ugc">was another bug</a> caught by that change as well, where the list of blocks should have been reversed. This is why I always name reversed lists with a <code>_reversed</code> suffix, but apparently I missed that one. Thankfully the fuzzer did not.</p>
<p>These bugs together took <em>hours</em> to track down, btw. Yeah.</p>
<p>Anyway, the storage engine is coming together. I’ve rewritten most of the code since my last update, and it’s no longer garbage. I also <a href="https://corporate.fm/blog/iterators-on-iterators" rel="noopener nofollow ugc">suffered a brief bout of iterator psychosis</a> if you missed that.</p>
<p>I’ll post a proper update (maybe on the blog instead) once it’s time to move on to integration, which will be soon. I’m at the stage where I have to keep a TODO list just to remember what’s left. You know how it is.</p>
<p>P.S. As a bonus bug, <a href="https://git.sr.ht/~garrisonc/hobbes/commit/6a38f04811b64ad87fecee4ab6c7edd3669aa693" rel="noopener nofollow ugc">it turns out update_counter applies the update <em>to</em> the default value</a>, unlike <code>Map.update()</code> and others which use the default directly. Oops.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381722" data-batch-url="/posts/batch_likers">
                        9
                      </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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/79">Post #78</a>
	                </div>
	            </div>
              <div id="likers-container-381722" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381722"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="382572" data-post-id="382572">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="garrison" data-post="79" data-topic="73003">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p><a href="https://git.sr.ht/~garrisonc/hobbes/commit/0ce7fdc717b48c5c32935655c8ff79f9617e035f" rel="noopener nofollow ugc">Fuzzer caught a pretty good one today</a>.</p>
</blockquote>
</aside>
<p>Can you please clarify to a noob in testing what fuzzers are and how do you use them to catch bugs? From your post they seem pretty helpful at catching bugs.</p>
<p>Btw congrats on the revisions! Happy to see Hobbes getting better <img src="https://forum.elixirforum.com/images/emoji/apple/smiling_face.png?v=15" title=":smiling_face:" class="emoji" alt=":smiling_face:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="382572" 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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/80">Post #79</a>
	                </div>
	            </div>
              <div id="likers-container-382572" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="382572"
                     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 #79"></div>
  </section>
</div>
    <div class="postbit" id="382573" data-post-id="382573">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Fuzzers are extreme point of property testing - you are throwing garbage at the system input and look for failures to happen.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="382573" data-batch-url="/posts/batch_likers">
                        4
                      </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/hobbes-a-low-level-distributed-database-for-the-elixir-programming-language/73003/81">Post #80</a>
	                </div>
	            </div>
              <div id="likers-container-382573" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="382573"
                     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 #80"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/73003/load_more?page=9">Load more posts (6 remaining)</a>
</div></template></turbo-stream>