<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ahmad Adewumi</title><link>https://bytesbyadewumi.tech/</link><description>Recent content on Ahmad Adewumi</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 11 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://bytesbyadewumi.tech/index.xml" rel="self" type="application/rss+xml"/><item><title>About</title><link>https://bytesbyadewumi.tech/about/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://bytesbyadewumi.tech/about/</guid><description>&lt;p&gt;I&amp;rsquo;m Ahmad, a software engineering student at the Federal University of Technology, Akure. I like building systems from scratch to understand how they actually work.&lt;/p&gt;
&lt;p&gt;Right now I&amp;rsquo;m kinda deep into data structures and algorithms, learning by building some stuffs. Along the way I will be writing about what I learn → heaps, trees, bloom filters, storage engines, and anything that comes up.&lt;/p&gt;
&lt;p&gt;If something I wrote is wrong, please, notify me. That&amp;rsquo;s how I get better.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;m Ahmad, a software engineering student at the Federal University of Technology, Akure. I like building systems from scratch to understand how they actually work.</p>
<p>Right now I&rsquo;m kinda deep into data structures and algorithms, learning by building some stuffs. Along the way I will be writing about what I learn → heaps, trees, bloom filters, storage engines, and anything that comes up.</p>
<p>If something I wrote is wrong, please, notify me. That&rsquo;s how I get better.</p>
<p><a href="https://github.com/AhmadAdewumi">GitHub</a> · <a href="https://www.linkedin.com/in/ahmad-adewumi">LinkedIn</a></p>
]]></content:encoded></item><item><title>Ordering Events by Time: Building a Min-Heap in Java</title><link>https://bytesbyadewumi.tech/2026/05/event-heap-minheap-java/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://bytesbyadewumi.tech/2026/05/event-heap-minheap-java/</guid><description>How a min-heap re-sequences out-of-order vehicle location events by timestamp, implemented from scratch in Java.</description><content:encoded><![CDATA[<h2 id="the-problem-event-arrives-out-of-sequence">The Problem: Event arrives out of sequence</h2>
<p>So, I have been working on a project and it has been kinda cool, learning new stuffs, challenging and all. The project is about a real time location processing system. So, I encountered this problem, let us say some data came in for vehicles.</p>
<p>Data came in different order. Influenced by a lot of factors. Network among the reasons which causes increased latency and also, spatial indexing, organizing our geometric data so location based queries run fast, is irrelevant, if the data is out of chronological order. We cannot build an accurate picture of where vehicles are right now if we are processing events from the past mixed with events from the present. Chaos will surely ensue at some point.</p>
<p>So we need a mechanism to re sequence our data.</p>
<p>Upon consulting Gemini, I learnt there is a data structure for exactly this. But, I am kind of a noob to it.</p>
<p>Well, that is how I came to learn about heaps. Went on YT and hello interview to study it, that&rsquo;s where I came across  this course by AbdulBari on it (That man is the real OG). When he was explaining, he made mention that a heap is a complete binary tree.</p>
<p>The knowledge of my DSA class last semester on Binary Trees flooded back and it really came in handy. Although it was mostly theory based.</p>
<p>So what is a complete binary tree? First, a binary tree is a tree data structure where each node has at most two children. A complete binary tree is a special type of it where every level of the tree is filled but possibly with the exception of the last level which is filled from left to right.</p>
<p>There are actually two types of heap. We have the min heap and we have the max heap.</p>
<p>Let us visualize the heap as a tree. Say we have this min heap:</p>
<pre tabindex="0"><code>          1 (Root)
        /   \
       2     4
      / \   /
     5   8 6
</code></pre><p>This particular heap is a min heap because if we notice:</p>
<ol>
<li>The smallest value is the root node</li>
<li>The parent of each node is less than either of its children</li>
</ol>
<p>And for a max heap, we have this example:</p>
<pre tabindex="0"><code>          9 (root)
        /   \
       8     5
      / \   /
     4   6 2
</code></pre><p>It can be represented as an array. From the min heap tree above, we get:</p>
<pre tabindex="0"><code>[1, 2, 4, 5, 8, 6]
</code></pre><p>So how do we translate the tree into an array?</p>
<p>Label each node by level, from left to right: 0, 1, 2, 3, and so on. Then place each value at its labeled position in the array. Simple.</p>
<p>Here is the min-heap tree from above as an array:</p>
<table>
  <thead>
      <tr>
          <th>Index</th>
          <th>0</th>
          <th>1</th>
          <th>2</th>
          <th>3</th>
          <th>4</th>
          <th>5</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Value</td>
          <td>1</td>
          <td>2</td>
          <td>4</td>
          <td>5</td>
          <td>8</td>
          <td>6</td>
      </tr>
  </tbody>
</table>
<p>When stored as a flat array, how do we know which node is whose child? Three formulas:</p>
<table>
  <thead>
      <tr>
          <th>Relationship</th>
          <th>Formula</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Left child of i</td>
          <td><code>2 * i + 1</code></td>
      </tr>
      <tr>
          <td>Right child of i</td>
          <td><code>2 * i + 2</code></td>
      </tr>
      <tr>
          <td>Parent of i</td>
          <td><code>(i - 1) / 2</code> (integer/floor division)</td>
      </tr>
  </tbody>
</table>
<p>These formulas are what make the heap work without pointers. No left/right child fields. No object overhead. Just an array and math.</p>
<p>For my project use case: events have timestamps. Earlier timestamps must be processed before later ones. This is exactly what a <strong>min-heap</strong> gives us, the smallest timestamp always sits at index 0, ready to be extracted next.</p>
<p>The two operations that keep the heap working are:</p>
<ul>
<li><code>heapifyUp()</code> → bubble a value up after insertion</li>
<li><code>heapifyDown()</code> → bubble a value down after extraction</li>
</ul>
<h2 id="interactive-heap-visualizer">Interactive Heap Visualizer</h2>
<p>Play with the min-heap below. Insert values and extract the minimum. Watch how the tree rearranges itself.</p>
<div id="heap-controls" style="margin: 20px 0; font-family: 'JetBrains Mono', monospace; font-size: 13px;">
  
  
  <div style="margin-bottom: 10px;">
    <input id="heap-value" type="number" placeholder="Enter a number" style="background:#0d1117; color:#e6edf3; border:1px solid #30363d; padding:6px 12px; border-radius:4px; width:130px; font-size:13px; font-family:inherit;">
    <button id="btn-insert" style="background:#21262d; color:#c9d1d9; border:1px solid #30363d; padding:6px 14px; border-radius:4px; cursor:pointer; margin-left:6px; font-size:13px; font-family:inherit;">Insert</button>
    <button id="btn-extract" style="background:#21262d; color:#c9d1d9; border:1px solid #30363d; padding:6px 14px; border-radius:4px; cursor:pointer; margin-left:4px; font-size:13px; font-family:inherit;">Extract Min</button>
    <button id="btn-reset" style="background:#21262d; color:#c9d1d9; border:1px solid #30363d; padding:6px 14px; border-radius:4px; cursor:pointer; margin-left:4px; font-size:13px; font-family:inherit;">Reset</button>
  </div>

  
  <div style="margin-bottom: 8px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
    <span style="color:#8b949e; font-size:12px;">Mode:</span>
    <button id="btn-mode-auto" style="background:#1f6feb; color:#fff; border:1px solid #1f6feb; padding:4px 12px; border-radius:4px; cursor:pointer; font-size:12px; font-family:inherit;">Auto</button>
    <button id="btn-mode-manual" style="background:#21262d; color:#c9d1d9; border:1px solid #30363d; padding:4px 12px; border-radius:4px; cursor:pointer; font-size:12px; font-family:inherit;">Step by Step</button>
    
    <span style="color:#8b949e; font-size:12px; margin-left:4px;">Speed:</span>
    <button id="btn-speed-05" style="background:#21262d; color:#c9d1d9; border:1px solid #30363d; padding:4px 10px; border-radius:4px; cursor:pointer; font-size:12px; font-family:inherit;">0.5x</button>
    <button id="btn-speed-1" style="background:#1f6feb; color:#fff; border:1px solid #1f6feb; padding:4px 10px; border-radius:4px; cursor:pointer; font-size:12px; font-family:inherit;">1x</button>
    <button id="btn-speed-2" style="background:#21262d; color:#c9d1d9; border:1px solid #30363d; padding:4px 10px; border-radius:4px; cursor:pointer; font-size:12px; font-family:inherit;">2x</button>

    <button id="btn-step" style="background:#238636; color:#fff; border:1px solid #238636; padding:4px 14px; border-radius:4px; cursor:pointer; font-size:12px; font-family:inherit; opacity:0.5; margin-left:4px;">Next Step ▶</button>
  </div>

  
  <div style="margin-bottom: 6px;">
    <span id="heap-status" style="color:#8b949e; font-size:13px;">Insert values to get started</span>
    <span id="heap-step-counter" style="color:#d2991d; font-size:12px; margin-left:12px;"></span>
  </div>
</div>

<canvas id="heap-canvas" width="800" height="420" style="background:#0d1117; border:1px solid #30363d; border-radius:6px; display:block; margin:10px 0; width:100%; max-width:800px; height:auto; aspect-ratio:800/420;"></canvas>

<script src="/js/heap-visualizer.js"></script>
<script>
  (function() {
    if (document.getElementById('heap-canvas') && !document.getElementById('heap-canvas').__heapInitialized) {
      document.getElementById('heap-canvas').__heapInitialized = true;
      new HeapVisualizer('heap-canvas', { controlsSelector: '#heap-controls' });
    }
  })();
</script>

<h2 id="insert-adding-an-event-to-the-heap">Insert: Adding an Event to the Heap</h2>
<p>So how do we add a new event to this thing?</p>
<p>We put it at the end of the array. That is step one. Just append, NB, we fill from left to right as usual.</p>
<p>But now the heap property might be broken. The new value might be smaller than its parent. And if the parent is bigger than the child, we have violated the min-heap rule. So we fix it.</p>
<p>We compare the new value with its parent. If the child is smaller, we swap them. Then we compare again with the new parent. We keep doing this until either the child is not smaller than the parent, or we reach the root.</p>
<p>This process is called <strong>bubble up</strong> or <strong>heapify up</strong>. It is the same idea every time. Compare. Swap if needed. Move up. Repeat.</p>
<p>Try inserting some values using the visualizer above. Watch how they bubble up. Try inserting a value smaller than the current root, it will travel all the way to the top. That is the worst case. That is O(log n) swaps.</p>
<h2 id="extractmin-getting-the-next-event-in-order">ExtractMin: Getting the Next Event in Order</h2>
<p>We have been adding events. Now we need to process them. The whole point of a min-heap is that the smallest value sits at the root. Always. So to get the next event in chronological order, we just look at index 0.</p>
<p>But we also need to remove it. And this removal is quite trickier than insertion.</p>
<p>We save the root value. That is what we return. Then we take the last element in the array, the rightmost leaf, and we move it to the root position.</p>
<p>Now the heap property is definitely broken. The value that was at the bottom is now at the top. It is probably bigger than one or both of its children.</p>
<p>So we bubble it down. We compare it with both children. If one of the children is smaller, we swap with the smaller child. Then we repeat from that child position. We keep going until the value is smaller than both its children, or it reaches a leaf with no children.</p>
<p>This is called <strong>bubble down</strong> or <strong>heapify down</strong>.</p>
<p>Try extracting the minimum a few times using the visualizer above and watch the bubble down:</p>
<h2 id="the-implementation-in-java">The Implementation in Java</h2>
<p>I think we&rsquo;ve had enough theory. Here is the actual code.</p>
<h3 id="the-eventheap-class">The EventHeap Class</h3>
<div class="highlight"><pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1</span><span><span style="color:#fff;font-weight:bold">package</span> com.rtlis.core.temporal;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3</span><span><span style="color:#fff;font-weight:bold">import</span> com.rtlis.core.model.Point;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5</span><span><span style="color:#fff;font-weight:bold">public</span> <span style="color:#fff;font-weight:bold">class</span> EventHeap {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6</span><span>    <span style="color:#fff;font-weight:bold">private</span> Point[] heap;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7</span><span>    <span style="color:#fff;font-weight:bold">private</span> <span style="color:#fff;font-weight:bold">int</span> size;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8</span><span>    <span style="color:#fff;font-weight:bold">private</span> <span style="color:#fff;font-weight:bold">int</span> capacity;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10</span><span>    <span style="color:#fff;font-weight:bold">public</span> EventHeap(<span style="color:#fff;font-weight:bold">int</span> capacity) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11</span><span>        <span style="color:#fff;font-weight:bold">this</span>.<span style="color:#007f7f">capacity</span> = capacity;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12</span><span>        <span style="color:#fff;font-weight:bold">this</span>.<span style="color:#007f7f">heap</span> = <span style="color:#fff;font-weight:bold">new</span> Point[capacity];
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13</span><span>        <span style="color:#fff;font-weight:bold">this</span>.<span style="color:#007f7f">size</span> = 0;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">14</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">15</span><span>}
</span></span></code></pre></div><p>This contains an array of Point objects. A size counter so we know how many elements are actually in the heap. A fixed capacity because this heap lives in memory and we do not want it growing forever. When it fills up, we flush it to disk and start a new one.</p>
<h3 id="the-point-class">The Point Class</h3>
<p>Before we get into the operations, here is the Point class that EventHeap stores:</p>
<div class="highlight"><pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1</span><span><span style="color:#fff;font-weight:bold">package</span> com.rtlis.core.model;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3</span><span><span style="color:#fff;font-weight:bold">public</span> <span style="color:#fff;font-weight:bold">class</span> Point {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4</span><span>    <span style="color:#fff;font-weight:bold">private</span> <span style="color:#fff;font-weight:bold">double</span> latitude;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5</span><span>    <span style="color:#fff;font-weight:bold">private</span> <span style="color:#fff;font-weight:bold">double</span> longitude;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6</span><span>    <span style="color:#fff;font-weight:bold">private</span> <span style="color:#fff;font-weight:bold">long</span> timestamp;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8</span><span>    <span style="color:#fff;font-weight:bold">public</span> Point(<span style="color:#fff;font-weight:bold">double</span> latitude, <span style="color:#fff;font-weight:bold">double</span> longitude, <span style="color:#fff;font-weight:bold">long</span> timestamp) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9</span><span>        <span style="color:#fff;font-weight:bold">this</span>.<span style="color:#007f7f">latitude</span> = latitude;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10</span><span>        <span style="color:#fff;font-weight:bold">this</span>.<span style="color:#007f7f">longitude</span> = longitude;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11</span><span>        <span style="color:#fff;font-weight:bold">this</span>.<span style="color:#007f7f">timestamp</span> = timestamp;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">14</span><span>    <span style="color:#fff;font-weight:bold">public</span> <span style="color:#fff;font-weight:bold">long</span> getTimestamp() {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">15</span><span>        <span style="color:#fff;font-weight:bold">return</span> timestamp;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">16</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">17</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">18</span><span>    <span style="color:#fff;font-weight:bold">public</span> <span style="color:#fff;font-weight:bold">double</span> getLatitude() {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">19</span><span>        <span style="color:#fff;font-weight:bold">return</span> latitude;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">20</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">21</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">22</span><span>    <span style="color:#fff;font-weight:bold">public</span> <span style="color:#fff;font-weight:bold">double</span> getLongitude() {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">23</span><span>        <span style="color:#fff;font-weight:bold">return</span> longitude;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">24</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">25</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">26</span><span>    @Override
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">27</span><span>    <span style="color:#fff;font-weight:bold">public</span> String toString() {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">28</span><span>        <span style="color:#fff;font-weight:bold">return</span> <span style="color:#0ff;font-weight:bold">&#34;Point{lat=&#34;</span> + latitude + <span style="color:#0ff;font-weight:bold">&#34;, lon=&#34;</span> + longitude + <span style="color:#0ff;font-weight:bold">&#34;, ts=&#34;</span> + timestamp + <span style="color:#0ff;font-weight:bold">&#34;}&#34;</span>;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">29</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">30</span><span>}
</span></span></code></pre></div><p>Each Point holds a location and a timestamp. The timestamp is what the heap compares, the latitude and longitude are the actual vehicle position we care about once events are processed in order.</p>
<h3 id="insert">Insert</h3>
<div class="highlight"><pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1</span><span><span style="color:#fff;font-weight:bold">public</span> <span style="color:#fff;font-weight:bold">void</span> insert(Point p) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2</span><span>    <span style="color:#fff;font-weight:bold">if</span> (size == capacity) <span style="color:#fff;font-weight:bold">throw</span> <span style="color:#fff;font-weight:bold">new</span> IllegalStateException(<span style="color:#0ff;font-weight:bold">&#34;Heap is full&#34;</span>);
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4</span><span>    heap[size] = p;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5</span><span>    size++;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">6</span><span>    heapifyUp(size - 1);
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">7</span><span>}
</span></span></code></pre></div><p>Put the new element at the end. Increment size. Then call heapifyUp starting from that new element index. That is it. The real work happens in heapifyUp.</p>
<h3 id="heapifyup">heapifyUp</h3>
<div class="highlight"><pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1</span><span><span style="color:#fff;font-weight:bold">private</span> <span style="color:#fff;font-weight:bold">void</span> heapifyUp(<span style="color:#fff;font-weight:bold">int</span> index) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2</span><span>    <span style="color:#fff;font-weight:bold">while</span> (index &gt; 0) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3</span><span>        <span style="color:#fff;font-weight:bold">int</span> parentIndex = (index - 1) / 2;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5</span><span>        <span style="color:#fff;font-weight:bold">if</span> (<span style="color:#fff;font-weight:bold">this</span>.<span style="color:#007f7f">heap</span>[index].<span style="color:#007f7f">getTimestamp</span>() &gt;= <span style="color:#fff;font-weight:bold">this</span>.<span style="color:#007f7f">heap</span>[parentIndex].<span style="color:#007f7f">getTimestamp</span>()) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6</span><span>            <span style="color:#fff;font-weight:bold">break</span>;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7</span><span>        }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9</span><span>        swap(index, parentIndex);
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10</span><span>        index = parentIndex;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12</span><span>}
</span></span></code></pre></div><p>Line by line explanation:</p>
<ul>
<li><code>while (index &gt; 0)</code> means keep going until we reach the root. The root has index 0 and no parent.</li>
<li><code>int parentIndex = (index - 1) / 2</code> is integer/floor division that gives us the parent index automatically. Remember the formula from the table above.</li>
<li>The <code>if</code> check: if the current timestamp is greater than or equal to the parent timestamp, the heap property is satisfied. We stop.</li>
<li>Otherwise, we swap the two elements and move our attention to the parent old position. Then we check again from there.</li>
</ul>
<h3 id="extractmin">extractMin</h3>
<h5 id="similar-to-pop-operation-in-stack-remove-and-return">(similar to pop operation in stack, remove and return)</h5>
<div class="highlight"><pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1</span><span><span style="color:#fff;font-weight:bold">public</span> Point extractMin() {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2</span><span>    <span style="color:#fff;font-weight:bold">if</span> (size == 0) <span style="color:#fff;font-weight:bold">return</span> <span style="color:#fff;font-weight:bold">null</span>;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4</span><span>    Point min = heap[0];
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5</span><span>    heap[0] = heap[size - 1];
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6</span><span>    heap[size - 1] = <span style="color:#fff;font-weight:bold">null</span>;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7</span><span>    size--;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9</span><span>    <span style="color:#fff;font-weight:bold">if</span> (size &gt; 0) heapifyDown(0);
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11</span><span>    <span style="color:#fff;font-weight:bold">return</span> min;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12</span><span>}
</span></span></code></pre></div><p>Line by line explanation:</p>
<ul>
<li><code>if (size == 0) return null</code> → nothing to extract if the heap is empty.</li>
<li><code>Point min = heap[0]</code> → we save the root because that is the minimum value and we need to return it.</li>
<li><code>heap[0] = heap[size - 1]</code> → move the last element to the root position.</li>
<li><code>heap[size - 1] = null</code> → clear the old last slot so the garbage collector can reclaim it.</li>
<li><code>size--</code> → shrink the heap.</li>
<li><code>if (size &gt; 0) heapifyDown(0)</code> → if the heap is not empty after removal, repair the heap starting from the root.</li>
</ul>
<h3 id="heapifydown">heapifyDown</h3>
<div class="highlight"><pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1</span><span><span style="color:#fff;font-weight:bold">private</span> <span style="color:#fff;font-weight:bold">void</span> heapifyDown(<span style="color:#fff;font-weight:bold">int</span> index) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2</span><span>    <span style="color:#fff;font-weight:bold">while</span> (<span style="color:#fff;font-weight:bold">true</span>) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3</span><span>        <span style="color:#fff;font-weight:bold">int</span> leftChild = 2 * index + 1;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4</span><span>        <span style="color:#fff;font-weight:bold">int</span> rightChild = 2 * index + 2;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5</span><span>        <span style="color:#fff;font-weight:bold">int</span> smallest = index;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7</span><span>        <span style="color:#fff;font-weight:bold">if</span> (leftChild &lt; size &amp;&amp; heap[leftChild].<span style="color:#007f7f">getTimestamp</span>() &lt; heap[smallest].<span style="color:#007f7f">getTimestamp</span>()) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8</span><span>            smallest = leftChild;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9</span><span>        }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11</span><span>        <span style="color:#fff;font-weight:bold">if</span> (rightChild &lt; size &amp;&amp; heap[rightChild].<span style="color:#007f7f">getTimestamp</span>() &lt; heap[smallest].<span style="color:#007f7f">getTimestamp</span>()) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12</span><span>            smallest = rightChild;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13</span><span>        }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">14</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">15</span><span>        <span style="color:#fff;font-weight:bold">if</span> (smallest == index) <span style="color:#fff;font-weight:bold">break</span>;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">16</span><span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">17</span><span>        swap(index, smallest);
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">18</span><span>        index = smallest;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">19</span><span>    }
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">20</span><span>}
</span></span></code></pre></div><p>This one is longer but the idea is the same as <code>heapifyUp</code>, just going down instead of up.</p>
<p>Line by line explanation:</p>
<ul>
<li><code>int leftChild = 2 * index + 1</code> and <code>int rightChild = 2 * index + 2</code> → get the children indices using the formula from earlier.</li>
<li><code>int smallest = index</code> → we start by assuming the current node is the smallest.</li>
<li><strong>Check left child</strong>: if it exists and its timestamp is smaller, it becomes the new candidate for smallest.</li>
<li><strong>Check right child</strong>: same thing. If it exists and is smaller than whatever is currently smallest, it becomes the new candidate.</li>
<li><code>if (smallest == index) break</code> → if after checking both children, the current node is still the smallest, we are done. Heap property is satisfied.</li>
<li>Otherwise, swap with the smaller child and continue the loop from that child position.</li>
</ul>
<h3 id="the-swap-helper">The Swap Helper</h3>
<div class="highlight"><pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1</span><span><span style="color:#fff;font-weight:bold">private</span> <span style="color:#fff;font-weight:bold">void</span> swap(<span style="color:#fff;font-weight:bold">int</span> i, <span style="color:#fff;font-weight:bold">int</span> j) {
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2</span><span>    Point temp = heap[i];
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3</span><span>    heap[i] = heap[j];
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4</span><span>    heap[j] = temp;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5</span><span>}
</span></span></code></pre></div><p>Nothing fancy. Just exchanging two array positions. Pull out one value, store it temporarily, overwrite it with the other, then put the temporary value where the other one was.</p>
<h3 id="so-how-does-this-matter-to-my-project">So, How does this matter to my project</h3>
<p>So why did I build this instead of just sorting an array?</p>
<p>Because events arrive continuously. Vehicles keep pinging. I cannot wait until I have all the events and then sort them. That would mean no processing happens until the system stops receiving data. And a real-time system never stops receiving data.</p>
<p>The heap gives me two operations that are both fast:</p>
<ul>
<li><strong>Insert</strong> is O(log n). When a new event arrives, it takes at most log n comparisons to put it in the right place.</li>
<li><strong>ExtractMin</strong> is O(log n). When I need the next event in chronological order, I pop the root and repair the heap in (log n) time.</li>
</ul>
<p>If I used a sorted array, insert would be O(n) because I would have to shift elements to make space. If I used an unsorted array, extractMin would be O(n) because I would have to scan the entire array for the minimum.</p>
<p>The heap is the sweet spot. Both operations are logarithmic. For a stream of millions of events, I think that is what makes the difference between a system that keeps up and a system that falls behind.</p>
<p>And when the heap fills up? I flush all the sorted data to an SSTable on disk and start a new heap. But that is a story for another day.</p>
<p>Thank you for reading ❤️. Ahmad Adewumi.</p>
]]></content:encoded></item><item><title>Privacy</title><link>https://bytesbyadewumi.tech/privacy/</link><pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate><guid>https://bytesbyadewumi.tech/privacy/</guid><description>&lt;p&gt;This site does not track you.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No cookies&lt;/li&gt;
&lt;li&gt;No analytics scripts that identify you&lt;/li&gt;
&lt;li&gt;No third-party services collecting your data&lt;/li&gt;
&lt;li&gt;No comment system storing your information&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only analytics I use are Cloudflare Web Analytics, which is privacy-first and does not use cookies or fingerprinting. It tells me &amp;ldquo;someone visited this page&amp;rdquo; - nothing more.&lt;/p&gt;
&lt;p&gt;This is a static site. There&amp;rsquo;s no database, no login system, no way for me to track individual visitors even if I wanted to.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This site does not track you.</p>
<ul>
<li>No cookies</li>
<li>No analytics scripts that identify you</li>
<li>No third-party services collecting your data</li>
<li>No comment system storing your information</li>
</ul>
<p>The only analytics I use are Cloudflare Web Analytics, which is privacy-first and does not use cookies or fingerprinting. It tells me &ldquo;someone visited this page&rdquo; - nothing more.</p>
<p>This is a static site. There&rsquo;s no database, no login system, no way for me to track individual visitors even if I wanted to.</p>
]]></content:encoded></item></channel></rss>