<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Tuna</title>
    <description>The latest articles on Forem by Tuna (@tuna99).</description>
    <link>https://forem.com/tuna99</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2193206%2F2d47c55e-dc66-43c4-9593-147b9409d5c5.jpg</url>
      <title>Forem: Tuna</title>
      <link>https://forem.com/tuna99</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tuna99"/>
    <language>en</language>
    <item>
      <title>Why Memory Alignment Matters in Go: Making Your Structs Lean and Fast</title>
      <dc:creator>Tuna</dc:creator>
      <pubDate>Thu, 03 Apr 2025 11:34:14 +0000</pubDate>
      <link>https://forem.com/tuna99/why-memory-alignment-matters-in-go-making-your-structs-lean-and-fast-1kfk</link>
      <guid>https://forem.com/tuna99/why-memory-alignment-matters-in-go-making-your-structs-lean-and-fast-1kfk</guid>
      <description>&lt;p&gt;When writing Go code, it’s easy to forget what’s happening under the hood—especially when it comes to memory layout. But did you know that how you organize fields in a &lt;code&gt;struct&lt;/code&gt; can actually bloat memory and even affect performance?&lt;/p&gt;

&lt;p&gt;Let’s take a fun but technical dive into how memory alignment works in Go, and why struct layout matters more than you might think.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What Is Memory Alignment, Exactly?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Memory alignment&lt;/strong&gt; is a concept rooted in how CPUs access memory. Most modern CPUs are optimized to access memory at &lt;strong&gt;aligned addresses&lt;/strong&gt;—that is, addresses that are multiples of the data’s size.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;int64&lt;/code&gt; (8 bytes) should ideally start at a memory address that’s a multiple of 8.&lt;/li&gt;
&lt;li&gt;An &lt;code&gt;int32&lt;/code&gt; (4 bytes) should start at a multiple of 4.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a variable is &lt;strong&gt;misaligned&lt;/strong&gt;, the CPU might need to perform &lt;strong&gt;multiple memory reads&lt;/strong&gt; just to get the full data. This slows things down. On top of that, if a variable &lt;strong&gt;spans across two cache lines&lt;/strong&gt;, you’ll suffer a performance penalty because the CPU has to load both cache lines.&lt;/p&gt;

&lt;p&gt;Here’s a simple analogy: imagine reading a sentence split across two pages in a book. You flip once, then again, just to get the whole message. Alignment keeps your "sentence" on the same page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aligned data = fast memory access
&lt;/li&gt;
&lt;li&gt;Misaligned data = slow, possibly multiple reads
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ How Go Handles Memory Alignment
&lt;/h2&gt;

&lt;p&gt;Go takes care of alignment &lt;em&gt;automatically&lt;/em&gt;. Each data type has an alignment requirement, and Go inserts &lt;strong&gt;padding bytes&lt;/strong&gt; between struct fields to ensure proper alignment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s look at this struct:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;PoorlyAligned&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;  &lt;span class="c"&gt;// 8 bytes&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although the fields themselves total 9 bytes, the compiler inserts padding to align each field properly. This results in:&lt;/p&gt;

&lt;p&gt;📆 &lt;strong&gt;Total size: 24 bytes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Offset&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;a (byte)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;padding&lt;/td&gt;
&lt;td&gt;1–7&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;To align &lt;code&gt;int64&lt;/code&gt; on 8-byte boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;b (int64)&lt;/td&gt;
&lt;td&gt;8–15&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Starts at offset 8.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;c (byte)&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Starts at offset 16.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;padding&lt;/td&gt;
&lt;td&gt;17–23&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;To round struct size to 8-byte multiple&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ✅ Well-Aligned Layout = Happy Memory
&lt;/h2&gt;

&lt;p&gt;Now let’s rearrange the fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;WellAligned&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;  &lt;span class="c"&gt;// 8 bytes&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;📆 &lt;strong&gt;Total size: 16 bytes&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Offset&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;b (int64)&lt;/td&gt;
&lt;td&gt;0–7&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a (byte)&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;c (byte)&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;padding&lt;/td&gt;
&lt;td&gt;10–15&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;💡 By simply reordering the fields, we reduced the struct's size from 24 bytes down to 16 bytes—saving 8 bytes for every single instance of this struct.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Real-World Impact: Memory and Performance
&lt;/h2&gt;

&lt;p&gt;Why does this matter?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less memory per struct = lower overall memory usage
&lt;/li&gt;
&lt;li&gt;Smaller structs fit better into CPU cache lines
&lt;/li&gt;
&lt;li&gt;Better cache usage = fewer cache misses = faster processing
&lt;/li&gt;
&lt;li&gt;Less memory used = less work for the garbage collector&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔬 Benchmarking Time!
&lt;/h3&gt;

&lt;p&gt;Let’s benchmark two slices: one using the poorly-aligned struct, one using the optimized version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;PoorlyAligned&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;  &lt;span class="c"&gt;// 8 bytes&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;WellAligned&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;  &lt;span class="c"&gt;// 8 bytes&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;poorlySlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;PoorlyAligned&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;_000_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wellSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;WellAligned&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;_000_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkPoorlyAligned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;poorlySlice&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;poorlySlice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkWellAligned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;wellSlice&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;wellSlice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📊 Typical Results:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;goos&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;darwin&lt;/span&gt;
&lt;span class="n"&gt;goarch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arm64&lt;/span&gt;
&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;metaleap&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tunatest&lt;/span&gt;
&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Apple&lt;/span&gt; &lt;span class="n"&gt;M1&lt;/span&gt;
&lt;span class="n"&gt;BenchmarkPoorlyAligned&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;            &lt;span class="m"&gt;3609&lt;/span&gt;            &lt;span class="m"&gt;323200&lt;/span&gt; &lt;span class="n"&gt;ns&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;
&lt;span class="n"&gt;BenchmarkWellAligned&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;              &lt;span class="m"&gt;3759&lt;/span&gt;            &lt;span class="m"&gt;316617&lt;/span&gt; &lt;span class="n"&gt;ns&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;
&lt;span class="n"&gt;PASS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;✅ &lt;strong&gt;Result:&lt;/strong&gt; On my Apple M1 chip, optimizing the struct layout resulted in a ~2% performance improvement.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🛠️ Tools: Check Alignment with &lt;code&gt;go vet&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You don’t need to do this manually. Go provides a vetting tool to help:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go vet &lt;span class="nt"&gt;-fieldalignment&lt;/span&gt; ./...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will suggest better ordering for your structs when applicable, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct with 24 bytes could be 16 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ Best Practices for Struct Layout in Go
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Order fields from &lt;strong&gt;largest to smallest alignment&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Group fields with the same size together.&lt;/li&gt;
&lt;li&gt;Consider memory layout when defining high-volume or performance-critical structs.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;go vet -fieldalignment&lt;/code&gt; for automatic suggestions.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📝 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Memory alignment is one of those “under-the-hood” details that can have outsized effects in real-world programs—especially those dealing with millions of objects or high-performance data processing.&lt;/p&gt;

&lt;p&gt;With just a bit of attention to field ordering, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save memory&lt;/li&gt;
&lt;li&gt;Speed up your programs&lt;/li&gt;
&lt;li&gt;Make your data more cache-friendly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go’s compiler does the heavy lifting to ensure safety and correctness. Your job is to &lt;strong&gt;be mindful of layout&lt;/strong&gt; when performance or memory use matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://goperf.dev/01-common-patterns/fields-alignment/" rel="noopener noreferrer"&gt;Go Optimization Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/fieldalignment" rel="noopener noreferrer"&gt;Go &lt;code&gt;go vet&lt;/code&gt; fieldalignment Analyzer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>performance</category>
      <category>programming</category>
    </item>
    <item>
      <title>Go 1.24 and the Swiss Table Revolution: A New Era for Maps</title>
      <dc:creator>Tuna</dc:creator>
      <pubDate>Mon, 03 Feb 2025 11:36:27 +0000</pubDate>
      <link>https://forem.com/tuna99/go-124-and-the-swiss-table-revolution-a-new-era-for-maps-1pdj</link>
      <guid>https://forem.com/tuna99/go-124-and-the-swiss-table-revolution-a-new-era-for-maps-1pdj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;With the release of Go 1.24, the language takes a significant leap forward in performance optimization—this time, targeting one of its most fundamental data structures: the map. Inspired by Google’s high-performance Swiss Table (popularized in C++’s Abseil library), the Go team has re-engineered the internals of its map implementation to deliver faster lookups, reduced memory overhead, and better cache utilization. This change marks a pivotal shift in how Go handles hash tables, addressing long-standing inefficiencies while embracing modern hash table design principles. Let’s dive into how this transformation works and why it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: The Old Map (A Quick Refresher)
&lt;/h2&gt;

&lt;p&gt;Before Go 1.24, maps worked like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Buckets: Your keys were stored in &lt;code&gt;buckets&lt;/code&gt; (groups of 8 entries).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Overflow Chains: If a bucket filled up, new entries went into &lt;code&gt;overflow&lt;/code&gt; buckets, linked like a chain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tophash: Each entry had a tiny &lt;code&gt;tophash&lt;/code&gt; (8 bits of the key’s hash) to skip non-matching keys quickly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It worked, but it had some rough edges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Slow Lookups: Scanning overflow chains meant jumping around in memory (hello, cache misses!).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memory Bloat: Overflow buckets ate up extra space.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resizing Woes: Growing the map meant rehashing everything. Ouch.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Want to dive deeper into the old design? Check out &lt;a href="https://victoriametrics.com/blog/go-map" rel="noopener noreferrer"&gt;this great explainer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: Swiss Table Deep Dive—How It Handles Collisions Like a Pro
&lt;/h2&gt;

&lt;p&gt;Let’s break down the Swiss Table’s secret sauce step-by-step, using a concrete example. Spoiler: It’s all about &lt;strong&gt;smart metadata&lt;/strong&gt; and &lt;strong&gt;cache-friendly groups&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Hash Splitting (H1 vs. H2)
&lt;/h3&gt;

&lt;p&gt;Imagine you insert the key &lt;code&gt;price&lt;/code&gt; into a Go map. The hash function generates a 64-bit value, say:&lt;br&gt;
&lt;code&gt;H = 0x5F4A3B2C1D&lt;/code&gt; (simplified for clarity).&lt;/p&gt;

&lt;p&gt;The Swiss Table splits this hash into two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;H2 (7 bits): The first 7 bits of the hash. Think of this as a "mini fingerprint" of the key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;H1 (57 bits): The remaining bits. This determines which group the key belongs to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;H2 = First 7 bits of &lt;code&gt;0x5F4A3B2C1D&lt;/code&gt; → &lt;code&gt;0x5F&lt;/code&gt; (binary: &lt;code&gt;01011111&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;H1 = The rest → Used to calculate the group index.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 2: Metadata—The Magic Cheat Sheet
&lt;/h3&gt;

&lt;p&gt;Every entry in the map has a 1-byte metadata field. This byte stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The 7-bit H2 value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A 1-bit status flag:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0: Empty.&lt;/li&gt;
&lt;li&gt;1: Occupied.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0x80&lt;/code&gt; (binary &lt;code&gt;10000000&lt;/code&gt;): Tombstone (deleted).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
When you insert &lt;code&gt;price&lt;/code&gt;, Go stores &lt;code&gt;0x5F&lt;/code&gt; in the metadata (since its H2 is &lt;code&gt;0x5F&lt;/code&gt;) and marks the status as 1 (occupied). The full metadata byte becomes &lt;code&gt;0x5F&lt;/code&gt; | &lt;code&gt;0x01&lt;/code&gt; = &lt;code&gt;0x5F1&lt;/code&gt; (simplified).&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3: Group Hunting with H1
&lt;/h3&gt;

&lt;p&gt;The map is divided into groups of 16 entries. To find where "price" belongs:&lt;/p&gt;

&lt;p&gt;Use H1 to calculate the group index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;group_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;H1&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;number_of_groups&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the metadata of all 16 entries in that group.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
If H1 points to Group 3, Go scans the 16 metadata bytes in Group 3.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Handling Collisions (No Linked Lists!)
&lt;/h3&gt;

&lt;p&gt;If Group 3 is full, here’s what happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Linear Probing: Go checks the next group (Group 4, then Group 5, etc.) until it finds an empty slot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tombstones: If a slot is marked as deleted (tombstone), it’s treated as empty for insertion but preserved for lookups.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why This Rocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No more chasing linked lists—everything stays in contiguous memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CPU caches love this (fewer cache misses!).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example Walkthrough:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Insert &lt;code&gt;price&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hash: &lt;code&gt;price&lt;/code&gt; → H = 0x5F4A3B2C1D.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Split:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;H2 = 0x5F → stored in metadata.&lt;/li&gt;
&lt;li&gt;H1 → calculates group index (e.g., Group 3).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Check Group 3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If Slot 5 in Group 3 is empty → insert "price" there.&lt;/li&gt;
&lt;li&gt;If Slot 5 is occupied, check Slot 6, then Slot 7, etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Collision? If Group 3 is full, move to Group 4.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Lookup &lt;code&gt;price&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Compute H2 = 0x5F.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to the group calculated by H1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scan the group’s metadata for 0x5F.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Match found: Compare the actual key (to handle hash collisions).&lt;/li&gt;
&lt;li&gt;No match: Skip to the next group.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This skips 99% of non-matching keys without even looking at the keys!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Beats the Old Map
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Old Map&lt;/th&gt;
&lt;th&gt;Swiss Table Map&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Used linked lists for collisions&lt;/td&gt;
&lt;td&gt;Uses linear probing (no pointers!)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scanned keys one-by-one&lt;/td&gt;
&lt;td&gt;Metadata filters out mismatches instantly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overflow buckets wasted memory&lt;/td&gt;
&lt;td&gt;Tombstones reuse space efficiently&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Final Takeaway
&lt;/h2&gt;

&lt;p&gt;The Swiss Table’s genius lies in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Metadata: A tiny cheat sheet to skip useless work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Groups: Cache-friendly memory layout.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linear Probing: Simpler, faster collision handling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go 1.24’s new map isn’t just faster—it’s smarter. And you get all this without changing a single line of your code! 🎉&lt;/p&gt;

&lt;p&gt;👉 For benchmarks and nitty-gritty details, check out &lt;a href="https://www.bytesizego.com/blog/go-124-swiss-table-maps" rel="noopener noreferrer"&gt;this post&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Still have questions? Drop them in the comments! 👇&lt;/p&gt;

</description>
      <category>go</category>
      <category>performance</category>
      <category>programming</category>
      <category>map</category>
    </item>
    <item>
      <title>MongoDB Indexes: The Superpower to Speed Up Your Queries ⚡</title>
      <dc:creator>Tuna</dc:creator>
      <pubDate>Mon, 11 Nov 2024 05:00:26 +0000</pubDate>
      <link>https://forem.com/tuna99/mongodb-indexes-the-superpower-to-speed-up-your-queries-3lea</link>
      <guid>https://forem.com/tuna99/mongodb-indexes-the-superpower-to-speed-up-your-queries-3lea</guid>
      <description>&lt;p&gt;Imagine walking into a massive library to find a single book. Without an index or catalog, you’d have to go shelf by shelf, scanning every title—sounds exhausting, right? MongoDB indexes are like a magical catalog that speeds up your searches, so MongoDB can find what it needs in a flash.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstqx8o3aigussvqoz24c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstqx8o3aigussvqoz24c.png" alt="Index" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just like library catalogs, indexes make data retrieval way faster. MongoDB uses a clever little structure called a B-tree to keep everything organized. B-trees allow MongoDB to skip over data that’s irrelevant to your search.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Want to know more about B-trees? Check out this awesome blog on &lt;a href="https://dev.to/tuna99/b-tree-the-secret-recipe-behind-efficient-data-handling-5do8"&gt;B-trees&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Types of MongoDB Indexes
&lt;/h2&gt;

&lt;p&gt;MongoDB offers several types of indexes, each with its own quirks and superpowers. Let’s take a look! 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  Single Field Index
&lt;/h3&gt;

&lt;p&gt;This is your classic, no-frills index, created on a single field. If you have a collection of users and often query by &lt;code&gt;username&lt;/code&gt;, creating a single field index on &lt;code&gt;username&lt;/code&gt; helps MongoDB find &lt;code&gt;username&lt;/code&gt; quickly instead of skimming through every document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.users.createIndex&lt;span class="o"&gt;({&lt;/span&gt; username: 1 &lt;span class="o"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;username&lt;/code&gt; is the field we’re indexing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; means ascending order (you could also use &lt;code&gt;-1&lt;/code&gt; for descending order).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Compound Indexes
&lt;/h3&gt;

&lt;p&gt;Need to search by multiple fields? A compound index includes more than one field, making multi-field searches lightning fast! Imagine a shopping app where you often query category and price. A compound index lets MongoDB efficiently find items in that category and price range.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.products.createIndex&lt;span class="o"&gt;({&lt;/span&gt; category: 1, price: &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB can use this index to search by both &lt;code&gt;category&lt;/code&gt; and &lt;code&gt;price&lt;/code&gt;, or just &lt;code&gt;category&lt;/code&gt; (since it’s the first field in the index). However, searches only on &lt;code&gt;price&lt;/code&gt; won’t use this index.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: If you have both a compound index &lt;code&gt;{ a: 1, b: 1 }&lt;/code&gt; and a single index &lt;code&gt;{ a: 1 }&lt;/code&gt;, consider removing the single index. MongoDB will happily use the compound index for both!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Multikey Indexes
&lt;/h3&gt;

&lt;p&gt;Multikey indexes are MongoDB’s answer for indexing arrays. If you have a tags field storing an array (like &lt;code&gt;["electronics", "computing", "portable"]&lt;/code&gt;), creating a multikey index lets MongoDB search each element as if it were a standalone field.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.products.createIndex&lt;span class="o"&gt;({&lt;/span&gt; tags: 1 &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Laptop"&lt;/span&gt;,
  &lt;span class="s2"&gt;"tags"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"electronics"&lt;/span&gt;, &lt;span class="s2"&gt;"computing"&lt;/span&gt;, &lt;span class="s2"&gt;"portable"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB uses the multikey index to find all products tagged with &lt;code&gt;computing&lt;/code&gt; without digging through each tag manually.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Compound indexes can have only one array field. Also, multikey indexes can get hefty for large arrays, so be mindful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Index Properties
&lt;/h2&gt;

&lt;p&gt;Index properties affect how the query planner uses an index and how indexed documents are stored. You can specify index properties as optional parameters when you create an index.&lt;/p&gt;

&lt;h3&gt;
  
  
  Case-Insensitive Indexes
&lt;/h3&gt;

&lt;p&gt;Need case-insensitive searches? Use collation options when creating indexes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.fruit.createIndex&lt;span class="o"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
   &lt;span class="o"&gt;{&lt;/span&gt; collation: &lt;span class="o"&gt;{&lt;/span&gt; locale: &lt;span class="s1"&gt;'en'&lt;/span&gt;, strength: 2 &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will allow you to find all variations of &lt;code&gt;apple&lt;/code&gt; (like &lt;code&gt;Apple&lt;/code&gt; or &lt;code&gt;APPLE&lt;/code&gt;). Just remember that your queries also need to specify the same &lt;a href="https://www.mongodb.com/docs/manual/reference/collation/#std-label-collation-document-fields" rel="noopener noreferrer"&gt;collation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Partial Indexes
&lt;/h3&gt;

&lt;p&gt;Want an index that only includes specific documents? A partial index lets you add a filter, so only documents that meet the condition are indexed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.restaurants.createIndex&lt;span class="o"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;{&lt;/span&gt; cuisine: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
   &lt;span class="o"&gt;{&lt;/span&gt; partialFilterExpression: &lt;span class="o"&gt;{&lt;/span&gt; rating: &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$gt&lt;/span&gt;: 5 &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only restaurants with a rating greater than 5 will be indexed—less storage, more efficiency!&lt;/p&gt;

&lt;h3&gt;
  
  
  Sparse Indexes
&lt;/h3&gt;

&lt;p&gt;A sparse index skips any documents that don’t have the indexed field, unlike other indexes which include every document, even if the field is missing or null.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.scores.createIndex&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; score: 1 &lt;span class="o"&gt;}&lt;/span&gt; , &lt;span class="o"&gt;{&lt;/span&gt; sparse: &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps MongoDB return only documents that actually have a score field when you query based on that field.&lt;/p&gt;

&lt;h3&gt;
  
  
  TTL Indexes
&lt;/h3&gt;

&lt;p&gt;TTL indexes automatically remove documents after a set time. Great for logs, session data, or anything that only needs to live temporarily.&lt;/p&gt;

&lt;p&gt;The TTL index &lt;code&gt;expireAfterSeconds&lt;/code&gt; value must be within &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;2147483647&lt;/code&gt; inclusive.&lt;/p&gt;

&lt;p&gt;Here, documents expire after 1 hour (3600 seconds) from their &lt;code&gt;lastModifiedDate&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.eventlog.createIndex&lt;span class="o"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;{&lt;/span&gt; lastModifiedDate: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
   &lt;span class="o"&gt;{&lt;/span&gt; expireAfterSeconds: 3600 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create a TTL index with a Partial Index to expire documents with specific filter expressions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.eventlog.createIndex&lt;span class="o"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"lastModifiedDate"&lt;/span&gt;: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
   &lt;span class="o"&gt;{&lt;/span&gt;
      name: &lt;span class="s2"&gt;"Partial-TTL-Index"&lt;/span&gt;,
      partialFilterExpression: &lt;span class="o"&gt;{&lt;/span&gt; canDelete : &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
      expireAfterSeconds: 10
   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unique Indexes
&lt;/h3&gt;

&lt;p&gt;A unique index ensures no duplicate values for the indexed field. MongoDB automatically makes the &lt;code&gt;_id&lt;/code&gt; field unique, but you can add unique constraints to other fields, too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.members.createIndex&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"user_id"&lt;/span&gt;: 1 &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt; unique: &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need a unique constraint on a combination of fields? No problem! With compound unique indexes, MongoDB enforces uniqueness across the combination of the index key values, so only a unique pair of values for each indexed field can exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.users.createIndex&lt;span class="o"&gt;({&lt;/span&gt; firstName: 1, lastName: 1 &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt; unique: &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes, you don’t want a unique constraint across your whole collection—just a specific subset of documents. With &lt;code&gt;partialFilterExpression&lt;/code&gt;, you can apply a unique constraint only to documents that match certain criteria, while the rest of the documents ignore it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.events.createIndex&lt;span class="o"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;{&lt;/span&gt; userId: 1, status: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
   &lt;span class="o"&gt;{&lt;/span&gt;
      unique: &lt;span class="nb"&gt;true&lt;/span&gt;,
      partialFilterExpression: &lt;span class="o"&gt;{&lt;/span&gt; status: &lt;span class="s2"&gt;"active"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The unique constraint only applies to documents that &lt;em&gt;match the filter expression&lt;/em&gt;. MongoDB won’t prevent you from inserting documents that don’t meet the unique constraint if they don’t satisfy the filter criteria.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Wrap-Up 🎉
&lt;/h2&gt;

&lt;p&gt;Indexes are your friends! They make MongoDB queries way faster, helping you find exactly what you need without MongoDB combing through the entire collection. Whether you’re indexing single fields, arrays, or setting up TTL for auto-cleanup, each index type has its own special trick to speed things up. Just remember, indexes do require some storage, so don’t go overboard.&lt;/p&gt;

&lt;p&gt;Happy querying, and may the MongoDB index force be with you! 🖖&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>database</category>
      <category>programming</category>
      <category>performance</category>
    </item>
    <item>
      <title>Understanding Iterators in Go: A Fun Dive!</title>
      <dc:creator>Tuna</dc:creator>
      <pubDate>Thu, 24 Oct 2024 11:08:28 +0000</pubDate>
      <link>https://forem.com/tuna99/understanding-iterators-in-go-a-fun-dive-1c57</link>
      <guid>https://forem.com/tuna99/understanding-iterators-in-go-a-fun-dive-1c57</guid>
      <description>&lt;p&gt;If you're a Go programmer, you've probably heard about iterators many times in Go &lt;strong&gt;1.22&lt;/strong&gt;, and especially in Go &lt;strong&gt;1.23&lt;/strong&gt;. But maybe you're still scratching your head, wondering why they're useful or when you should use them. Well, you're in the right place! Let's start by looking at how iterators work in Go and why they can be so useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Transformation: No Iterator Yet
&lt;/h2&gt;

&lt;p&gt;Imagine we have a list of numbers, and we want to double each number. We could do this using a straightforward function like the one below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NormalTransform&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;transformed&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;transformed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;transformed&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;doubleFunc&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;NormalTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doubleFunc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s what happens when you run this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 2
1 4
2 6
3 8
4 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty simple, right? This is a basic generic Go function that takes a list of any type &lt;code&gt;T1&lt;/code&gt;, applies a transformation function to each element, and returns a new list with the transformed list of any type &lt;code&gt;T2&lt;/code&gt;. Easy to understand if you know Go &lt;strong&gt;generics&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;But what if I told you there’s another way to handle this—using an iterator?&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter the Iterator!
&lt;/h2&gt;

&lt;p&gt;Now, let’s take a look at how you might use an iterator for the same transformation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;IteratorTransform&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seq2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;doubleFunc&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;NormalTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doubleFunc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before running it, you must make sure your Go version is &lt;strong&gt;1.23&lt;/strong&gt;. The output is exactly the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 2
1 4
2 6
3 8
4 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But wait, why would we need an iterator here? Isn't that more complicated? Let’s dig into the differences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use an Iterator?
&lt;/h2&gt;

&lt;p&gt;At first glance, iterators seem a bit over-engineered for something as simple as transforming a list. But when you run benchmarks, you start to see why they’re worth considering!&lt;/p&gt;

&lt;p&gt;Let’s benchmark both methods and see how they perform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;list&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkNormalTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;NormalTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkIteratorTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IteratorTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the initial benchmark result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BenchmarkNormalTransform-8      41292933                29.49 ns/op
BenchmarkIteratorTransform-8    1000000000               0.3135 ns/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whoa! That’s a huge difference! But hold on—there’s a bit of unfairness here. The &lt;code&gt;NormalTransform&lt;/code&gt; function returns a fully transformed list, while the IteratorTransform function only sets up the iterator without transforming the list yet.&lt;/p&gt;

&lt;p&gt;Let’s make it fair by fully looping through the iterator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkIteratorTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;IteratorTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the results are more reasonable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BenchmarkNormalTransform-8      40758822                29.16 ns/op
BenchmarkIteratorTransform-8    53967146                22.39 ns/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, the iterator is a bit faster. Why? Because &lt;code&gt;NormalTransform&lt;/code&gt; creates an entire transformed list in memory (on the heap) before returning it, while the iterator does the transformation as you loop through it, saving time and memory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Read more about &lt;strong&gt;Stack and Heap&lt;/strong&gt; &lt;a href="https://dev.to/tuna99/understanding-stack-and-heap-in-go-a-simple-guide-20i"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The iterator's real magic happens when you don’t need to process the whole list. Let’s benchmark a scenario where we only want to find the number &lt;code&gt;4&lt;/code&gt; after transforming the list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkNormalTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;NormalTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkIteratorTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;IteratorTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results speak for themselves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BenchmarkNormalTransform-8      39599744                30.03 ns/op
BenchmarkIteratorTransform-8    164853723                7.288 ns/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the iterator is much faster! Why? Because the iterator doesn’t transform the entire list—it stops as soon as it finds the result you’re looking for. On the other hand, &lt;code&gt;NormalTransform&lt;/code&gt; still transforms the entire list, even if we only care about one item.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: When to Use Iterators?
&lt;/h2&gt;

&lt;p&gt;So, why use an iterator in Go?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency&lt;/strong&gt;: Iterators can save both time and memory by not processing the entire list if you don’t need it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: They allow you to handle large datasets efficiently, especially when working with streams of data or when you need to stop early.
But keep in mind, iterators can be a bit trickier to understand and implement. Use them when you need that extra performance boost, especially in scenarios where you don’t need to work with an entire list upfront.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Iterators: They're fast, flexible, and fun—once you get the hang of them!&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>coding</category>
      <category>performance</category>
    </item>
    <item>
      <title>B-tree: The Secret Recipe Behind Efficient Data Handling 🍰</title>
      <dc:creator>Tuna</dc:creator>
      <pubDate>Sat, 19 Oct 2024 16:58:28 +0000</pubDate>
      <link>https://forem.com/tuna99/b-tree-the-secret-recipe-behind-efficient-data-handling-5do8</link>
      <guid>https://forem.com/tuna99/b-tree-the-secret-recipe-behind-efficient-data-handling-5do8</guid>
      <description>&lt;p&gt;Have you ever wondered how databases keep your data sorted and quickly accessible? It’s all thanks to B-trees! These powerful data structures are behind the scenes in many database systems, file storage systems, and your computer’s operating system. Let’s break down B-trees in an easy way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a B-tree? 🌳
&lt;/h2&gt;

&lt;p&gt;B-tree is a self-balancing data structure that keeps data sorted and supports efficient searches, sequential access, insertions, and deletions in logarithmic time. It extends the concept of a binary search tree by permitting nodes to have more than two children.&lt;/p&gt;

&lt;p&gt;A B-tree is a self-balancing search tree defined by the following properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maximum Children&lt;/strong&gt;: Every node can have up to m children.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimum Children&lt;/strong&gt;: Every internal node (except the root and leaves) has at least ⌈m/2⌉ children.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Root Node&lt;/strong&gt;: The root has at least two children unless it's a leaf.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaf Level Consistency&lt;/strong&gt;: All leaves exist on the same level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keys and Separation&lt;/strong&gt;: A non-leaf node with k children has k-1 keys, which serve as separation values dividing the node’s children.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How B-trees Work: An Easy Breakdown ⚙️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Searching a Key 🔍
&lt;/h3&gt;

&lt;p&gt;In a B-tree, each node contains multiple keys, and a search starts from the root, comparing the key against all keys in the node. If the key isn’t found, the appropriate child node is followed. Each node reduces the search range considerably because B-trees remain balanced, with multiple keys per node. This ensures a worst-case time complexity of O(logₘ n), where m is the order of the B-tree (maximum number of children) and n is the number of elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inserting a Key 🎯
&lt;/h3&gt;

&lt;p&gt;Inserting data into a B-tree is like putting a book into a sorted bookshelf. The B-tree checks where it belongs finds the right place, and slides it in while keeping everything neat. If a shelf (node) gets too full, it splits into two smaller shelves, keeping the tree balanced.&lt;/p&gt;

&lt;p&gt;Sounds easy, right? Let’s dive into an example to see how it works:&lt;/p&gt;

&lt;p&gt;We have a B-tree where each node can have up to 4 children. Our task is to add key 10.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7anx8uy0x8px2a3ez7ri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7anx8uy0x8px2a3ez7ri.png" alt="Insert1" width="701" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, we find the right spot and place it in the correct order.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4b0ucd82gehjagrne5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4b0ucd82gehjagrne5t.png" alt="Insert2" width="741" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uh-oh! The node now has 5 children, which exceeds the maximum allowed for a single node. We must split it in half and push the middle key to the parent node.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpst5pkpha152r2u9as6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpst5pkpha152r2u9as6.png" alt="Insert3" width="706" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But wait—the top node is full! So, we repeat the process until the tree satisfies all its rules. Now, we get the balanced B-tree shown below!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkk4wxyj4s9lavsddxlv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkk4wxyj4s9lavsddxlv.png" alt="Insert4" width="701" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deleting a Key 🗑️
&lt;/h3&gt;

&lt;p&gt;Deleting a key from a B-tree is a bit more complex. The tree must ensure that after deletion, the structure remains balanced:&lt;/p&gt;

&lt;h4&gt;
  
  
  Deleting a Key from a Leaf Node:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplest Case&lt;/strong&gt;: If the key is in a leaf node, it can be directly removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rebalancing&lt;/strong&gt;: After deletion, if the node still has enough keys (≥⌈m/2⌉), no further action is needed. If it falls below this minimum, the node needs to borrow a key from a sibling or merge with a sibling, ensuring the B-tree properties are maintained.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Deleting a Key from an Internal (Middle) Node:
&lt;/h4&gt;

&lt;p&gt;This case is trickier because internal nodes serve as separators for their subtrees. There are two approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Replace with Predecessor/Successor&lt;/strong&gt;: Replace the key with its predecessor (the largest key from the left subtree) or successor (the smallest key from the right subtree), then delete the predecessor/successor from its leaf node. This may trigger a recursive deletion in the leaf.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Merge or Borrow&lt;/strong&gt;: If the node becomes underfilled after deletion (fewer than ⌈m/2⌉ keys), borrowing a key from an adjacent sibling or merging with a sibling is required. This ensures that the tree remains balanced. If merging happens, a key from the parent node must move down, potentially requiring further rebalancing up the tree.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s say a B-tree of order 4 has the following structure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfoz21y3wlidf978k59o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfoz21y3wlidf978k59o.png" alt="Delete2" width="800" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the example shown in the image, when we delete the root key 15 (an internal node), we follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Replace Key&lt;/strong&gt;: We replace 15 with the largest key from the left subtree, which is 10 (we could also use the smallest key from the right subtree, 20).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Remove Key&lt;/strong&gt;: After replacement, we remove 10 from the leaf node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Merge&lt;/strong&gt;: Since the left leaf node now has fewer keys than required (below the minimum), we merge it with its sibling to maintain the B-tree properties.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps the B-tree balanced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why B-trees Dominate Databases
&lt;/h2&gt;

&lt;p&gt;Let’s consider a database with &lt;strong&gt;1 million records&lt;/strong&gt; stored on a disk, where finding one record using binary search would take &lt;strong&gt;20 comparisons&lt;/strong&gt; ( log2 (1,000,000) ≈ 20). Each comparison requires a disk read, and since each disk read takes around &lt;strong&gt;10 milliseconds&lt;/strong&gt;, searching would take &lt;strong&gt;0.2 seconds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, databases improve this process using B-trees. By grouping data into disk blocks (e.g., 100 records per block) and using an index structure, B-trees dramatically reduce the number of disk reads. A B-tree with &lt;strong&gt;100 entries per node&lt;/strong&gt; reduces the number of reads to about &lt;strong&gt;3 disk reads&lt;/strong&gt; (because log100 (1,000,000) = 3), taking just &lt;strong&gt;30 milliseconds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In practice, B-trees ensure efficient searching because they minimize disk reads. This is critical in databases, where disk access is slow compared to in-memory comparisons. With fewer disk reads, B-trees make searches faster by using logarithmic time based on the number of children per node (logₘ n), where m can be large, making search times drastically shorter than in a binary search tree (BST).&lt;/p&gt;

&lt;h2&gt;
  
  
  In Conclusion
&lt;/h2&gt;

&lt;p&gt;B-trees are like the librarians of data structures, ensuring everything is neatly organized, quickly accessible, and always balanced. Whether you're dealing with small data sets or massive databases, B-trees keep your data sorted and efficient behind the scenes! 🌳&lt;/p&gt;

&lt;p&gt;For more in-depth information on B-trees, you can check out &lt;a href="https://en.wikipedia.org/wiki/B-tree" rel="noopener noreferrer"&gt;this detailed explanation on Wikipedia&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>database</category>
      <category>programming</category>
      <category>coding</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Understanding Stack and Heap in Go: A Simple Guide</title>
      <dc:creator>Tuna</dc:creator>
      <pubDate>Sun, 13 Oct 2024 15:59:45 +0000</pubDate>
      <link>https://forem.com/tuna99/understanding-stack-and-heap-in-go-a-simple-guide-20i</link>
      <guid>https://forem.com/tuna99/understanding-stack-and-heap-in-go-a-simple-guide-20i</guid>
      <description>&lt;p&gt;When you start learning Go, or any programming language for that matter, you will often hear about stack and heap memory. These two areas of memory are super important for understanding how your program runs and manages data behind the scenes. But don’t worry—today, we’ll explain them in an easy-to-understand way with a fun twist.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Stack?
&lt;/h2&gt;

&lt;p&gt;Imagine the stack as a neat pile of trays in a cafeteria. Every time someone needs a tray, they grab one from the top. And when they return a tray, they put it back on top of the pile. The stack in Go works similarly!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The stack is a small, super-fast memory area.&lt;/li&gt;
&lt;li&gt;It stores things like function calls and local variables (like integers or small structs).&lt;/li&gt;
&lt;li&gt;Every time a function is called, Go adds a “tray” (frame) to the top of the stack. When the function finishes, it removes that tray from the top.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, the stack follows a &lt;strong&gt;LIFO&lt;/strong&gt; (Last In, First Out) system, just like how you’d take and return trays.&lt;/p&gt;

&lt;p&gt;Example: Stack in Action&lt;br&gt;
Let’s say we have this simple Go code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Hello, "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s what happens step-by-step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go puts a tray on the stack for the &lt;code&gt;main&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt; calls &lt;code&gt;greet()&lt;/code&gt;, so another tray (stack frame) is added for &lt;code&gt;greet()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;greet&lt;/code&gt; function creates a local variable message, and Go places that in the tray.&lt;/li&gt;
&lt;li&gt;Once &lt;code&gt;greet()&lt;/code&gt; is done, that tray is removed (popped) from the stack.&lt;/li&gt;
&lt;li&gt;Finally, when &lt;code&gt;main&lt;/code&gt; is done, the last tray is removed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neat and organized, right? The stack is perfect for handling things that are temporary and go away quickly—like local variables inside functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Heap?
&lt;/h2&gt;

&lt;p&gt;Now, let’s imagine the heap as a large playground. Unlike the stack, where you can only add or remove things from the top, the heap is more like a big open area where you can put things anywhere.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;heap&lt;/strong&gt; is a much larger memory space.&lt;/li&gt;
&lt;li&gt;It is used to store data that needs to stick around for a while, even after a function finishes.&lt;/li&gt;
&lt;li&gt;Things stored on the heap have no specific order, and Go has to keep track of them using something called &lt;strong&gt;pointers&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While the heap is big and can store more data, it’s slower to access than the stack because Go has to figure out where things are and clean up after itself. Go has a &lt;strong&gt;garbage collector&lt;/strong&gt; that automatically tidies up unused heap memory, just like someone sweeping up the playground.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Heap in Action&lt;/strong&gt;&lt;br&gt;
Take a look at this Go code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;newUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;newUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s how the heap comes into play:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt; calls &lt;code&gt;newUser()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Inside &lt;code&gt;newUser&lt;/code&gt;, we create a new &lt;code&gt;User&lt;/code&gt; struct with the &lt;code&gt;name&lt;/code&gt; field.&lt;/li&gt;
&lt;li&gt;Go decides to store this struct on the heap, not on the stack, because it needs to stick around after &lt;code&gt;newUser&lt;/code&gt; returns.&lt;/li&gt;
&lt;li&gt;Go gives us a &lt;strong&gt;pointer&lt;/strong&gt; (like a map to where the struct lives in memory) and returns it to &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Now, even after &lt;code&gt;newUser&lt;/code&gt; is done, the User struct stays in memory (on the heap), and &lt;code&gt;main&lt;/code&gt; can still access it using the pointer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The heap is useful when you need to store data that outlives the function it was created in, but it’s a little slower and needs careful management by Go’s garbage collector.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack vs. Heap: What’s the Difference?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stack&lt;/strong&gt; is like a tray stack: small, fast, and temporary. Perfect for local variables inside functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Heap&lt;/strong&gt; is like a playground: big, more flexible, but slower. Used for things that need to live longer (like objects that need to be shared across functions).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding the difference between the stack and heap is key to writing efficient Go programs. The stack is fast and easy to manage, great for temporary data. The heap is bigger but slower, used when you need something to stick around.&lt;/p&gt;

&lt;p&gt;Go handles much of the complexity for you with automatic memory management, but knowing these concepts will help you write more optimized and efficient code.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>Introduction to SOLID Principles: The Heroic Saga of Code</title>
      <dc:creator>Tuna</dc:creator>
      <pubDate>Sun, 13 Oct 2024 08:22:05 +0000</pubDate>
      <link>https://forem.com/tuna99/introduction-to-solid-principles-the-heroic-saga-of-code-9nf</link>
      <guid>https://forem.com/tuna99/introduction-to-solid-principles-the-heroic-saga-of-code-9nf</guid>
      <description>&lt;p&gt;Welcome, fellow adventurer, to the realm of software design, where dragons of spaghetti code threaten the kingdom of Clean Code! Fear not, for today we arm ourselves with the legendary &lt;strong&gt;SOLID&lt;/strong&gt; principles. These principles are not just any boring rules; they’re your enchanted shield and sword in the battle for maintainable, scalable, and bug-free code.&lt;/p&gt;

&lt;p&gt;But first, what is &lt;strong&gt;SOLID&lt;/strong&gt; in the name of code refactoring? It stands for five knightly virtues—&lt;em&gt;Single Responsibility&lt;/em&gt;, &lt;em&gt;Open/Closed&lt;/em&gt;, &lt;em&gt;Liskov Substitution&lt;/em&gt;, &lt;em&gt;Interface Segregation&lt;/em&gt;, and &lt;em&gt;Dependency Inversion&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Grab your mouse and keyboard. Let’s embark on this journey together, full of twists, turns, and maybe even a few bad jokes.&lt;/p&gt;

&lt;h2&gt;
  
  
  S: Single Responsibility Principle (SRP) - The Anti-Monolithic Spell
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt;&lt;br&gt;
A class should have one, and only one, reason to change. Don’t give your class an existential crisis!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Action:&lt;/strong&gt;&lt;br&gt;
Imagine a medieval blacksmith who makes swords, bakes bread, and does your taxes. He’s trying to sharpen your sword while thinking about tax deductions, and there’s flour in the forge. Messy, right? That’s what happens when your class tries to do too much!&lt;/p&gt;

&lt;p&gt;Instead, keep your classes focused. Have one class for sword-making, another for baking, and a third for dealing with the tax trolls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Bad SRP example&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Blacksmith&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MakeSword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;BakeBread&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;FileTaxes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// Better SRP example&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Blacksmith&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MakeSword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Baker&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;BakeBread&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TaxFiler&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;FileTaxes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A knight with a single responsibility sleeps better at night. Trust me.&lt;/p&gt;

&lt;h2&gt;
  
  
  O: Open/Closed Principle (OCP) - The Door is Closed, but Feel Free to Paint it!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt;&lt;br&gt;
Your classes should be open for extension but closed for modification. It’s like having a fancy door that you can decorate but never remove.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Action:&lt;/strong&gt;&lt;br&gt;
You’ve built a loyal, trustworthy squire. But now you need him to do more—fetch water, sharpen your sword, and polish your armor. Don’t rewrite his DNA (code)! Just add to his training.&lt;/p&gt;

&lt;p&gt;Instead of modifying the Squire class every time, create extensions. Keep the door closed, but hang a stylish sword on it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Without OCP&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Squire&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;FetchWater&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;SharpenSword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// With OCP: Add without modifying&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FetchWaterTask&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;FetchWaterTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Fetch water&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;SharpenSwordTask&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;SharpenSwordTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Sharpen sword&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your code can evolve as majestically as a knight’s skill set without rewriting the core.&lt;/p&gt;

&lt;h2&gt;
  
  
  L: Liskov Substitution Principle (LSP) - The “Imposter Syndrome” Cure
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt;&lt;br&gt;
If a class inherits from another, it should be able to replace the parent class without causing mayhem (or, in our case, runtime errors).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Action:&lt;/strong&gt;&lt;br&gt;
Imagine you own a stable. Horses gallop, and unicorns… well, they gallop too, but with glitter. Now, if you swapped your horse for a unicorn, you wouldn’t expect the unicorn to explode or refuse to gallop, right? That’s LSP in action.&lt;/p&gt;

&lt;p&gt;Your subclasses (like the unicorn) should behave like the parent (the horse), without any unexpected behavior (no glitter explosions, please).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// LSP violation&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Horse&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Gallop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Unicorn&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Gallop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Throws glitter instead of galloping!&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following LSP is like having a well-behaved unicorn. It looks magical but doesn’t break the barn.&lt;/p&gt;

&lt;h2&gt;
  
  
  I: Interface Segregation Principle (ISP) - The Curse of Unnecessary Contracts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt;&lt;br&gt;
Clients should not be forced to depend on interfaces they don’t use. Consider it breaking down contracts so you only sign what’s necessary.&lt;br&gt;
&lt;strong&gt;In Action:&lt;/strong&gt;&lt;br&gt;
Let’s say you’re a knight with a sword. Your knight’s guild gives you a contract that also requires you to know archery, jousting, and dragon taming. But you just want to swing your sword! Don’t make a sword-wielding knight learn dragon-taming unless they want to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Bad ISP Example&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Warrior&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;FightWithSword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;RideDragon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c"&gt;// Not every warrior rides dragons!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Better ISP Example&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Swordsman&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;FightWithSword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;DragonRider&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;RideDragon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, you can focus on what you do best—sword-swinging—and leave the dragon-taming to the professionals.&lt;/p&gt;

&lt;h2&gt;
  
  
  D: Dependency Inversion Principle (DIP) - No More Royal Puppeteers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt;&lt;br&gt;
High-level modules should not depend on low-level modules. Both should depend on abstractions. Let the peasants (low-level modules) and kings (high-level modules) follow the same laws (interfaces).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Action:&lt;/strong&gt;&lt;br&gt;
Think of a knight who needs a weapon. Instead of demanding a specific sword from the blacksmith, they ask for any weapon that adheres to the Weapon interface. This way, they can use a sword, a bow, or even a banana (if someone implements it). The knight isn’t tied to one weapon, just the idea of a weapon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Without DIP&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Knight&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sword&lt;/span&gt; &lt;span class="n"&gt;Sword&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// With DIP&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Weapon&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Knight&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;weapon&lt;/span&gt; &lt;span class="n"&gt;Weapon&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Knight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Fight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weapon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the knight is flexible and can fight with any weapon, even a legendary potato cannon (if coded properly).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: The Hero’s Journey to SOLID Code
&lt;/h2&gt;

&lt;p&gt;The journey to mastering SOLID principles is full of challenges, much like slaying dragons. But with Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion by your side, your code will be as smooth as a bard’s ballad.&lt;/p&gt;

&lt;p&gt;You now wield the mighty sword of maintainable design. Go forth and refactor with confidence, brave coder!&lt;/p&gt;

&lt;p&gt;Let me know if you’d like to see any specific areas covered more deeply!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>coding</category>
      <category>go</category>
    </item>
    <item>
      <title>Clustered index vs Non-clustered and how they look like in MongoDB</title>
      <dc:creator>Tuna</dc:creator>
      <pubDate>Thu, 10 Oct 2024 10:19:15 +0000</pubDate>
      <link>https://forem.com/tuna99/clustered-index-vs-non-clustered-and-how-they-look-like-in-mongodb-1jf1</link>
      <guid>https://forem.com/tuna99/clustered-index-vs-non-clustered-and-how-they-look-like-in-mongodb-1jf1</guid>
      <description>&lt;p&gt;When working with databases, performance optimization is often a key concern. One of the most effective ways to optimize queries is through indexing. In relational databases like SQL Server or MySQL, clustered and non-clustered indexes are important concepts for efficiently organizing and retrieving data. However, if you're moving to or working with NoSQL databases like MongoDB, you might wonder how these concepts apply. Let’s explore both and look at how MongoDB handles indexing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Index?
&lt;/h2&gt;

&lt;p&gt;Before diving into clustered and non-clustered indexes, let's clarify what an index is. An &lt;strong&gt;index&lt;/strong&gt; is a special data structure that improves the speed of data retrieval operations on a database table at the cost of additional storage space. Without an index, the database engine would have to perform a full scan of the entire collection or table to find the necessary records.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clustered vs Non-Clustered Index
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clustered Index
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: A &lt;strong&gt;clustered index&lt;/strong&gt; is a type of index where the data rows are stored physically on the disk in the same order as the index. In other words, the clustered index defines the order in which data is stored in a table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Features&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;A table can have only &lt;strong&gt;one&lt;/strong&gt; clustered index because the data can only be sorted in one way.&lt;/li&gt;
&lt;li&gt;The actual data of the table is part of the clustered index.&lt;/li&gt;
&lt;li&gt;Clustered indexes are generally created on a primary key.&lt;/li&gt;
&lt;li&gt;Faster data retrieval for range queries, as data is stored in sorted order.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Non-Clustered Index
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: A &lt;strong&gt;non-clustered index&lt;/strong&gt; stores the data separately from the actual table. The index contains pointers to the physical location of the data rather than storing the data in the index itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Features&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;A table can have multiple non-clustered indexes.&lt;/li&gt;
&lt;li&gt;Non-clustered indexes are generally used to speed up lookups for columns that are not sorted physically.&lt;/li&gt;
&lt;li&gt;It creates a logical ordering of data that points to the physical data blocks.&lt;/li&gt;
&lt;li&gt;They take up additional space because they are separate from the data table.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. When to Use Each Type
&lt;/h3&gt;

&lt;p&gt;Choose a clustered index when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You frequently run range queries&lt;/li&gt;
&lt;li&gt;The column has high cardinality (many unique values)&lt;/li&gt;
&lt;li&gt;You need fast data retrieval for a specific column&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Opt for non-clustered indexes when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need multiple indexes on a table&lt;/li&gt;
&lt;li&gt;You frequently search for specific values&lt;/li&gt;
&lt;li&gt;You want to index columns used in JOIN, WHERE, and ORDER BY clauses&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Indexing in MongoDB
&lt;/h2&gt;

&lt;p&gt;MongoDB, being a NoSQL database, does not use the exact same terminology as SQL databases when it comes to indexes, but the underlying concepts of how data is indexed are similar. MongoDB uses &lt;strong&gt;B-tree&lt;/strong&gt; indexes to store and retrieve data efficiently, and indexes can drastically improve query performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clustered Indexes in MongoDB
&lt;/h3&gt;

&lt;p&gt;MongoDB traditionally didn’t have a direct equivalent to SQL’s clustered indexes. However, as of MongoDB 5.3, MongoDB introduced &lt;strong&gt;clustered collections&lt;/strong&gt;, which provide functionality similar to a clustered index in relational databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Clustered Collections in MongoDB?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;clustered collection&lt;/strong&gt; in MongoDB organizes documents based on a specified field and stores data in the same order as the index on that field. The clustered index is embedded directly into the collection, which eliminates the need for a separate B-tree structure that MongoDB typically uses for secondary indexes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key Features&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Documents are stored in the same order as the specified clustered index field.&lt;/li&gt;
&lt;li&gt;It is primarily useful for time-series data or use cases where data is naturally ordered by a specific field (e.g., timestamps, log data, etc.).&lt;/li&gt;
&lt;li&gt;MongoDB ensures that the clustered index field must be unique, so there can be only one clustered index per collection, much like SQL’s clustered index limitation.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Clustered Collections Work in MongoDB
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When you create a clustered collection, MongoDB physically organizes the documents based on the clustered index field, making range queries or searches on that field more efficient.&lt;/li&gt;
&lt;li&gt;Unlike traditional secondary indexes, MongoDB does not need to maintain a separate index structure for clustered collections, as the documents are inherently organized according to the clustered index field.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Benchmarks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"go.mongodb.org/mongo-driver/bson"&lt;/span&gt;
    &lt;span class="s"&gt;"go.mongodb.org/mongo-driver/bson/primitive"&lt;/span&gt;
    &lt;span class="s"&gt;"go.mongodb.org/mongo-driver/mongo"&lt;/span&gt;
    &lt;span class="s"&gt;"go.mongodb.org/mongo-driver/mongo/options"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;uri&lt;/span&gt;                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mongodb://localhost:27017"&lt;/span&gt;
    &lt;span class="n"&gt;dbName&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"performance_test"&lt;/span&gt;
    &lt;span class="n"&gt;clusteredCollName&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"clustered_logs"&lt;/span&gt;
    &lt;span class="n"&gt;nonClusteredCollName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"non_clustered_logs"&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;               &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mongo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;                   &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mongo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;
    &lt;span class="n"&gt;numDocuments&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;_000_000&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mongo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApplyURI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkQueryClusteredCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Drop collection before the benchmark to ensure fresh test data&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clusteredCollName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c"&gt;// // Create Clustered Collection&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateCollection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;SetClusteredIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"unique"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;clusteredCollName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error creating clustered collection: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clusteredCollName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;insertTestData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Clustered Collection: Inserted %d documents in %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numDocuments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;startID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewObjectIDFromTimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;endID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewObjectIDFromTimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResetTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Reset the timer for the actual query benchmarking&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"$gte"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;startID&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"$lt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;endID&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkQueryNonClusteredCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Drop collection before the benchmark to ensure fresh test data&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nonClusteredCollName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c"&gt;// Create Non-Clustered Collection and Index&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nonClusteredCollName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error creating non-clustered collection: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nonClusteredCollName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;insertTestData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Non-Clustered Collection: Inserted %d documents in %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numDocuments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;startID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewObjectIDFromTimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;endID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewObjectIDFromTimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResetTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Reset the timer for the actual query benchmarking&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"$gte"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;startID&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"$lt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;endID&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;insertTestData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mongo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numDocuments&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"log"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Log entry %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InsertMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-bench&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

BenchmarkQueryClusteredCollection-8
Clustered Collection: Inserted 1000000 documents &lt;span class="k"&gt;in &lt;/span&gt;2.032176167s
    9693            113248 ns/op
BenchmarkQueryNonClusteredCollection-8
Non-Clustered Collection: Inserted 1000000 documents &lt;span class="k"&gt;in &lt;/span&gt;2.738731583s
    8781            137176 ns/op
PASS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Interpretation:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Insertion Time: The clustered collection is faster at inserting documents. This is expected because, in a clustered collection, the documents are already stored in the order of the &lt;code&gt;_id&lt;/code&gt; field, which optimizes the insertion process. In contrast, non-clustered collections require managing the separate index for &lt;code&gt;_id&lt;/code&gt;, adding overhead.&lt;/li&gt;
&lt;li&gt;Query Performance: The clustered collection is faster for queries, which is consistent with MongoDB's behavior. Since the data in a clustered collection is stored according to the &lt;code&gt;_id&lt;/code&gt; field, range queries can be executed more efficiently. The non-clustered collection requires additional lookups on the &lt;code&gt;_id&lt;/code&gt; index, which adds overhead and makes the query slightly slower.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Differences between SQL Clustered Indexes and MongoDB Clustered Collections
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Physical Data Organization: In both SQL and MongoDB, clustered indexes determine the physical order of data. However, MongoDB only recently introduced clustered collections in version 5.3, whereas SQL has long had clustered indexes.&lt;/li&gt;
&lt;li&gt;Default Behavior: In SQL, a primary key often defaults to a clustered index, whereas in MongoDB, the &lt;code&gt;_id&lt;/code&gt; field is indexed by default, but not as a clustered index. You need to explicitly create a clustered collection if you want MongoDB to organize documents based on a specific field.&lt;/li&gt;
&lt;li&gt;Use Cases: Clustered collections in MongoDB are especially beneficial for time-series data and logs where the data is naturally sequential. In SQL, clustered indexes can be applied to various types of data and use cases.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With the introduction of &lt;strong&gt;clustered collections&lt;/strong&gt;, MongoDB now offers a way to physically organize documents in a collection based on a specified field, similar to a clustered index in relational databases. This feature is especially useful for use cases like time-series data, where the natural ordering of data can improve query efficiency.&lt;/p&gt;

&lt;p&gt;For MongoDB users, understanding and applying clustered collections to appropriate workloads can significantly enhance query performance, particularly when dealing with sequential or range-based data.&lt;/p&gt;

&lt;p&gt;For more details, you can refer to MongoDB’s official documentation on &lt;a href="https://www.mongodb.com/docs/manual/core/clustered-collections/" rel="noopener noreferrer"&gt;clustered collections&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>performance</category>
      <category>programming</category>
      <category>coding</category>
    </item>
  </channel>
</rss>
