<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[Chenyo's Blog]]></title>
<description><![CDATA[Chenyo's Blog]]></description>
<link>https://chenyo.me</link>
<lastBuildDate>Sat, 11 Oct 2025 13:40:06 +0200</lastBuildDate>
<item>
  <title><![CDATA[CS110L Notes]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgd334dd4">1. Channel</a>
<ul>
<li><a href="#org41de397">1.1. Mutex-based channel implementation</a></li>
<li><a href="#org1b3e13f">1.2. Rust crossbeam channel implementation</a></li>
</ul>
</li>
<li><a href="#orga78e457">2. Networking systems</a>
<ul>
<li><a href="#org07da297">2.1. System</a>
<ul>
<li><a href="#org6827dc5">2.1.1. File system</a></li>
<li><a href="#org4d30174">2.1.2. Start a server</a></li>
<li><a href="#org09d4a4b">2.1.3. Connect to a server (ignore networking details)</a></li>
</ul>
</li>
<li><a href="#orge4156d8">2.2. Scalability and avilability</a>
<ul>
<li><a href="#orga346693">2.2.1. Load balancers</a></li>
</ul>
</li>
<li><a href="#org423b813">2.3. Security</a></li>
</ul>
</li>
<li><a href="#org3081613">3. Event-driven programming</a>
<ul>
<li><a href="#orgb6048c3">3.1. Rust future</a>
<ul>
<li><a href="#org9fb7399">3.1.1. Executor</a></li>
<li><a href="#org7fe885f">3.1.2. Tokio</a></li>
<li><a href="#org6c2af8e">3.1.3. Compilation</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
Notes for CS110L Safety in Systems Programming.
Mostly follow <a href="https://reberhardt.com/cs110l/spring-2020/">Spring 2020</a>, also include <a href="https://reberhardt.com/cs110l/spring-2021/">Spring 2021</a>.
</p>

<p>
Not complete, only started taking notes since Lec 10 (2020).
</p>
<div id="outline-container-orgd334dd4" class="outline-2">
<h2 id="orgd334dd4"><span class="section-number-2">1.</span> Channel</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>Golang: Do not communicate by sharing memory; instead, share memory by communicating.</li>
<li><b><b>Message passing</b></b>: each thread has its own memory, they communicate only by message exchanging.
<ul class="org-ul">
<li>In theory, this implies: no shared memory -&gt; no data races -&gt; each thread needs to copy the data -&gt; expensive</li>
<li>In practice, goroutines share heap memory and only make shallow copies into channels -&gt; pass pointers to channel is dangerous!</li>
</ul></li>
<li>In Rust, passing pointers, e.g., <code>Box</code> is always safe due to ownership transfer</li>
<li>An ideal channel: MPMC (multi-producer, multi-consumer).</li>
</ul>
</div>
<div id="outline-container-org41de397" class="outline-3">
<h3 id="org41de397"><span class="section-number-3">1.1.</span> Mutex-based channel implementation</h3>
<div class="outline-text-3" id="text-1-1">
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">pub</span> <span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">SemaPlusPlus</span>&lt;<span style="color: #ECBE7B;">T</span>&gt; {
    <span style="color: #dcaeea;">queue_and_cv</span>: <span style="color: #ECBE7B;">Arc</span>&lt;(<span style="color: #ECBE7B;">Mutex</span>&lt;<span style="color: #ECBE7B;">VecDeque</span>&lt;<span style="color: #ECBE7B;">T</span>&gt;&gt;, <span style="color: #ECBE7B;">Condvar</span>)&gt;,
}

<span style="color: #51afef;">impl</span>&lt;<span style="color: #ECBE7B;">T</span>&gt; <span style="color: #ECBE7B;">SemaPlusPlus</span>&lt;<span style="color: #ECBE7B;">T</span>&gt; {
    <span style="color: #51afef;">pub</span> <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">send</span>(<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">self</span>, <span style="color: #dcaeea;">message</span>: <span style="color: #ECBE7B;">T</span>) {
        <span style="color: #51afef;">let</span> (queue_lock, cv) = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>*<span style="color: #51afef;">self</span>.queue_and_cv;
        <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">queue</span> = queue_lock.lock().unwrap();
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">queue_was_empty</span> = queue.is_empty();
        queue.push_back(message);
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if a queue is not empty, then another thread must have notified and main()</span>
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">must be awake</span>
        <span style="color: #51afef;">if</span> queue_was_empty {
            cv.notify_all();
        }
    }

    <span style="color: #51afef;">pub</span> <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">recv</span>(<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">self</span>) -&gt; <span style="color: #ECBE7B;">T</span> {
        <span style="color: #51afef;">let</span> (queue_lock, cv) = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>*<span style="color: #51afef;">self</span>.queue_and_cv;
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">wait_while dereferences the guard and pass the protected data to the closure,</span>
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">when the condition is true, it releases the lock and sleep until another thread</span>
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">notify_all</span>
        <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">queue</span> = cv
            .wait_while(queue_lock.lock().unwrap(), |queue| queue.is_empty())
            .unwrap();
        queue.pop_front().unwrap()
    }
}

<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">main</span>() {
    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">sem</span>: <span style="color: #ECBE7B;">SemaPlusPlus</span>&lt;<span style="color: #ECBE7B;">String</span>&gt; = <span style="color: #ECBE7B;">SemaPlusPlus</span>::new();
    <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">handlers</span> = <span style="color: #ECBE7B;">Vec</span>::new();
    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">i</span> <span style="color: #51afef;">in</span> 0..<span style="color: #ECBE7B;">NUM_THREADS</span> {
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">sem_clone</span> = sem.clone();
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">handle</span> = <span style="color: #a9a1e1;">thread</span>::spawn(<span style="color: #51afef;">move</span> || {
            rand_sleep();
            sem_clone.send(<span style="color: #c678dd;">format!</span>(<span style="color: #98be65;">"thread </span><span style="color: #98be65; font-style: italic;">{}</span><span style="color: #98be65;"> just finished!"</span>, i))
        });
        handlers.push(handle);
    }
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">main is the only consumer of the queue,</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">it wakes up when some thread notify_all, locks the queue, consume the message</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">and release the lock until it is notified again</span>
    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">_</span> <span style="color: #51afef;">in</span> 0..<span style="color: #ECBE7B;">NUM_THREADS</span> {
        <span style="color: #c678dd;">println!</span>(<span style="color: #98be65;">"</span><span style="color: #98be65; font-style: italic;">{}</span><span style="color: #98be65;">"</span>, sem.recv())
    }

    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">handle</span> <span style="color: #51afef;">in</span> handlers {
        handle.join().unwrap();
    }
}
</pre>
</div>
<ul class="org-ul">
<li>Mutex-based channel is inefficient:
<ul class="org-ul">
<li>it does not allow the queue producer and consumer modify the queue simultaneously.</li>
<li>It involves system calls.</li>
</ul></li>
<li>Go channels are MPMC, but it essentially implement <code>Mutex&lt;VecDeque&lt;&gt;&gt;</code> with <a href="https://eli.thegreenplace.net/2018/basics-of-futexes/">fuxtex</a>.</li>
</ul>
</div>
</div>
<div id="outline-container-org1b3e13f" class="outline-3">
<h3 id="org1b3e13f"><span class="section-number-3">1.2.</span> Rust <a href="https://docs.rs/crossbeam/latest/crossbeam/channel/index.html">crossbeam</a> channel implementation</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Minimal lock usage.</li>
<li>Channels are not the best choice for global values -&gt; lock still required.</li>
</ul>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #83898d;">/// Factor the number while receiving numbers from stdin</span>
<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">main</span>() {
    <span style="color: #51afef;">let</span> (sender, receiver) = <span style="color: #a9a1e1;">crossbeam_channel</span>::unbounded();
    <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">threads</span> = <span style="color: #ECBE7B;">Vec</span>::new();
    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">_</span> <span style="color: #51afef;">in</span> 0..<span style="color: #a9a1e1;">num_cpus</span>::get() {
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">The channel maintains a reference counter for senders and for receivers</span>
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">when receiver.clone(), the receiver counter increments.</span>
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">receiver</span> = receiver.clone();
        threads.push(<span style="color: #a9a1e1;">thread</span>::spawn(<span style="color: #51afef;">move</span> || {
            <span style="color: #51afef;">while</span> <span style="color: #51afef;">let</span> <span style="color: #ECBE7B;">Ok</span>(next_num) = receiver.recv() {
                factor_number(next_num);
            }
        }));
    }

    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">stdin</span> = <span style="color: #a9a1e1;">std</span>::<span style="color: #a9a1e1;">io</span>::stdin();
    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">line</span> <span style="color: #51afef;">in</span> stdin.lock().lines() {
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">num</span> = line.unwrap().parse::&lt;<span style="color: #ECBE7B;">u32</span>&gt;().unwrap();
        sender.send(num).expect(<span style="color: #98be65;">"Cannot send to channel when there is no receiver"</span>);
    }

    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">decrement the sender counter, when no sender, the channel is closed</span>
    drop(sender);

    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">thread</span> <span style="color: #51afef;">in</span> threads {
        thread.join().expect(<span style="color: #98be65;">"panic"</span>);
    }
}
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orga78e457" class="outline-2">
<h2 id="orga78e457"><span class="section-number-2">2.</span> Networking systems</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-org07da297" class="outline-3">
<h3 id="org07da297"><span class="section-number-3">2.1.</span> System</h3>
<div class="outline-text-3" id="text-2-1">
</div>
<div id="outline-container-org6827dc5" class="outline-4">
<h4 id="org6827dc5"><span class="section-number-4">2.1.1.</span> File system</h4>
<div class="outline-text-4" id="text-2-1-1">
<ul class="org-ul">
<li>Open file (OF) table: system-wide table, stores file position, access mode (read/write) and reference count.</li>
<li>File descriptor (FD) table: process-specific table, maps file descriptor integers to references in the OF table; multiple FD entries can point to the same OF entry (e.g., parent and child processes share file positions).</li>
<li>Vnode table: system-wide table, contains file (e.g., terminal, socket) size, permissions, timestamps, disk block locations; multiple  OF entries can reference the same vnode entry, indicating same file opened multiple times.</li>
</ul>
</div>
</div>
<div id="outline-container-org4d30174" class="outline-4">
<h4 id="org4d30174"><span class="section-number-4">2.1.2.</span> Start a server</h4>
<div class="outline-text-4" id="text-2-1-2">
<ul class="org-ul">
<li>A process creates a socket file descriptor with a queue for connection requests.</li>
<li>The process binds the socket with specific IP and port.</li>
<li>The process listens and accepts connections in a loop.</li>
</ul>
</div>
</div>
<div id="outline-container-org09d4a4b" class="outline-4">
<h4 id="org09d4a4b"><span class="section-number-4">2.1.3.</span> Connect to a server (ignore networking details)</h4>
<div class="outline-text-4" id="text-2-1-3">
<ul class="org-ul">
<li>The client creates a socket and send the socket address in the SYN packet.</li>
<li>The server accpets the request and start a new clinet-specific socket to establish a bidirectional communication channel.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orge4156d8" class="outline-3">
<h3 id="orge4156d8"><span class="section-number-3">2.2.</span> Scalability and avilability</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li>Internet traffic has grown faster than hardware has increased in power.</li>
<li>Two machines with commodity performance is much cheaper than one machine with 2x performance.</li>
<li>Need to distribute a system&rsquo;s functionality over servers using networking.</li>
<li>Scale out: separate stateless computation and data storage.</li>
<li><a href="https://blog.codinghorror.com/working-with-the-chaos-monkey/">Chaos engineering</a>: intentionally introduce failures on production, e.g., randomly terminates an entire datacenter or even a region.</li>
</ul>
</div>
<div id="outline-container-orga346693" class="outline-4">
<h4 id="orga346693"><span class="section-number-4">2.2.1.</span> Load balancers</h4>
<div class="outline-text-4" id="text-2-2-1">
<ul class="org-ul">
<li>Relay client requests to one compute node; health check each compute node.</li>
<li>Load balancing load balancers:
<ul class="org-ul">
<li>Round-robin DNS; DNS return multiple IPs for the same hostname.
<ul class="org-ul">
<li>Hard to consistently rotate IPs if the DNS responses are cached.</li>
<li>DNS has no idea of IP health.</li>
</ul></li>
<li>Geographic routing: DNS servers respond with the load balancer IP closest to the client.
<ul class="org-ul">
<li>If the cloest data center is done, availability is still broken.</li>
</ul></li>
<li>IP anycast: multiple computers announce they own the same IP (BGP).</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org423b813" class="outline-3">
<h3 id="org423b813"><span class="section-number-3">2.3.</span> Security</h3>
<div class="outline-text-3" id="text-2-3">
<ul class="org-ul">
<li>Authentication: who are you? Authorization: are you allowed?</li>
<li>Prevent confidential data leakage: use a framework to handle every request, check authenticartion/authorization; use type systems.</li>
<li>Elasticsearch: distributed, open source search and analytics engine for all types of data; involved in multiple <a href="https://www.troyhunt.com/the-unattributable-db8151dd-data-breach/">data breach</a> incidents.
<ul class="org-ul">
<li>Why: bad default settings, e.g., default username and password; accept all connections by default.</li>
</ul></li>
<li>Design principles: needs to be harder to do things wrong than to do thing right.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org3081613" class="outline-2">
<h2 id="org3081613"><span class="section-number-2">3.</span> Event-driven programming</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Threads: a lightweight process; has own stack, CPU registers, status; managed by OS scheduler, e.g., swap on and off the core.
<ul class="org-ul">
<li>States: block, ready, running</li>
</ul></li>
<li>Block syscalls: every thread runs for a time slice before switched by OS, or give up the slice early if it is blocked by e.g., <code>read</code>, <code>waitpid</code>, <code>cv.wait</code>, <code>lock</code>, <code>sleep</code>.</li>
<li>Switching threads are expensive:
<ul class="org-ul">
<li>Context switching cost: switch virtual address space, restore register and cache, etc.</li>
<li>Memory overhead: each thread consumes stack memory.</li>
</ul></li>
<li>The thread could have done other work when it is blocked on one request.</li>
<li><b><b>Non-blocking I/O</b></b>: One thread handles concurrent I/O with <a href="https://en.wikipedia.org/wiki/Epoll">Epoll</a>, which repeatedly notifies what file descriptors are ready for I/O.
<ul class="org-ul">
<li>Key problem: state management.</li>
</ul></li>
</ul>
</div>
<div id="outline-container-orgb6048c3" class="outline-3">
<h3 id="orgb6048c3"><span class="section-number-3">3.1.</span> Rust future</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>Fututres are single eventual values produced by asynchronous computations.</li>
<li>Keep track of in-progress operations along with associated state; each future handles one operation.</li>
</ul>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #83898d;">/// A simplified version of Future definition</span>
<span style="color: #51afef;">trait</span> <span style="color: #ECBE7B;">Future</span> {
<span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">Output</span>;
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">the executor thread calls poll() to start running until it cannot progress</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">cx includes a wake() function so that the future wakes up the executor when it can progress again</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">when wake() is called, the executor uses cx to identify the future that can make new progress</span>
<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">poll</span>(<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> <span style="color: #51afef;">self</span>, <span style="color: #dcaeea;">cx</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> <span style="color: #ECBE7B;">Context</span>) -&gt; <span style="color: #ECBE7B;">Poll</span>&lt;<span style="color: #ECBE7B;">Self</span>::<span style="color: #ECBE7B;">Output</span>&gt;;
}

<span style="color: #51afef;">enum</span> <span style="color: #ECBE7B;">Poll</span>&lt;<span style="color: #ECBE7B;">T</span>&gt; {
<span style="color: #ECBE7B;">Ready</span>(<span style="color: #ECBE7B;">T</span>),
<span style="color: #83898d;">/// Allow the single thread to work on other future</span>
<span style="color: #ECBE7B;">Pending</span>,
}
</pre>
</div>

<ul class="org-ul">
<li>In practice, futures are composed with various combinators.</li>
</ul>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #5B6268;">// </span><span style="color: #5B6268;">This is just an example to show combinator,</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">it is not real code, as this is hard to maintain when complexity increases</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">and shared data must be propogated through the chain even if they are not always used</span>
<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">addToInbox</span>(<span style="color: #dcaeea;">email_id</span>: <span style="color: #ECBE7B;">u64</span>, <span style="color: #dcaeea;">recipient_id</span>: <span style="color: #ECBE7B;">u64</span>) -&gt; <span style="color: #51afef;">impl</span> <span style="color: #ECBE7B;">Future</span>&lt;<span style="color: #ECBE7B;">Output</span> = <span style="color: #ECBE7B;">Result</span>&lt;(), <span style="color: #ECBE7B;">Error</span>&gt;&gt; {  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">return type is tedious</span>
    loadMessage(email_id)
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">message is needed in get_recipient, but later future needs</span>
        .and_then(|message| get_recipient(message, recipient_id))
        .map(|(message, recipient)| recipient.verifyHasSpace(<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>message))
        .and_then(|(message, recipient)| recipient.addToInbox(message))
}
</pre>
</div>

<ul class="org-ul">
<li>Can write futures that depend on multiple concurrently-executing futures.</li>
</ul>
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">let</span> <span style="color: #dcaeea;">cook_meal_future</span> = <span style="color: #a9a1e1;">futures</span>::<span style="color: #a9a1e1;">future</span>::join(
    <span style="color: #51afef; font-weight: bold;">vec!</span>[
        <span style="color: #ECBE7B;">CookMeatFuture</span>::new(),
        <span style="color: #ECBE7B;">CookMeatFuture</span>::new(),
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">future may return Pending after complete 2 futures,</span>
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the next time when the executor calls poll(), the state is restored</span>
        <span style="color: #ECBE7B;">CookSoupFuture</span>::new(),
        <span style="color: #ECBE7B;">BakeBreadFuture</span>::new()
    ]
);
</pre>
</div>

<ul class="org-ul">
<li>Syntax suger: <code>async</code> and <code>await</code>.</li>
</ul>
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #5B6268;">// </span><span style="color: #5B6268;">An async function is a function that returns future</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">the compiler transform the code into Future with poll()</span>
<span style="color: #51afef;">async</span> <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">addToInbox</span>(<span style="color: #dcaeea;">email_id</span>: <span style="color: #ECBE7B;">u64</span>, <span style="color: #dcaeea;">recipient_id</span>: <span style="color: #ECBE7B;">u64</span>) -&gt; <span style="color: #ECBE7B;">Result</span>&lt;(), <span style="color: #ECBE7B;">Error</span>&gt; {
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">.await waits for a future and gets its value</span>
    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">message</span> = loadMessage(email_id).<span style="color: #51afef;">await</span><span style="color: #c678dd; font-weight: bold;">?</span>;
    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">recipient</span> = get_recipient(recipient_id).<span style="color: #51afef;">await</span><span style="color: #c678dd; font-weight: bold;">?</span>;
    recipient.verifyHasSpace(<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>message)<span style="color: #c678dd; font-weight: bold;">?</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">this is a normal function</span>
    recipient.addToInbox(message).<span style="color: #51afef;">await</span>
}
</pre>
</div>

<ul class="org-ul">
<li>An async function does not do anything when running it, its purpose is to produce a future that does the stuff written in the function.</li>
</ul>
</div>
<div id="outline-container-org9fb7399" class="outline-4">
<h4 id="org9fb7399"><span class="section-number-4">3.1.1.</span> Executor</h4>
<div class="outline-text-4" id="text-3-1-1">
<ul class="org-ul">
<li>An executor loops over futures that can currently make progress and call <code>poll</code> on them; or go to sleep until some future calls <code>wake</code>.</li>
<li>A popular executor is Tokio; it allows multiple executors to execute futures in parallel.
<ul class="org-ul">
<li>Need to protect shared data with synchronization primitives acorss futures.</li>
</ul></li>
<li>Futures cannot block, e.g., call <code>lock</code>, otherwise the executor cannot continue other futures.
<ul class="org-ul">
<li>Tokio provides a non-blocking versions for synchronization primitives.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org7fe885f" class="outline-4">
<h4 id="org7fe885f"><span class="section-number-4">3.1.2.</span> Tokio</h4>
<div class="outline-text-4" id="text-3-1-2">
<ul class="org-ul">
<li>Convert blocking functions into async versions.</li>
</ul>
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">use</span> <span style="color: #a9a1e1;">tokio</span>::<span style="color: #a9a1e1;">io</span>::{<span style="color: #ECBE7B;">AsyncReadExt</span>, <span style="color: #ECBE7B;">AsyncWriteExt</span>};
<span style="color: #51afef;">use</span> <span style="color: #a9a1e1;">tokio</span>::<span style="color: #a9a1e1;">net</span>::<span style="color: #ECBE7B;">TcpListener</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">should not block in async code</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">futures do not do anything until an executor executes them</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">the macro generates a sync main which creates a runtime executor </span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">and submits the returned future to the executor</span>
<span style="color: #51afef; font-weight: bold;">#[tokio::main]</span>
<span style="color: #51afef;">async</span> <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">main</span>() {
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">listener</span> = <span style="color: #ECBE7B;">TcpListener</span>::bind(<span style="color: #98be65;">"127.0.0.1:8080"</span>).<span style="color: #51afef;">await</span>.unwrap();
<span style="color: #51afef;">loop</span> {
    <span style="color: #51afef;">let</span> (<span style="color: #51afef;">mut</span> socket, _) = listener.accept().<span style="color: #51afef;">await</span>.unwrap();
    <span style="color: #a9a1e1;">tokio</span>::spawn(<span style="color: #51afef;">async</span> <span style="color: #51afef;">move</span> {  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">an async block</span>
        <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">buf</span> = [0; 1024];
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">n</span> = socket.read(<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> buf).<span style="color: #51afef;">await</span>.unwrap();
        socket.write_all(<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>buf[0..n]).<span style="color: #51afef;">await</span>.unwrap();
    });
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org6c2af8e" class="outline-4">
<h4 id="org6c2af8e"><span class="section-number-4">3.1.3.</span> Compilation</h4>
<div class="outline-text-4" id="text-3-1-3">
<ul class="org-ul">
<li>Normal (synchronous) code stores variables on the stack.
<ul class="org-ul">
<li>When calling another function, the inner function gets a new stack frame and CPU remembers the return address.</li>
<li>When the function returns, the stack frame is popped and CPU jumps back to the return address.</li>
</ul></li>
<li>Async functions may return multiple times at each <code>.await</code>, everytime it returns, the stack frame is popped, so the async function needs to maintain its state in its returned future object.</li>
<li>The compiler transforms the async function into a state enum that implements <code>Future</code> and an implementation of <code>poll()</code>.</li>
</ul>
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">enum</span> <span style="color: #ECBE7B;">AddToInboxState</span> {
    <span style="color: #ECBE7B;">NotYetStarted</span> {
        <span style="color: #dcaeea;">email_id</span>: <span style="color: #ECBE7B;">u64</span>,
        <span style="color: #dcaeea;">recipient_id</span>: <span style="color: #ECBE7B;">u64</span>,
    },
    <span style="color: #ECBE7B;">WaitingLoadMessage</span> {
        <span style="color: #dcaeea;">recipient_id</span>: <span style="color: #ECBE7B;">u64</span>, <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the data is to be used in the next state</span>
        <span style="color: #dcaeea;">state</span>: <span style="color: #ECBE7B;">LoadMessageFuture</span>,
    },
    <span style="color: #ECBE7B;">WaitingGetRecipient</span> {
        <span style="color: #dcaeea;">message</span>: <span style="color: #ECBE7B;">Message</span>,
        <span style="color: #dcaeea;">state</span>: <span style="color: #ECBE7B;">GetRecipientFuture</span>,
    },
    <span style="color: #ECBE7B;">WaitingAddToInbox</span> {
        <span style="color: #dcaeea;">state</span>: <span style="color: #ECBE7B;">AddToInboxFuture</span>,
    },
    <span style="color: #ECBE7B;">Completed</span> {
        <span style="color: #dcaeea;">result</span>: <span style="color: #ECBE7B;">Result</span>&lt;(), <span style="color: #ECBE7B;">Error</span>&gt;,
    },
}

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">this is only concept code, not real implementation</span>
<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">poll</span>() {
    <span style="color: #51afef;">match</span> <span style="color: #51afef;">self</span>.state {
        <span style="color: #ECBE7B;">NotYetStarted</span>(email_id, recipient_id) =&gt; {
            <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">next_future</span> = load_message(email_id);
            <span style="color: #51afef;">self</span>.state = <span style="color: #ECBE7B;">AddToInboxState</span>::<span style="color: #ECBE7B;">WaitingLoadMessage</span> {
                <span style="color: #dcaeea;">recipient_id</span>: *recipient_id,
                <span style="color: #dcaeea;">state</span>: next_future,
            };
        }
        <span style="color: #ECBE7B;">WaitingLoadMessage</span>(recipient_id, state) =&gt; {
            <span style="color: #51afef;">match</span> state.poll() {
                <span style="color: #ECBE7B;">Ready</span>(message) =&gt; {
                    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">next_future</span> = get_recipient(recipient_id);
                    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">switch to WaitingGetRecipient state</span>
                }
                <span style="color: #ECBE7B;">Pending</span> =&gt; <span style="color: #51afef;">return</span> <span style="color: #ECBE7B;">Pending</span>,
            }
        }
        <span style="color: #ECBE7B;">WaitingGetRecipient</span>(message, state) =&gt; {
            <span style="color: #51afef;">match</span> state.poll() {
                <span style="color: #ECBE7B;">Ready</span>(recipient) =&gt; {
                    recipient.verifyHasSpace(<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>message)<span style="color: #c678dd; font-weight: bold;">?</span>;
                    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">next_future</span> = recipient.addToInbox(message);
                    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">switch to WaitingAddToInbox state</span>
                }
                <span style="color: #ECBE7B;">Pending</span> =&gt; <span style="color: #51afef;">return</span> <span style="color: #ECBE7B;">Pending</span>,
            }
        }
    }
}
</pre>
</div>

<ul class="org-ul">
<li>All compiled futures are registered in the executor, the executor works as a scheduler and polls each future when it wakes up.</li>
<li>The executor does not care each future&rsquo;s internal state, this is maintained in the future context.</li>
<li>The executor polls <code>main</code> future first and run until it reaches <code>.await</code>.</li>
<li>When an async function polls another async function, if the inner future returns <code>Pending</code>, the outer future also returns <code>Pending</code>; when the inner future is ready, it wakes the whole task in the executor, and the executor polls outer future again.</li>
<li>Sync functions consume stack, async functions consume heap as each future is live on heap.</li>
<li>Usage: I/O bound and highly concurrent, e.g., thousand network connections, DB queries.</li>
</ul>
</div>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-rust.html">rust</a> <a href="https://chenyo.me/tag-stanford.html">stanford</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[rust]]></category>
  <category><![CDATA[stanford]]></category>
  <link>https://chenyo.me/2025-08-04-cs110l-notes.html</link>
  <guid>https://chenyo.me/2025-08-04-cs110l-notes.html</guid>
  <pubDate>Mon, 04 Aug 2025 20:38:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Org static blog in Neovim]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orga1a43d0">1. Emacs non-interactive commands</a></li>
<li><a href="#orgc088ca2">2. Correct HTML export</a></li>
<li><a href="#org9dbe8bc">3. Modify Emacs function</a></li>
<li><a href="#org2058482">4. Create Neovim functions</a></li>
</ul>
</div>
</nav>
<p>
This post records how I use org static blog in Neovim with <a href="https://github.com/nvim-orgmode/orgmode">nvim-orgmode</a>.
</p>
<div id="outline-container-orga1a43d0" class="outline-2">
<h2 id="orga1a43d0"><span class="section-number-2">1.</span> Emacs non-interactive commands</h2>
<div class="outline-text-2" id="text-1">
<p>
The emacs <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Batch-Mode.html">batch mode</a> does not really work for me.
So I use the <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Invoking-emacsclient.html">emacsclient</a> instead. The basic usage is like following:
</p>

<div class="org-src-container">
<pre class="src src-bash">emacsclient -e <span style="color: #98be65;">"(org-static-blog-publish)"</span> <span style="color: #5B6268;"># </span><span style="color: #5B6268;">no arguments</span>
emacsclient -e <span style="color: #98be65;">'(progn (org-static-blog-create-new-post-non-interactive "New Post Title"))'</span> <span style="color: #5B6268;"># </span><span style="color: #5B6268;">with arguments</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgc088ca2" class="outline-2">
<h2 id="orgc088ca2"><span class="section-number-2">2.</span> Correct HTML export</h2>
<div class="outline-text-2" id="text-2">
<p>
While I can start a daemon with <code>emacs --daemon</code> to run <code>emacsclient</code>, the HTML export done by <code>org-static-blog-publish</code> lacks correct syntax highlighting in code block and messes up other page layout.
It seems due to under the daemon mode some packages are not properly initialized.
I don&rsquo;t have enough knowledge for this, so I take a brutal way: open the Emacs GUI, run the command, and close GUI.
On OSX, the commands look like this:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #5B6268;"># </span><span style="color: #5B6268;">~/.config/nvim/scripts/org-static-blog-publish.sh</span>
open -n /Applications/Emacs.app --args --eval <span style="color: #98be65;">"(server-start)"</span>
<span style="color: #ECBE7B;">sleep</span> 1  <span style="color: #5B6268;"># </span><span style="color: #5B6268;">necessary, otherwise emacsclient command is not received</span>
emacsclient -e <span style="color: #98be65;">"(org-static-blog-publish)"</span>
emacsclient -e <span style="color: #98be65;">"(kill-emacs)"</span>
</pre>
</div>

<p>
Then in the Neovim config, execute it like following (don&rsquo;t forget <code>chmod +x</code> first):
</p>

<div class="org-src-container">
<pre class="src src-lua">vim.fn.jobstart(vim.fn.expand(<span style="color: #98be65;">"~/.config/nvim/scripts/org-static-blog-publish.sh"</span>), {})
</pre>
</div>
</div>
</div>
<div id="outline-container-org9dbe8bc" class="outline-2">
<h2 id="org9dbe8bc"><span class="section-number-2">3.</span> Modify Emacs function</h2>
<div class="outline-text-2" id="text-3">
<p>
In the original function, <code>org-static-blog-create-new-post</code> is an interactive command that requires users to input and confirm a title.
To use <code>emacsclient</code>, I wrap it with a non-interactive function like following:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(<span style="color: #51afef;">defun</span> <span style="color: #c678dd;">org-static-blog-create-new-post-non-interactive</span> (title)
(<span style="color: #51afef;">require</span> '<span style="color: #a9a1e1;">org-static-blog</span>)
(<span style="color: #51afef;">let</span> ((filename (concat (format-time-string <span style="color: #98be65;">"%Y-%m-%d-"</span> (current-time))
                        (replace-regexp-in-string org-static-blog-suggested-filename-cleaning-regexp
                                                  <span style="color: #98be65;">"-"</span> (downcase title))
                        <span style="color: #98be65;">".org"</span>)))
  (find-file (concat-to-dir
              org-static-blog-posts-directory
              filename))
  (save-buffer)))
</pre>
</div>
</div>
</div>
<div id="outline-container-org2058482" class="outline-2">
<h2 id="org2058482"><span class="section-number-2">4.</span> Create Neovim functions</h2>
<div class="outline-text-2" id="text-4">
<p>
Finally, add the Neovim commands as following:
</p>
<div class="org-src-container">
<pre class="src src-lua"><span style="color: #51afef;">local</span> <span style="color: #dcaeea;">M</span> = {}
vim.api.nvim_create_user_command(<span style="color: #98be65;">"OrgBlogNewPost"</span>, <span style="color: #51afef;">function</span>(<span style="color: #dcaeea;">opts</span>)
  <span style="color: #51afef;">local</span> <span style="color: #dcaeea;">title</span> = <span style="color: #c678dd;">table</span>.<span style="color: #c678dd;">concat</span>(opts.fargs, <span style="color: #98be65;">" "</span>)
  M.create_post_with_title(title)
<span style="color: #51afef;">end</span>, { nargs = <span style="color: #98be65;">"*"</span>, desc = <span style="color: #98be65;">"Create new org static blog post"</span> })

vim.api.nvim_create_user_command(
  <span style="color: #98be65;">"OrgBlogPublish"</span>,
  <span style="color: #51afef;">function</span>() M.publish_blog() <span style="color: #51afef;">end</span>,
  { desc = <span style="color: #98be65;">"Publish org static blog"</span> }
)
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-vim.html">vim</a> <a href="https://chenyo.me/tag-org.html">org</a> </div>]]></description>
  <category><![CDATA[vim]]></category>
  <category><![CDATA[org]]></category>
  <link>https://chenyo.me/2025-08-03-org-static-blog-in-neovim.html</link>
  <guid>https://chenyo.me/2025-08-03-org-static-blog-in-neovim.html</guid>
  <pubDate>Sun, 03 Aug 2025 17:08:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Configure PHP with Doom Emacs on Arch Linux]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgcce816f">1. Terminal Installation</a></li>
<li><a href="#orgfa6c37e">2. Emacs Configuration</a></li>
<li><a href="#org784f9f4">3. Usage</a></li>
</ul>
</div>
</nav>
<p>
This post records my steps of installing and configuring basic PHP with Doom Emacs and Arch Linux.
</p>
<div id="outline-container-orgcce816f" class="outline-2">
<h2 id="orgcce816f"><span class="section-number-2">1.</span> Terminal Installation</h2>
<div class="outline-text-2" id="text-1">
<ol class="org-ol">
<li><code>yay php</code>: install PHP.</li>
<li><code>yay composer</code>: install PHP package manager.</li>
<li><code>yay phpactor</code>: install the language server.</li>
<li>Install the following packages with `composer` globally so any project can use it:
<ul class="org-ul">
<li><code>composer global require phpunit/phpunit</code>: install PHP test framework.</li>
<li><code>composer global require techlivezheng/phpctags</code>: better code completion.</li>
<li><code>composer global require friendsofphp/php-cs-fixer</code>: code formatting.</li>
</ul></li>
<li>Export the <code>composer</code> global path with <code>export PATH="$PATH:$HOME/.config/composer/vendor/bin" &gt;&gt; ~/.zshrc</code>.</li>
<li>Configure <code>phpactor</code> to auto-load global packages:
<ul class="org-ul">
<li><p>
Create file <code>~/.config/phpactor/phpactor.yml</code> and write to file:
</p>
<div class="org-src-container">
<pre class="src src-yaml"><span style="color: #dcaeea;">composer.autoloader_path</span>:
  - ~/.config/composer/vendor/autoload.php
</pre>
</div></li>
</ul></li>
</ol>
</div>
</div>
<div id="outline-container-orgfa6c37e" class="outline-2">
<h2 id="orgfa6c37e"><span class="section-number-2">2.</span> Emacs Configuration</h2>
<div class="outline-text-2" id="text-2">
<ol class="org-ol">
<li>Uncomment <code>(php +lsp)</code> in  <code>init.el</code>.</li>
<li>Add packages <code>(package! phpactor)</code> and <code>(package! php-cs-fixer)</code> to <code>packages.el</code> to use their interfaces in Emacs.</li>
<li><p>
Configure <code>config.el</code> as following:
</p>
<div class="org-src-container">
<pre class="src src-lisp">(after! lsp-mode
    (setq lsp-disabled-clients '(intelephense php-ls))  <span style="color: #5B6268;">;; </span><span style="color: #5B6268;">disable other language servers</span>
  (setq lsp-php-server 'phpactor)  <span style="color: #5B6268;">;; </span><span style="color: #5B6268;">set the language explicitly</span>
  (setq lsp-phpactor-path (executable-find <span style="color: #98be65;">"phpactor"</span>)))

(use-package! php-mode
  <span style="color: #c678dd;">:hook</span> (php-mode . lsp-deferred))  <span style="color: #5B6268;">;; </span><span style="color: #5B6268;">defer lsp loading</span>
</pre>
</div></li>
<li>run <code>doom sync</code> and restart the Emacs.</li>
</ol>
</div>
</div>
<div id="outline-container-org784f9f4" class="outline-2">
<h2 id="org784f9f4"><span class="section-number-2">3.</span> Usage</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Use <code>M-x lsp-describe-session</code> to verify <code>phpactor</code> is in use.</li>
<li>Use <code>M-x php-cs-fixer-fix</code> to format the current PHP buffer.</li>
<li>Use <code>M-x phpunit-current-test</code> to run the tests in the current buffer.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-php.html">php</a> <a href="https://chenyo.me/tag-linux.html">linux</a> <a href="https://chenyo.me/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[php]]></category>
  <category><![CDATA[linux]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://chenyo.me/2025-01-31-configure-php-with-doom-emacs-on-arch-linux.html</link>
  <guid>https://chenyo.me/2025-01-31-configure-php-with-doom-emacs-on-arch-linux.html</guid>
  <pubDate>Fri, 31 Jan 2025 16:31:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Interesting Rust snippets]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org62935f2">1. References</a></li>
<li><a href="#org87fc779">2. Reference and lifetime</a></li>
<li><a href="#orgebad419">3. Traits</a>
<ul>
<li><a href="#org89b3bea">3.1. Associated types</a></li>
<li><a href="#org5c10eb1">3.2. Static/Dynamic dispatch</a></li>
<li><a href="#orgca620aa">3.3. Trait bounds</a></li>
<li><a href="#org48a674d">3.4. Existential types</a></li>
</ul>
</li>
<li><a href="#org83f62fb">4. Linked-list</a>
<ul>
<li><a href="#orge5d18c5">4.1. Leetcode 146: LRU cache</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<div id="outline-container-org62935f2" class="outline-2">
<h2 id="org62935f2"><span class="section-number-2">1.</span> References</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li><a href="https://rust-for-rustaceans.com/">Rust for Rustaceans</a></li>
<li><a href="https://rustlings.cool/">Rustlings</a></li>
<li><a href="https://tfpk.github.io/lifetimekata/">LifetimeKata</a></li>
<li>Claude</li>
</ul>
</div>
</div>
<div id="outline-container-org87fc779" class="outline-2">
<h2 id="org87fc779"><span class="section-number-2">2.</span> Reference and lifetime</h2>
<div class="outline-text-2" id="text-2">
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">x</span>;
x = <span style="color: #da8548; font-weight: bold;">42</span>;
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">y</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>x;
x = <span style="color: #da8548; font-weight: bold;">43</span>;
<span style="color: #51afef; font-weight: bold;">assert_eq!</span><span style="color: #51afef;">(</span>*y, <span style="color: #da8548; font-weight: bold;">42</span><span style="color: #51afef;">)</span>;
</pre>
</div>

<p>
The above code will cause compiler error at <code>x=43</code> since <code>x</code> has a shared reference which is still active after <code>x=43</code>. If we comment the <code>assert_eq!</code>, the code compiles.
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">x</span> = <span style="color: #ECBE7B;">Vec</span>::new<span style="color: #51afef;">()</span>;
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">y</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> x;
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">z</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> x;
y.push<span style="color: #51afef;">(</span><span style="color: #da8548; font-weight: bold;">42</span><span style="color: #51afef;">)</span>;
z.push<span style="color: #51afef;">(</span><span style="color: #da8548; font-weight: bold;">13</span><span style="color: #51afef;">)</span>;
<span style="color: #51afef; font-weight: bold;">assert_eq!</span><span style="color: #51afef;">(</span>x, <span style="color: #c678dd;">[</span><span style="color: #da8548; font-weight: bold;">42</span>, <span style="color: #da8548; font-weight: bold;">13</span><span style="color: #c678dd;">]</span><span style="color: #51afef;">)</span>;
</pre>
</div>

<p>
Similarly, the code above will cause compiler error at <code>let z = &amp;mut x</code> since at this point there exist two mutable references for <code>x</code>. If we swap this line with <code>y.push(42)</code>, the error is resolved because <code>y</code> is never used after <code>let z = &amp;mut x</code> now.
</p>

<p>
The compiler accepts the following code. In <code>*x = 84</code>, the borrow checker takes out a mutable reference to <code>x</code>, while there is also a shared reference <code>r = &amp;x</code> in the scope at the same time, since it is not accessed later, it does not create a conflict flow. Similarly, when <code>println!("{z}")</code>, the borrow checker walks back the path and finds no conflict until the <code>r</code> us created.
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">x</span> = <span style="color: #ECBE7B;">Box</span>::new<span style="color: #51afef;">(</span><span style="color: #da8548; font-weight: bold;">42</span><span style="color: #51afef;">)</span>;
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">r</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>x; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">lifetime 'a starts</span>
<span style="color: #51afef;">if</span> rand<span style="color: #51afef;">()</span> &gt; <span style="color: #da8548; font-weight: bold;">0.5</span> <span style="color: #51afef;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">deref a Box returns a shared or a mutable reference</span>
    *x = <span style="color: #da8548; font-weight: bold;">84</span>;
<span style="color: #51afef;">}</span> <span style="color: #51afef;">else</span> <span style="color: #51afef;">{</span>
    <span style="color: #c678dd;">println!</span><span style="color: #c678dd;">(</span><span style="color: #98be65;">"</span><span style="color: #98be65; font-style: italic;">{z}</span><span style="color: #98be65;">"</span><span style="color: #c678dd;">)</span>;
<span style="color: #51afef;">}</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">println!("{z}");  // this will cause the compiler error</span>
</pre>
</div>

<p>
The following code also compiles, even when the lifetime is intermittently invalid:
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">x</span> = <span style="color: #ECBE7B;">Box</span>::new<span style="color: #51afef;">(</span><span style="color: #da8548; font-weight: bold;">42</span><span style="color: #51afef;">)</span>;
<span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">z</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>x;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">liefttime 'a starts</span>
<span style="color: #51afef;">for</span> <span style="color: #dcaeea;">i</span> <span style="color: #51afef;">in</span> <span style="color: #da8548; font-weight: bold;">0</span>..<span style="color: #da8548; font-weight: bold;">100</span> <span style="color: #51afef;">{</span>
    <span style="color: #c678dd;">println!</span><span style="color: #c678dd;">(</span><span style="color: #98be65;">{</span><span style="color: #98be65;">"z"</span><span style="color: #98be65;">}</span><span style="color: #c678dd;">)</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">lifetime 'a ends here</span>
    x = <span style="color: #ECBE7B;">Box</span>::new<span style="color: #c678dd;">(</span>i<span style="color: #c678dd;">)</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">x is moved</span>
    z = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>x;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">restart lifetime 'a</span>
<span style="color: #51afef;">}</span>
<span style="color: #c678dd;">println!</span><span style="color: #51afef;">(</span><span style="color: #98be65;">"</span><span style="color: #98be65; font-style: italic;">{z}</span><span style="color: #98be65;">"</span><span style="color: #51afef;">)</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">'a ends here</span>
</pre>
</div>

<p>
In the following code, we have to use two generic lifetime annotations:
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">MutStr</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span>, '<span style="color: #dcaeea;">b</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #dcaeea;">_s</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #51afef;">mut</span> <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">b</span> <span style="color: #ECBE7B;">str</span>
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">s</span> = <span style="color: #98be65;">"hello"</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">creates a 'static lifetime to "hello"</span>
*<span style="color: #ECBE7B;">MutStr</span> <span style="color: #51afef;">{</span><span style="color: #dcaeea;">_s</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> s<span style="color: #51afef;">}</span>._s = <span style="color: #98be65;">"world"</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">creates a mutable reference to s</span>
<span style="color: #c678dd;">println!</span><span style="color: #51afef;">(</span><span style="color: #98be65;">"</span><span style="color: #98be65; font-style: italic;">{s}</span><span style="color: #98be65;">"</span><span style="color: #51afef;">)</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">creates a shared reference to s, now s is "world"</span>
</pre>
</div>

<p>
To <code>println("{s}")</code>, the borrow checker has to assume that the lifetime of the mutable reference to <code>s</code>  <code>'a</code> ends at the line before, and <code>'b</code> is always <code>'static</code> as a reference to a string slice.
If we use <code>'a</code> only, then the borrow checker tries to shorten <code>'static</code> to <code>'a</code>, but since the lifetime is behind <code>&amp;mut</code> which is invariant (see &ldquo;Rust for Rustaceans&rdquo; Ch 1), the conversion will fail.
</p>

<p>
Lifetimes are required when there exists mutable references in the function parameters, even if there is no output reference. In the following code, we need <code>'contents</code> to make sure the new inserted value lives for at least as long as the vector content.
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">fn</span> <span style="color: #c678dd;">insert_value</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">vector</span>, '<span style="color: #dcaeea;">content</span><span style="color: #51afef;">&gt;(</span><span style="color: #dcaeea;">my_vec</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">vector</span> <span style="color: #51afef;">mut</span> <span style="color: #ECBE7B;">Vec</span><span style="color: #c678dd;">&lt;</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">content</span> <span style="color: #ECBE7B;">i32</span><span style="color: #c678dd;">&gt;</span>, <span style="color: #dcaeea;">value</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">content</span> <span style="color: #ECBE7B;">i32</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{</span>
    my_vec.push<span style="color: #c678dd;">(</span>value<span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">value needs to live for as long as the contents of my_vec, aka my_vec</span>
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">x</span> = <span style="color: #da8548; font-weight: bold;">1</span>;
    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">my_vec</span> = <span style="color: #51afef; font-weight: bold;">vec!</span><span style="color: #c678dd;">[</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>x<span style="color: #c678dd;">]</span>;
    <span style="color: #c678dd;">{</span>
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">y</span> = <span style="color: #da8548; font-weight: bold;">2</span>;
        insert_value<span style="color: #98be65;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> my_vec, <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>y<span style="color: #98be65;">)</span>;
    <span style="color: #c678dd;">}</span>
    <span style="color: #c678dd;">println!</span><span style="color: #c678dd;">(</span><span style="color: #98be65;">"</span><span style="color: #98be65; font-style: italic;">{my_vec:?}</span><span style="color: #98be65;">"</span><span style="color: #c678dd;">)</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>

<p>
It&rsquo;s important to note that the single lifetime does not work, see the usage below:
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">fn</span> <span style="color: #c678dd;">insert_value</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span><span style="color: #51afef;">&gt;(</span><span style="color: #dcaeea;">my_vec</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #51afef;">mut</span> <span style="color: #ECBE7B;">Vec</span><span style="color: #c678dd;">&lt;</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">i32</span><span style="color: #c678dd;">&gt;</span>, <span style="color: #dcaeea;">value</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">i32</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{</span>
    my_vec.push<span style="color: #c678dd;">(</span>value<span style="color: #c678dd;">)</span>;
<span style="color: #51afef;">}</span>
<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
    <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">my_vec</span>: <span style="color: #ECBE7B;">Vec</span><span style="color: #c678dd;">&lt;</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #ECBE7B;">i32</span><span style="color: #c678dd;">&gt;</span> = <span style="color: #51afef; font-weight: bold;">vec!</span><span style="color: #c678dd;">[]</span>;
    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">val1</span> = <span style="color: #da8548; font-weight: bold;">1</span>;
    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">val2</span> = <span style="color: #da8548; font-weight: bold;">2</span>;
    insert_value<span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> my_vec, <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>val1<span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">&amp;val1 needs to live until the vector is dropped</span>
                                      <span style="color: #5B6268;">// </span><span style="color: #5B6268;">so is &amp;mut my_vec now</span>
    insert_value<span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> my_vec, <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>val2<span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the last &amp;mut my_vec is still valid!</span>
    <span style="color: #c678dd;">println!</span><span style="color: #c678dd;">(</span><span style="color: #98be65;">"</span><span style="color: #98be65; font-style: italic;">{my_vec:?}</span><span style="color: #98be65;">"</span><span style="color: #c678dd;">)</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>

<p>
We need to explicitly annotate the lifetime in the structs and its implementation. In the following code, <code>next_word</code> uses a second lifetime annotation to decouple the lifetime of the mutable reference to <code>WordIterator</code> and the next world, otherwise we have to drop the previous next word before getting a new next word.
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">WordIterator</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">s</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #dcaeea;">position</span>: <span style="color: #ECBE7B;">usize</span>,
    <span style="color: #dcaeea;">string</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">s</span> <span style="color: #ECBE7B;">str</span>,
<span style="color: #51afef;">}</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">impl&lt;'a&gt; defines a lifetime</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">WordIterator&lt;'a&gt; says the references in WordIterator must live for 'a</span>
<span style="color: #51afef;">impl</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span><span style="color: #51afef;">&gt;</span> <span style="color: #ECBE7B;">WordIterator</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">new</span><span style="color: #c678dd;">(</span><span style="color: #dcaeea;">string</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">str</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">WordIterator</span><span style="color: #c678dd;">&lt;</span>'<span style="color: #dcaeea;">a</span><span style="color: #c678dd;">&gt;</span> <span style="color: #c678dd;">{</span>
        <span style="color: #ECBE7B;">WordIterator</span> <span style="color: #98be65;">{</span>
            <span style="color: #dcaeea;">position</span>: <span style="color: #da8548; font-weight: bold;">0</span>,
            string,
        <span style="color: #98be65;">}</span>
    <span style="color: #c678dd;">}</span>

    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">Gives the next word, None if there is no word left</span>
    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">next_word</span><span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">b</span> <span style="color: #51afef;">mut</span> <span style="color: #51afef;">self</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">Option</span><span style="color: #c678dd;">&lt;</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">str</span><span style="color: #c678dd;">&gt;</span> <span style="color: #c678dd;">{</span>
        <span style="color: #51afef; font-weight: bold;">todo!</span><span style="color: #98be65;">()</span>
    <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>
</pre>
</div>

<p>
We can also use lifetime bounds to specify <code>'a</code> should outlives, i.e., live for at least as long as <code>'b</code> with <code>'a: 'b</code>:
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">fn</span> <span style="color: #c678dd;">f</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span>, '<span style="color: #dcaeea;">b</span><span style="color: #51afef;">&gt;(</span><span style="color: #dcaeea;">x</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">i32</span>, <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">y</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">b</span> <span style="color: #ECBE7B;">i32</span><span style="color: #51afef;">)</span>
<span style="color: #51afef;">where</span>
    '<span style="color: #dcaeea;">a</span>: '<span style="color: #dcaeea;">b</span>,
<span style="color: #51afef;">{</span>
    y = x; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">&amp;'a i32 is a subtype of &amp;'b</span>
    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">r</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">b</span> <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">i32</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;&amp;</span><span style="color: #da8548; font-weight: bold;">0</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">&amp;'b is never dangling</span>
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgebad419" class="outline-2">
<h2 id="orgebad419"><span class="section-number-2">3.</span> Traits</h2>
<div class="outline-text-2" id="text-3">
</div>
<div id="outline-container-org89b3bea" class="outline-3">
<h3 id="org89b3bea"><span class="section-number-3">3.1.</span> Associated types</h3>
<div class="outline-text-3" id="text-3-1">
<p>
One should use associated types instead of generic type parameters in a trait if there should only exist one trait implementation for any type. For instance, for any given type, the <code>Item</code> type should be unambiguous even if type contains generic parameters.
</p>
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">standard trait</span>
<span style="color: #5B6268;">trait Iterator {</span>
<span style="color: #5B6268;">    type Item;</span>
<span style="color: #5B6268;">    fn next(&amp;mut self) -&gt; Option&lt;Self::Item&gt;;</span>
<span style="color: #5B6268;">}</span>
<span style="color: #5B6268;">*/</span>

<span style="color: #51afef; font-weight: bold;">#</span><span style="color: #51afef; font-weight: bold;">[</span><span style="color: #51afef; font-weight: bold;">derive</span><span style="color: #c678dd; font-weight: bold;">(</span><span style="color: #51afef; font-weight: bold;">Default</span><span style="color: #c678dd; font-weight: bold;">)</span><span style="color: #51afef; font-weight: bold;">]</span>
<span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">MyVec</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">we cannot directly implement Iterator for MyVec&lt;T&gt; as it does not store internal states.</span>
    <span style="color: #dcaeea;">vec</span>: <span style="color: #ECBE7B;">Vec</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #c678dd;">&gt;</span>
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">MyVecIter</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span>, <span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #dcaeea;">vec</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">Vec</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #c678dd;">&gt;</span>,
    <span style="color: #dcaeea;">position</span>: <span style="color: #ECBE7B;">usize</span>,
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">impl</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span>, <span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #ECBE7B;">Iterator</span> <span style="color: #51afef;">for</span> <span style="color: #ECBE7B;">MyVecIter</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span>, <span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">Item</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">T</span>;

    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">next</span><span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> <span style="color: #51afef;">self</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">Option</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">Self</span>::<span style="color: #ECBE7B;">Item</span><span style="color: #c678dd;">&gt;</span> <span style="color: #c678dd;">{</span>
        <span style="color: #51afef;">if</span> <span style="color: #51afef;">self</span>.position &lt; <span style="color: #51afef;">self</span>.vec.len<span style="color: #98be65;">()</span> <span style="color: #98be65;">{</span>
            <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">item</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">self</span>.vec<span style="color: #a9a1e1;">[</span><span style="color: #51afef;">self</span>.position<span style="color: #a9a1e1;">]</span>;
            <span style="color: #51afef;">self</span>.position += <span style="color: #da8548; font-weight: bold;">1</span>;
            <span style="color: #ECBE7B;">Some</span><span style="color: #a9a1e1;">(</span>item<span style="color: #a9a1e1;">)</span>
        <span style="color: #98be65;">}</span> <span style="color: #51afef;">else</span> <span style="color: #98be65;">{</span>
            <span style="color: #ECBE7B;">None</span>
        <span style="color: #98be65;">}</span>
    <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">impl</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #ECBE7B;">MyVec</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">iter</span><span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">self</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">MyVecIter</span><span style="color: #c678dd;">&lt;</span>'<span style="color: #dcaeea;">_</span>, <span style="color: #ECBE7B;">T</span><span style="color: #c678dd;">&gt;</span> <span style="color: #c678dd;">{</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">this does not consume MyIter</span>
        <span style="color: #ECBE7B;">MyVecIter</span> <span style="color: #98be65;">{</span>
            <span style="color: #dcaeea;">vec</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">self</span>.vec,
            <span style="color: #dcaeea;">position</span>: <span style="color: #da8548; font-weight: bold;">0</span>,
        <span style="color: #98be65;">}</span>
    <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">impl</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span>, <span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #ECBE7B;">IntoIterator</span> <span style="color: #51afef;">for</span> <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">MyVec</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">this consumes MyIter</span>
    <span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">Item</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">T</span>;
    <span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">IntoIter</span> = <span style="color: #ECBE7B;">MyVecIter</span><span style="color: #c678dd;">&lt;</span>'<span style="color: #dcaeea;">a</span>, <span style="color: #ECBE7B;">T</span><span style="color: #c678dd;">&gt;</span>;

    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">into_iter</span><span style="color: #c678dd;">(</span><span style="color: #51afef;">self</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">Self</span>::<span style="color: #ECBE7B;">IntoIter</span> <span style="color: #c678dd;">{</span>
        <span style="color: #51afef;">self</span>.iter<span style="color: #98be65;">()</span>
    <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">usage</span>
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">my_vec</span> = <span style="color: #ECBE7B;">MyVec</span>::<span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">i32</span><span style="color: #51afef;">&gt;</span>::default<span style="color: #51afef;">()</span>;
<span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">my_vec_iter</span> = my_vec.into_iter<span style="color: #51afef;">()</span>;
my_vec_iter.next<span style="color: #51afef;">()</span>;
</pre>
</div>

<p>
On the other hands, sometimes we want multiple trait implementations for the given type, e.g., convert a type to both <code>String</code> and <code>i32</code>, or when the type has different generic bounds:
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">impl</span> <span style="color: #ECBE7B;">From</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">i32</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">for</span> <span style="color: #ECBE7B;">MyType</span> <span style="color: #51afef;">{}</span>

<span style="color: #51afef;">impl</span> <span style="color: #ECBE7B;">From</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">String</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">for</span> <span style="color: #ECBE7B;">MyType</span> <span style="color: #51afef;">{}</span>

<span style="color: #51afef;">impl</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #ECBE7B;">MyTrait</span> <span style="color: #51afef;">for</span> <span style="color: #ECBE7B;">Vec</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">where</span> <span style="color: #dcaeea;">T</span>: <span style="color: #ECBE7B;">Display</span> <span style="color: #51afef;">{}</span>

<span style="color: #51afef;">impl</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #ECBE7B;">MyTrait</span> <span style="color: #51afef;">for</span> <span style="color: #ECBE7B;">Vec</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">where</span> <span style="color: #dcaeea;">T</span>: <span style="color: #ECBE7B;">Debug</span> <span style="color: #51afef;">{}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org5c10eb1" class="outline-3">
<h3 id="org5c10eb1"><span class="section-number-3">3.2.</span> Static/Dynamic dispatch</h3>
<div class="outline-text-3" id="text-3-2">
<p>
There are two ways to pass into a function a type that implements a trait: static dispatch and dynamic dispatch:
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">fn</span> <span style="color: #c678dd;">static_dispatch</span><span style="color: #51afef;">(</span><span style="color: #dcaeea;">item</span>: <span style="color: #51afef;">impl</span> <span style="color: #ECBE7B;">MyTrait</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{}</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">or static_dispatch&lt;T: MyTrait&gt;(item: T) {}</span>

<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">dynamic_dispatch</span><span style="color: #51afef;">(</span><span style="color: #dcaeea;">item</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">dyn</span> <span style="color: #ECBE7B;">MyTrait</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{}</span>
</pre>
</div>

<p>
Static dispatch tells the compiler to make a copy of the function for each <code>T</code> and replace each generic parameter with the concrete type provided, which is called monomorphization.
In this way the compiler can optimize the generic code just at non-generic code. To avoid generating duplicated machine code, one can declare a non-generic inner function inside the generic function.
</p>

<p>
When calling <code>dynamic_dispatch</code>, the caller passes a trait object, which is the combination of a type that implements the trait and a pointer to its virtual method table (vtable) which holds all trait method implementations of this type. Since <code>dyn</code> is not resolved during the compile time, it is <code>!Sized</code> and hence it needs to be a wide pointer (<code>&amp;dyn</code>) holder, e.g., <code>&amp;mut</code>, <code>Box</code> or <code>Arc</code>.
</p>

<p>
Only object-safe traits can allow dynamic dispatch. An object-safe trait must satisfy:
</p>
<ol class="org-ol">
<li>All methods are object-safe:
<ol class="org-ol">
<li>No generic parameters,</li>
<li>No <code>Self</code> as return type, otherwise the memory layout cannot be determined during the compile time.</li>
<li>No static methods, i.e., must take <code>&amp;self</code> or <code>&amp;mut self</code>, otherwise the vtable is not available.</li>
</ol></li>
<li>Trait cannot be <code>Sized</code> bound, otherwise it&rsquo;s against the nature of dynamic dispatch.</li>
</ol>

<p>
Broadly speaking, use static dispatch in a library, and dynamic dispatch in a binary (no other users):
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">pub</span> <span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">DynamicLogger</span> <span style="color: #51afef;">{</span>
    <span style="color: #dcaeea;">writer</span>: <span style="color: #ECBE7B;">Box</span><span style="color: #c678dd;">&lt;</span><span style="color: #51afef;">dyn</span> <span style="color: #ECBE7B;">Write</span><span style="color: #c678dd;">&gt;</span>
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">pub</span> <span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">StaticLogger</span><span style="color: #51afef;">&lt;</span><span style="color: #dcaeea;">W</span>: <span style="color: #ECBE7B;">Write</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #dcaeea;">writer</span>: <span style="color: #ECBE7B;">W</span>
<span style="color: #51afef;">}</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">usage</span>
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">file</span> = <span style="color: #ECBE7B;">File</span>::create<span style="color: #51afef;">(</span><span style="color: #98be65;">"dynamic_log.txt"</span><span style="color: #51afef;">)</span><span style="color: #c678dd; font-weight: bold;">?</span>;
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">dynamic_logger</span> = <span style="color: #ECBE7B;">DynamicLogger</span> <span style="color: #51afef;">{</span> <span style="color: #dcaeea;">writer</span>: <span style="color: #ECBE7B;">Box</span>::new<span style="color: #c678dd;">(</span>file<span style="color: #c678dd;">)</span> <span style="color: #51afef;">}</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">Users are forced to use dynamic dispatch</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">Both works for static dispatch</span>
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">file</span> = <span style="color: #ECBE7B;">File</span>::create<span style="color: #51afef;">(</span><span style="color: #98be65;">"static_log.txt"</span><span style="color: #51afef;">)</span><span style="color: #c678dd; font-weight: bold;">?</span>;
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">logger</span> = <span style="color: #ECBE7B;">Logger</span> <span style="color: #51afef;">{</span> <span style="color: #dcaeea;">writer</span>: file <span style="color: #51afef;">}</span>;

<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">file</span>: <span style="color: #ECBE7B;">Box</span><span style="color: #51afef;">&lt;</span><span style="color: #51afef;">dyn</span> <span style="color: #ECBE7B;">Write</span><span style="color: #51afef;">&gt;</span> = <span style="color: #ECBE7B;">Box</span>::new<span style="color: #51afef;">(</span><span style="color: #ECBE7B;">File</span>::create<span style="color: #c678dd;">(</span><span style="color: #98be65;">"static_log.txt"</span><span style="color: #c678dd;">)</span><span style="color: #c678dd; font-weight: bold;">?</span><span style="color: #51afef;">)</span>;
<span style="color: #51afef;">let</span> <span style="color: #dcaeea;">logger</span> = <span style="color: #ECBE7B;">Logger</span> <span style="color: #51afef;">{</span> <span style="color: #dcaeea;">writer</span>: file <span style="color: #51afef;">}</span>;
</pre>
</div>
</div>
</div>
<div id="outline-container-orgca620aa" class="outline-3">
<h3 id="orgca620aa"><span class="section-number-3">3.3.</span> Trait bounds</h3>
<div class="outline-text-3" id="text-3-3">
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">fn</span> <span style="color: #c678dd;">collect_to_map</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span>, <span style="color: #ECBE7B;">S</span><span style="color: #51afef;">&gt;(</span><span style="color: #dcaeea;">items</span>: <span style="color: #51afef;">impl</span> <span style="color: #ECBE7B;">IntoIterator</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">Item</span> = <span style="color: #ECBE7B;">T</span><span style="color: #c678dd;">&gt;</span><span style="color: #51afef;">)</span> -&gt; <span style="color: #ECBE7B;">HashMap</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span>, <span style="color: #ECBE7B;">usize</span>, <span style="color: #ECBE7B;">S</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef;">where</span>
   <span style="color: #ECBE7B;">HashMap</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span>, <span style="color: #ECBE7B;">usize</span>, <span style="color: #ECBE7B;">S</span><span style="color: #51afef;">&gt;</span>: <span style="color: #ECBE7B;">FromIterator</span><span style="color: #51afef;">&lt;</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">T</span>, <span style="color: #ECBE7B;">usize</span><span style="color: #c678dd;">)</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef;">{</span>
   items
       .into_iter<span style="color: #c678dd;">()</span>
       .enumerate<span style="color: #c678dd;">()</span>
       .map<span style="color: #c678dd;">(</span>|<span style="color: #98be65;">(</span>i, item<span style="color: #98be65;">)</span>| <span style="color: #98be65;">(</span>item, i<span style="color: #98be65;">)</span><span style="color: #c678dd;">)</span>
       .collect<span style="color: #c678dd;">()</span>
<span style="color: #51afef;">}</span>
</pre>
</div>

<p>
The trait above is better than explicitly writing <code>T: Hash + Eq</code> and <code>S: BuildHasher + Default</code> since they are implicitly required for <code>HashMap</code> to implement <code>FromIterator</code>.
</p>

<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">impl</span> <span style="color: #ECBE7B;">Debug</span> <span style="color: #51afef;">for</span> <span style="color: #ECBE7B;">AnyIterable</span>
<span style="color: #51afef;">where</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the reference to Self implements IntoIterator for any lifetime 'a</span>
    <span style="color: #51afef;">for</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span><span style="color: #51afef;">&gt;</span> <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #dcaeea;">Self</span>: <span style="color: #ECBE7B;">IntoIterator</span>,
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the item (associated type in Self) produced by iterating over the reference to Self implement Debug</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">We cannnot write &lt;&amp;'a Self&gt;::Item because the associated type Item only exists in IntoIterator</span>
    <span style="color: #51afef;">for</span><span style="color: #51afef;">&lt;</span>'<span style="color: #dcaeea;">a</span><span style="color: #51afef;">&gt;</span> &lt;<span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>'<span style="color: #dcaeea;">a</span> <span style="color: #ECBE7B;">Self</span> <span style="color: #51afef;">as</span> <span style="color: #ECBE7B;">IntoIterator</span>&gt;::<span style="color: #dcaeea;">Item</span>: <span style="color: #ECBE7B;">Debug</span>,
<span style="color: #51afef;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">since fmt signature does not allow lifetime annotation,</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">we need to specify "the reference implements the trait for any lifetime"</span>
    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">fmt</span><span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">self</span>, <span style="color: #dcaeea;">f</span>: <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> <span style="color: #ECBE7B;">Formatter</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">Result</span><span style="color: #c678dd;">&lt;</span><span style="color: #98be65;">()</span>, <span style="color: #ECBE7B;">Error</span><span style="color: #c678dd;">&gt;</span> <span style="color: #c678dd;">{</span>
        f.debug_list<span style="color: #98be65;">()</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">formats items, e.g., [item1, item2]</span>
            .entries<span style="color: #98be65;">(</span><span style="color: #51afef;">self</span><span style="color: #98be65;">)</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">iterates over self and debug-formatted each item</span>
            .finish<span style="color: #98be65;">()</span>
    <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>
</pre>
</div>

<p>
The code above adds trait bounds for both outer type and the inner associated type. It implement <code>Debug</code> for any type that can be iterated over and whose elements are <code>Debug</code>.
</p>
</div>
</div>
<div id="outline-container-org48a674d" class="outline-3">
<h3 id="org48a674d"><span class="section-number-3">3.4.</span> Existential types</h3>
<div class="outline-text-3" id="text-3-4">
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef; font-weight: bold;">#!</span><span style="color: #51afef; font-weight: bold;">[</span><span style="color: #51afef; font-weight: bold;">feature</span><span style="color: #c678dd; font-weight: bold;">(</span><span style="color: #51afef; font-weight: bold;">impl_trait_in_assoc_type</span><span style="color: #c678dd; font-weight: bold;">)</span><span style="color: #51afef; font-weight: bold;">]</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">require nightly</span>

<span style="color: #51afef; font-weight: bold;">#</span><span style="color: #51afef; font-weight: bold;">[</span><span style="color: #51afef; font-weight: bold;">derive</span><span style="color: #c678dd; font-weight: bold;">(</span><span style="color: #51afef; font-weight: bold;">Default</span><span style="color: #c678dd; font-weight: bold;">)</span><span style="color: #51afef; font-weight: bold;">]</span>
<span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">MyVec</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #dcaeea;">vec</span>: <span style="color: #ECBE7B;">Vec</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #c678dd;">&gt;</span>,
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">impl</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #ECBE7B;">IntoIterator</span> <span style="color: #51afef;">for</span> <span style="color: #ECBE7B;">MyVec</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">{</span>
    <span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">Item</span> = <span style="color: #ECBE7B;">T</span>;
    <span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">IntoIter</span> = <span style="color: #51afef;">impl</span> <span style="color: #ECBE7B;">Iterator</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">Item</span> = <span style="color: #ECBE7B;">Self</span>::<span style="color: #ECBE7B;">Item</span><span style="color: #c678dd;">&gt;</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">existential type</span>

    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">into_iter</span><span style="color: #c678dd;">(</span><span style="color: #51afef;">self</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">Self</span>::<span style="color: #ECBE7B;">IntoIter</span> <span style="color: #c678dd;">{</span>
        <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">vec</span> = <span style="color: #51afef;">self</span>.vec;
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">position</span> = <span style="color: #da8548; font-weight: bold;">0</span>;
        <span style="color: #a9a1e1;">std</span>::<span style="color: #a9a1e1;">iter</span>::from_fn<span style="color: #98be65;">(</span><span style="color: #51afef;">move</span> || <span style="color: #a9a1e1;">{</span>
            <span style="color: #51afef;">if</span> position &lt; vec.len<span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
                <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">item</span> = vec.remove<span style="color: #c678dd;">(</span>position<span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">consume vec</span>
                <span style="color: #ECBE7B;">Some</span><span style="color: #c678dd;">(</span>item<span style="color: #c678dd;">)</span>
            <span style="color: #51afef;">}</span> <span style="color: #51afef;">else</span> <span style="color: #51afef;">{</span>
                <span style="color: #ECBE7B;">None</span>
            <span style="color: #51afef;">}</span>
        <span style="color: #a9a1e1;">}</span><span style="color: #98be65;">)</span>
    <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">fn</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
    <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">my_vec</span> = <span style="color: #ECBE7B;">MyVec</span>::<span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">i32</span><span style="color: #c678dd;">&gt;</span>::default<span style="color: #c678dd;">()</span>.into_iter<span style="color: #c678dd;">()</span>;
    <span style="color: #c678dd;">println!</span><span style="color: #c678dd;">(</span><span style="color: #98be65;">"</span><span style="color: #98be65; font-style: italic;">{:?}</span><span style="color: #98be65;">"</span>, my_vec.next<span style="color: #98be65;">()</span><span style="color: #c678dd;">)</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>

<p>
The code above uses existential types in the associated types to avoid creating new type <code>MyVecIter</code>, hence perform zero-cost type erasure.
</p>
</div>
</div>
</div>
<div id="outline-container-org83f62fb" class="outline-2">
<h2 id="org83f62fb"><span class="section-number-2">4.</span> Linked-list</h2>
<div class="outline-text-2" id="text-4">
</div>
<div id="outline-container-orge5d18c5" class="outline-3">
<h3 id="orge5d18c5"><span class="section-number-3">4.1.</span> <a href="https://leetcode.com/problems/lru-cache/description/">Leetcode 146: LRU cache</a></h3>
<div class="outline-text-3" id="text-4-1">
<p>
Below is my personal solution for the problem, while it was accepted, there is space to improve it and I may come back when I have another idea.
</p>
<div class="org-src-container">
<pre class="src src-rust"><span style="color: #51afef;">use</span> <span style="color: #a9a1e1;">std</span>::<span style="color: #51afef;">{</span><span style="color: #a9a1e1;">cell</span>::<span style="color: #ECBE7B;">RefCell</span>, <span style="color: #a9a1e1;">collections</span>::<span style="color: #ECBE7B;">HashMap</span>, <span style="color: #a9a1e1;">rc</span>::<span style="color: #ECBE7B;">Rc</span><span style="color: #51afef;">}</span>;

<span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">List</span> = <span style="color: #ECBE7B;">Option</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">Rc</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">RefCell</span><span style="color: #98be65;">&lt;</span><span style="color: #ECBE7B;">ListNode</span><span style="color: #98be65;">&gt;</span><span style="color: #c678dd;">&gt;</span><span style="color: #51afef;">&gt;</span>;

<span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">ListNode</span> <span style="color: #51afef;">{</span>
    <span style="color: #dcaeea;">key</span>: <span style="color: #ECBE7B;">i32</span>,
    <span style="color: #dcaeea;">value</span>: <span style="color: #ECBE7B;">i32</span>,
    <span style="color: #dcaeea;">prev</span>: <span style="color: #ECBE7B;">List</span>,
    <span style="color: #dcaeea;">next</span>: <span style="color: #ECBE7B;">List</span>,
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">LRUCache</span> <span style="color: #51afef;">{</span>
    <span style="color: #dcaeea;">head</span>: <span style="color: #ECBE7B;">List</span>,
    <span style="color: #dcaeea;">tail</span>: <span style="color: #ECBE7B;">List</span>,
    <span style="color: #dcaeea;">data</span>: <span style="color: #ECBE7B;">HashMap</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">i32</span>, <span style="color: #ECBE7B;">Rc</span><span style="color: #98be65;">&lt;</span><span style="color: #ECBE7B;">RefCell</span><span style="color: #a9a1e1;">&lt;</span><span style="color: #ECBE7B;">ListNode</span><span style="color: #a9a1e1;">&gt;</span><span style="color: #98be65;">&gt;</span><span style="color: #c678dd;">&gt;</span>,
    <span style="color: #dcaeea;">capacity</span>: <span style="color: #ECBE7B;">usize</span>,
<span style="color: #51afef;">}</span>

<span style="color: #51afef;">impl</span> <span style="color: #ECBE7B;">LRUCache</span> <span style="color: #51afef;">{</span>
    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">new</span><span style="color: #c678dd;">(</span><span style="color: #dcaeea;">capacity</span>: <span style="color: #ECBE7B;">i32</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">Self</span> <span style="color: #c678dd;">{</span>
        <span style="color: #ECBE7B;">Self</span> <span style="color: #98be65;">{</span>
            <span style="color: #dcaeea;">head</span>: <span style="color: #ECBE7B;">None</span>,
            <span style="color: #dcaeea;">tail</span>: <span style="color: #ECBE7B;">None</span>,
            <span style="color: #dcaeea;">data</span>: <span style="color: #ECBE7B;">HashMap</span>::new<span style="color: #a9a1e1;">()</span>,
            <span style="color: #dcaeea;">capacity</span>: capacity <span style="color: #51afef;">as</span> <span style="color: #ECBE7B;">usize</span>,
        <span style="color: #98be65;">}</span>
    <span style="color: #c678dd;">}</span>

    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">move_to_front</span><span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> <span style="color: #51afef;">self</span>, <span style="color: #dcaeea;">node</span>: <span style="color: #ECBE7B;">Rc</span><span style="color: #98be65;">&lt;</span><span style="color: #ECBE7B;">RefCell</span><span style="color: #a9a1e1;">&lt;</span><span style="color: #ECBE7B;">ListNode</span><span style="color: #a9a1e1;">&gt;</span><span style="color: #98be65;">&gt;</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">early return if the node is already the head</span>
        <span style="color: #51afef;">if</span> <span style="color: #51afef;">let</span> <span style="color: #ECBE7B;">Some</span><span style="color: #98be65;">(</span>head<span style="color: #98be65;">)</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">self</span>.head <span style="color: #98be65;">{</span>
            <span style="color: #51afef;">if</span> <span style="color: #ECBE7B;">Rc</span>::ptr_eq<span style="color: #a9a1e1;">(</span>head, <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>node<span style="color: #a9a1e1;">)</span> <span style="color: #a9a1e1;">{</span>
                <span style="color: #51afef;">return</span>;
            <span style="color: #a9a1e1;">}</span>
        <span style="color: #98be65;">}</span>

        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">prev</span> = node.borrow<span style="color: #98be65;">()</span>.prev.clone<span style="color: #98be65;">()</span>;
        <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">next</span> = node.borrow<span style="color: #98be65;">()</span>.next.clone<span style="color: #98be65;">()</span>;

        <span style="color: #51afef;">match</span> <span style="color: #98be65;">(</span>prev.as_ref<span style="color: #a9a1e1;">()</span>, next.as_ref<span style="color: #a9a1e1;">()</span><span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
            <span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">None</span>, <span style="color: #ECBE7B;">None</span><span style="color: #a9a1e1;">)</span> =&gt; <span style="color: #a9a1e1;">{</span>
                <span style="color: #5B6268;">// </span><span style="color: #5B6268;">insert a new node only modifies the head,</span>
                <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the rest of the list is untouched.</span>
            <span style="color: #a9a1e1;">}</span>
            <span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">Some</span><span style="color: #51afef;">(</span>prev<span style="color: #51afef;">)</span>, <span style="color: #ECBE7B;">None</span><span style="color: #a9a1e1;">)</span> =&gt; <span style="color: #a9a1e1;">{</span>
                <span style="color: #5B6268;">// </span><span style="color: #5B6268;">get the tail node</span>
                prev.borrow_mut<span style="color: #51afef;">()</span>.next = <span style="color: #ECBE7B;">None</span>;
                <span style="color: #51afef;">self</span>.tail = <span style="color: #ECBE7B;">Some</span><span style="color: #51afef;">(</span><span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #c678dd;">(</span>prev<span style="color: #c678dd;">)</span><span style="color: #51afef;">)</span>;
            <span style="color: #a9a1e1;">}</span>
            <span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">None</span>, <span style="color: #ECBE7B;">Some</span><span style="color: #51afef;">(</span>_<span style="color: #51afef;">)</span><span style="color: #a9a1e1;">)</span> =&gt; <span style="color: #a9a1e1;">{</span>
                <span style="color: #5B6268;">// </span><span style="color: #5B6268;">get the head node is already handled</span>
                <span style="color: #51afef;">return</span>;
            <span style="color: #a9a1e1;">}</span>
            <span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">Some</span><span style="color: #51afef;">(</span>prev<span style="color: #51afef;">)</span>, <span style="color: #ECBE7B;">Some</span><span style="color: #51afef;">(</span>next<span style="color: #51afef;">)</span><span style="color: #a9a1e1;">)</span> =&gt; <span style="color: #a9a1e1;">{</span>
                <span style="color: #5B6268;">// </span><span style="color: #5B6268;">get a node in the middle of a list,</span>
                <span style="color: #5B6268;">// </span><span style="color: #5B6268;">connect its prev and next</span>
                prev.borrow_mut<span style="color: #51afef;">()</span>.next = <span style="color: #ECBE7B;">Some</span><span style="color: #51afef;">(</span><span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #c678dd;">(</span>next<span style="color: #c678dd;">)</span><span style="color: #51afef;">)</span>;
                next.borrow_mut<span style="color: #51afef;">()</span>.prev = <span style="color: #ECBE7B;">Some</span><span style="color: #51afef;">(</span><span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #c678dd;">(</span>prev<span style="color: #c678dd;">)</span><span style="color: #51afef;">)</span>;
            <span style="color: #a9a1e1;">}</span>
        <span style="color: #98be65;">}</span>

        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">update node to be the new head</span>
        <span style="color: #51afef;">if</span> <span style="color: #51afef;">let</span> <span style="color: #ECBE7B;">Some</span><span style="color: #98be65;">(</span>old_head<span style="color: #98be65;">)</span> = <span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">self</span>.head <span style="color: #98be65;">{</span>
            node.borrow_mut<span style="color: #a9a1e1;">()</span>.next = <span style="color: #ECBE7B;">Some</span><span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #51afef;">(</span>old_head<span style="color: #51afef;">)</span><span style="color: #a9a1e1;">)</span>;
            old_head.borrow_mut<span style="color: #a9a1e1;">()</span>.prev = <span style="color: #ECBE7B;">Some</span><span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #51afef;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>node<span style="color: #51afef;">)</span><span style="color: #a9a1e1;">)</span>;
        <span style="color: #98be65;">}</span> <span style="color: #51afef;">else</span> <span style="color: #98be65;">{</span>
            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">insert a node to the empty list</span>
            <span style="color: #51afef;">self</span>.tail = <span style="color: #ECBE7B;">Some</span><span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #51afef;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>node<span style="color: #51afef;">)</span><span style="color: #a9a1e1;">)</span>;
        <span style="color: #98be65;">}</span>
        node.borrow_mut<span style="color: #98be65;">()</span>.prev = <span style="color: #ECBE7B;">None</span>;
        <span style="color: #51afef;">self</span>.head = <span style="color: #ECBE7B;">Some</span><span style="color: #98be65;">(</span>node<span style="color: #98be65;">)</span>;
    <span style="color: #c678dd;">}</span>

    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">get</span><span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> <span style="color: #51afef;">self</span>, <span style="color: #dcaeea;">key</span>: <span style="color: #ECBE7B;">i32</span><span style="color: #c678dd;">)</span> -&gt; <span style="color: #ECBE7B;">i32</span> <span style="color: #c678dd;">{</span>
        <span style="color: #51afef;">let</span> <span style="color: #51afef;">mut</span> <span style="color: #dcaeea;">result</span> = -<span style="color: #da8548; font-weight: bold;">1</span>;
        <span style="color: #51afef;">if</span> <span style="color: #51afef;">let</span> <span style="color: #ECBE7B;">Some</span><span style="color: #98be65;">(</span>node<span style="color: #98be65;">)</span> = <span style="color: #51afef;">self</span>.data.get<span style="color: #98be65;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>key<span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
            result = node.borrow<span style="color: #a9a1e1;">()</span>.value;
            <span style="color: #51afef;">self</span>.move_to_front<span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #51afef;">(</span>node<span style="color: #51afef;">)</span><span style="color: #a9a1e1;">)</span>;
        <span style="color: #98be65;">}</span>
        result
    <span style="color: #c678dd;">}</span>

    <span style="color: #51afef;">fn</span> <span style="color: #c678dd;">put</span><span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span><span style="color: #51afef;">mut</span> <span style="color: #51afef;">self</span>, <span style="color: #dcaeea;">key</span>: <span style="color: #ECBE7B;">i32</span>, <span style="color: #dcaeea;">value</span>: <span style="color: #ECBE7B;">i32</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
        <span style="color: #51afef;">if</span> <span style="color: #51afef;">let</span> <span style="color: #ECBE7B;">Some</span><span style="color: #98be65;">(</span>node<span style="color: #98be65;">)</span> = <span style="color: #51afef;">self</span>.data.get<span style="color: #98be65;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>key<span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
            <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">node</span> = <span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #a9a1e1;">(</span>node<span style="color: #a9a1e1;">)</span>;
            node.borrow_mut<span style="color: #a9a1e1;">()</span>.value = value;
            <span style="color: #51afef;">self</span>.move_to_front<span style="color: #a9a1e1;">(</span>node<span style="color: #a9a1e1;">)</span>;
        <span style="color: #98be65;">}</span> <span style="color: #51afef;">else</span> <span style="color: #98be65;">{</span>
            <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">new_node</span> = <span style="color: #ECBE7B;">Rc</span>::new<span style="color: #a9a1e1;">(</span><span style="color: #ECBE7B;">RefCell</span>::new<span style="color: #51afef;">(</span><span style="color: #ECBE7B;">ListNode</span> <span style="color: #c678dd;">{</span>
                key,
                value,
                <span style="color: #dcaeea;">prev</span>: <span style="color: #ECBE7B;">None</span>,
                <span style="color: #dcaeea;">next</span>: <span style="color: #ECBE7B;">None</span>,
            <span style="color: #c678dd;">}</span><span style="color: #51afef;">)</span><span style="color: #a9a1e1;">)</span>;
            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">evict the tail node</span>
            <span style="color: #51afef;">if</span> <span style="color: #51afef;">self</span>.data.len<span style="color: #a9a1e1;">()</span> &gt;= <span style="color: #51afef;">self</span>.capacity <span style="color: #a9a1e1;">{</span>
                <span style="color: #51afef;">if</span> <span style="color: #51afef;">let</span> <span style="color: #ECBE7B;">Some</span><span style="color: #51afef;">(</span>tail<span style="color: #51afef;">)</span> = <span style="color: #51afef;">self</span>.tail.take<span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
                    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">cannot simply take the prev as it breaks the list?</span>
                    <span style="color: #51afef;">let</span> <span style="color: #dcaeea;">prev</span> = tail.borrow<span style="color: #c678dd;">()</span>.prev.clone<span style="color: #c678dd;">()</span>;
                    <span style="color: #51afef;">self</span>.data.remove<span style="color: #c678dd;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>tail.borrow<span style="color: #98be65;">()</span>.key<span style="color: #c678dd;">)</span>;
                    <span style="color: #51afef;">if</span> <span style="color: #51afef;">let</span> <span style="color: #ECBE7B;">Some</span><span style="color: #c678dd;">(</span>prev<span style="color: #c678dd;">)</span> = prev <span style="color: #c678dd;">{</span>
                        prev.borrow_mut<span style="color: #98be65;">()</span>.next = <span style="color: #ECBE7B;">None</span>;
                        <span style="color: #51afef;">self</span>.tail = <span style="color: #ECBE7B;">Some</span><span style="color: #98be65;">(</span>prev<span style="color: #98be65;">)</span>;
                    <span style="color: #c678dd;">}</span> <span style="color: #51afef;">else</span> <span style="color: #c678dd;">{</span>
                        <span style="color: #51afef;">self</span>.head = <span style="color: #ECBE7B;">None</span>;
                        <span style="color: #51afef;">self</span>.tail = <span style="color: #ECBE7B;">None</span>;
                    <span style="color: #c678dd;">}</span>
                <span style="color: #51afef;">}</span>
            <span style="color: #a9a1e1;">}</span>
            <span style="color: #51afef;">self</span>.data.insert<span style="color: #a9a1e1;">(</span>key, <span style="color: #ECBE7B;">Rc</span>::clone<span style="color: #51afef;">(</span><span style="color: #bbc2cf; background-color: #282c34;">&amp;</span>new_node<span style="color: #51afef;">)</span><span style="color: #a9a1e1;">)</span>;
            <span style="color: #51afef;">self</span>.move_to_front<span style="color: #a9a1e1;">(</span>new_node<span style="color: #a9a1e1;">)</span>;
        <span style="color: #98be65;">}</span>
    <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>

</pre>
</div>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-rust.html">rust</a> <a href="https://chenyo.me/tag-program.html">program</a> </div>]]></description>
  <category><![CDATA[rust]]></category>
  <category><![CDATA[program]]></category>
  <link>https://chenyo.me/2024-12-28-interesting-rust-snippets.html</link>
  <guid>https://chenyo.me/2024-12-28-interesting-rust-snippets.html</guid>
  <pubDate>Sat, 28 Dec 2024 10:21:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Book notes: A Philosophy of Software Design]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orga657ed5">1. Introduction</a></li>
<li><a href="#org1917476">2. Complexity</a>
<ul>
<li><a href="#org8e9d6aa">2.1. Definition</a></li>
<li><a href="#orge5b36b6">2.2. Symptoms</a></li>
<li><a href="#orgb9d2185">2.3. Causes</a></li>
</ul>
</li>
<li><a href="#org9ddf31f">3. Programming mindsets</a>
<ul>
<li><a href="#orge8e1b21">3.1. Strategic programming</a></li>
</ul>
</li>
<li><a href="#org2830b98">4. Modular design</a>
<ul>
<li><a href="#orgb6344b6">4.1. Interface</a></li>
<li><a href="#org2577a29">4.2. Abstraction</a></li>
</ul>
</li>
<li><a href="#org3ce63f4">5. Information hiding</a>
<ul>
<li><a href="#orgcf2d65b">5.1. Information leakage</a></li>
<li><a href="#org9d344e3">5.2. Temporal decomposition</a></li>
</ul>
</li>
<li><a href="#org707264a">6. General-Purpose modules</a>
<ul>
<li><a href="#orgac0f26f">6.1. Example: GUI text editor design</a></li>
</ul>
</li>
<li><a href="#org49e9c8b">7. Layers of abstractions</a>
<ul>
<li><a href="#orgf68c15a">7.1. Pass-through methods</a></li>
<li><a href="#org0b297c6">7.2. Pass-through variables</a></li>
<li><a href="#org1792615">7.3. Acceptable interface duplication</a></li>
</ul>
</li>
<li><a href="#org7020788">8. Combine or separate functionality</a></li>
<li><a href="#org5af7f08">9. Exception handling</a>
<ul>
<li><a href="#org1f06053">9.1. Define errors out of existence</a></li>
<li><a href="#org8b716f2">9.2. Exception masking</a></li>
<li><a href="#org1c1c0c9">9.3. Exception aggregation</a></li>
</ul>
</li>
<li><a href="#org074dfb1">10. Design it twice</a></li>
<li><a href="#org531e52e">11. Write comments</a>
<ul>
<li><a href="#org452c4d5">11.1. Why write comments</a></li>
<li><a href="#org5ea44c7">11.2. What are good comments</a>
<ul>
<li><a href="#org9f0b7f9">11.2.1. Lower-level comments</a></li>
<li><a href="#org8de8e4e">11.2.2. Higher-level comments</a></li>
<li><a href="#orgb2dc86a">11.2.3. Interface comments</a></li>
<li><a href="#orgf6d93df">11.2.4. Implementation comments</a></li>
<li><a href="#org62b2ad3">11.2.5. Cross-module comments</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#orgc96d377">12. Choose names</a>
<ul>
<li><a href="#org24c083f">12.1. Precision</a></li>
<li><a href="#org9a759fc">12.2. Consistency</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for the book &ldquo;A Philosophy of Software Design&rdquo; (2018, John Ousterhout).
John Ousterhout is the author of Tcl scripting language and the Raft protocol.
This book works together with <a href="https://web.stanford.edu/~ouster/cs190-winter24/info/">Stanford CS190</a>.
</p>
<div id="outline-container-orga657ed5" class="outline-2">
<h2 id="orga657ed5"><span class="section-number-2">1.</span> Introduction</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>The most fundamental problem in CS is <b><b>problem decomposition</b></b>: how to divide a complex problem into pieces that can be solved independently.</li>
<li>Complexity increases <b><b>inevitably</b></b> over the life of the program, but simpler designs allow to build larger systems before complexity becomes overwhelming.</li>
<li>Two general approaches:
<ul class="org-ul">
<li>Making code more obvious, e.g., eliminating special cases, using identifiers in a consistent fashion.</li>
<li>Encapsulate the complexity, i.e., divide a system into independent modules.</li>
</ul></li>
<li>Waterfall model: each phase of a project e.g., requirement, design, coding, testing, completes before the next phase starts, such that the entire system is designed once.
<ul class="org-ul">
<li>Does not work for software since the problem of the initial design do not become apparent until implementation is well underway; then the developers need to patch around the problems, resulting in an explosion of complexity.</li>
</ul></li>
<li>Agile/Incremental development: in each iteration the design focuses on a small subset of the overall functionality, so that problems can be fixed when the system is small and later features benefit from previous experience.
<ul class="org-ul">
<li>Developers should always think about design issues and complexity, and use complexity to guide the design.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org1917476" class="outline-2">
<h2 id="org1917476"><span class="section-number-2">2.</span> Complexity</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Complexity is <b><b>incremental</b></b>.</li>
<li>Developers must adopt a <b><b>zero tolerance</b></b> philosophy.</li>
</ul>
</div>
<div id="outline-container-org8e9d6aa" class="outline-3">
<h3 id="org8e9d6aa"><span class="section-number-3">2.1.</span> Definition</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>Complexity is anything related to the structure of a software system that makes it hard to understand and modify the system.</li>
<li>\(C = \sum_p(c_pt_p)\): The overall complexity  is determined by the complexity of each part \(p\) weighted by the fraction of time developers working on that part.
<ul class="org-ul">
<li>Isolating complexity in a place where it will never be seen is as good as eliminating the complexity.</li>
</ul></li>
<li>Complexity is more apparent to readers than writers: if you write a piece of code that seems simple to you, but others think it is complex, then it is complex.</li>
</ul>
</div>
</div>
<div id="outline-container-orge5b36b6" class="outline-3">
<h3 id="orge5b36b6"><span class="section-number-3">2.2.</span> Symptoms</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li>Change amplification: a seemingly simple change requires code modifications in many different places.</li>
<li>Cognitive load: developers have to spend more time learning the required information to complete a task, which leads to greater risk of bugs.
<ul class="org-ul">
<li>E.g., a function allocates memory and returns a pointer to the memory, but assumes the caller should free the memory.</li>
<li>Sometimes an approach that requires more lines of code is actually simpler as it reduces cognitive load.</li>
</ul></li>
<li>Unknown unknowns (the worst!): it is not obvious which pieces of code must be modified or which information must have to complete the task.</li>
<li>The goal of a good design is for a system to be <b><b>obvious</b></b>: a developer can make a quick guess about what to do and yet to be confident that the guess is correct.</li>
</ul>
</div>
</div>
<div id="outline-container-orgb9d2185" class="outline-3">
<h3 id="orgb9d2185"><span class="section-number-3">2.3.</span> Causes</h3>
<div class="outline-text-3" id="text-2-3">
<ul class="org-ul">
<li>Complexity is caused by two things: <b><b>dependencies</b></b> and <b><b>obscurity</b></b>.</li>
<li>A dependency exists when a code cannot be understood and modified in isolation.
<ul class="org-ul">
<li>E.g., in network protocols both senders and receivers must conform to the protocol, changing code for the sender almost always requires corresponding changes at the receiver.</li>
<li>Dependencies are fundamental and cannot be completely eliminated, the goal is to make the dependencies remain simple and obvious (e.g., variable renaming are detected by compilers).</li>
</ul></li>
<li>Obscurity occurs when important information is not obvious, e.g., a variable is too generic or the documentation is inadequate.
<ul class="org-ul">
<li>Obscurity is often associated with non-obvious dependencies.</li>
<li>Inconsistency is also a major contributor, e.g., the same variable name is used for two different purposes.</li>
<li>The need for extensive documentation is often a red flag that the design is complex.</li>
</ul></li>
<li>Dependencies lead to change amplification and cognitive load; obscurity creates unknown unknowns and cognitive load.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org9ddf31f" class="outline-2">
<h2 id="org9ddf31f"><span class="section-number-2">3.</span> Programming mindsets</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Tactical programming: the main focus is to get something working, e.g., a new feature or a bug fix.</li>
<li>Tactical programming is short-sighted, e.g., each task contributes a reasonable compromise to finish the current task quickly.</li>
<li>Once a code base turns to spaghetti, it is nearly impossible to fix.</li>
</ul>
</div>
<div id="outline-container-orge8e1b21" class="outline-3">
<h3 id="orge8e1b21"><span class="section-number-3">3.1.</span> Strategic programming</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>Requires an investment mindset to improve the system design rather than taking the fastest path to finish the current task.</li>
<li>Proactive investment: try a couple of alternative designs and pick the cleanest one; imagine a few ways in which the system might need to be changed in the future; write documentation.</li>
<li>Reactive investments: continuously make small improvements to the system design when a design problem becomes obvious rather than patching around it.</li>
<li>The ideal design tends to emerge in bits and pieces, thus the best approach is to make lots of <b><b>small</b></b> investments on a <b><b>continual</b></b> basis, e.g., 10-20% of total development time on investments.</li>
</ul>


<figure id="org931e0f3">
<img src="https://csruiliu.github.io/blog/images/strategic-tactical.jpeg" alt="strategic-tactical.jpeg" align="center" width="400px">

<figcaption><span class="figure-number">Figure 1: </span>Strategic vs Tactical programming (<a href="https://csruiliu.github.io/blog/images/strategic-tactical.jpeg">Source</a>)</figcaption>
</figure>
</div>
</div>
</div>
<div id="outline-container-org2830b98" class="outline-2">
<h2 id="org2830b98"><span class="section-number-2">4.</span> Modular design</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>The goal of modular design is to minimize the dependencies between modules.</li>
<li>Each module consists of two parts: interface and implementation. The interface describes what the module does, the implementation specifies how it does.
<ul class="org-ul">
<li>The interface consists of everything that a developer working on a different module must know in order to use the given module.</li>
<li>The implementation consists of the code that carries out the promises made by the interface.</li>
</ul></li>
<li>The best modules are <b><b>deep</b></b>, i.e., those whose interfaces are much simpler than their implementations.
<ul class="org-ul">
<li>In such cases the modification in the implementation is less likely to affect other modules.</li>
</ul></li>
<li>Small modules tend to be shallow, because the benefit they provide is negated by the cost of learning and using their interfaces.</li>
<li>Classitis refers to a mistaken view that developers should minimize the amount of functionality in each new class.
<ul class="org-ul">
<li>It may result in classes that are individually simple, but increases the overall complexity.</li>
</ul></li>
</ul>
</div>
<div id="outline-container-orgb6344b6" class="outline-3">
<h3 id="orgb6344b6"><span class="section-number-3">4.1.</span> Interface</h3>
<div class="outline-text-3" id="text-4-1">
<ul class="org-ul">
<li>A module interface contains two information: formal and informal.</li>
<li>The formal part for a method is its signature; The formal interface for a class consists of the signatures for all public methods and variables.</li>
<li>The informal part includes its high-level behavior and usage constraints; they can only be described using comments and cannot be ensured by the programming languages.
<ul class="org-ul">
<li>Informal aspects are larger and more complex than the formal aspects for most interfaces.</li>
</ul></li>
<li>While providing choice is good, interfaces should be designed to make the <b><b>common case</b></b> as simple as possible (c.f. \(C = \sum_p(c_pt_p)\)).</li>
</ul>
</div>
</div>
<div id="outline-container-org2577a29" class="outline-3">
<h3 id="org2577a29"><span class="section-number-3">4.2.</span> Abstraction</h3>
<div class="outline-text-3" id="text-4-2">
<ul class="org-ul">
<li>An abstraction is a simplified view of an entity, which omits unimportant details.
<ul class="org-ul">
<li>The more unimportant details that are omitted from an abstraction, the better, otherwise the abstraction increases the cognitive load.</li>
<li>A detail can only be omitted if it is unimportant, otherwise obscurity occurs.</li>
</ul></li>
<li>In modular programming, each module provides an abstraction in form of its interface.</li>
<li>The key to designing abstractions is to understand what is important.
<ul class="org-ul">
<li>E.g., how to choose storage blocks for a file is unimportant to users, but the rules for flushing data to secondary storage is important for databases, hence it must be visible in the file system interface.</li>
<li>Garbage collectors in Go and Java do not have interface at all.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org3ce63f4" class="outline-2">
<h2 id="org3ce63f4"><span class="section-number-2">5.</span> Information hiding</h2>
<div class="outline-text-2" id="text-5">
<ul class="org-ul">
<li>Information hiding is the most important technique for achieving deep modules.</li>
<li>Each module should encapsulate a few design information (e.g., data structures, low-level details) in the module implementation but not appear in its interface.</li>
<li>Information hiding simplifies the module interface and makes it easier to evolve the system as a design change related a hidden information only affects that module.</li>
<li>Making an item <code>private</code> is not the same as information hiding, as the information about the private items can still be exposed through public methods such as <code>getter</code> and <code>setter</code>.</li>
<li>If a particular information is only needed by a few of a class&rsquo;s users, it can be <b><b>partially</b></b> hidden if it is accessed through separate methods, so that it is still invisible in the most common use cases.
<ul class="org-ul">
<li>E.g., modules should provide adequate <b><b>defaults</b></b> and only callers that want to override the default need to be aware of the parameter.</li>
</ul></li>
</ul>
</div>
<div id="outline-container-orgcf2d65b" class="outline-3">
<h3 id="orgcf2d65b"><span class="section-number-3">5.1.</span> Information leakage</h3>
<div class="outline-text-3" id="text-5-1">
<ul class="org-ul">
<li>The leakage occurs when a design decision is reflected in multiple modules. thus creating dependencies between the modules.
<ul class="org-ul">
<li>Interface information is by definition has been leaked.</li>
</ul></li>
<li>Information can be leaked even if it does not appear in the interface, i.e., back-door leakage.
<ul class="org-ul">
<li>E.g., two classes read and write the same file format, then if the format changes, both classes need to be modified; such leakage is more pernicious than interface leakage as it is not obvious.</li>
</ul></li>
<li>If affected classes are relatively small and closely tied to the leaked information, they may need to be <b><b>merged</b></b> into a single class.
<ul class="org-ul">
<li>The bigger class is deeper as the entire computation is easier to be abstracted in the interface compared to separate sub-computations.</li>
</ul></li>
<li>One may also pull the leaked information out of all affected classes and create a new class to encapsulate the information, i.e., replace back-door leakage with interface leakage.</li>
<li>One should avoid exposing internal data structures (e.g., return by reference) as such approach makes more work for callers, and make the module shallow.
<ul class="org-ul">
<li>E.g., instead of writing <code>getParams()</code> which returns a map of all parameters, one should have <code>getParameter(String name)</code> and <code>getIntParameter(String name)</code> to return a specific parameter and throw an exception if the name does not exist or cannot be converted.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org9d344e3" class="outline-3">
<h3 id="org9d344e3"><span class="section-number-3">5.2.</span> Temporal decomposition</h3>
<div class="outline-text-3" id="text-5-2">
<ul class="org-ul">
<li>Temporal decomposition is a common cause of information leakage.</li>
<li>It decompose the system into operations corresponding to the execution order.
<ul class="org-ul">
<li>E.g., A file-reading application is broken into 3 classes: read, modify and write, then both reading and writing steps have knowledge about the file format.</li>
<li>The solution is to combine the core mechanisms for reading and writing into a single class.</li>
</ul></li>
<li>Orders should not be reflected in the module structure unless different stages use totally different information.</li>
<li>One should focus on the <b><b>knowledge</b></b> needed to perform each task, not the order in which tasks occur.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org707264a" class="outline-2">
<h2 id="org707264a"><span class="section-number-2">6.</span> General-Purpose modules</h2>
<div class="outline-text-2" id="text-6">
<ul class="org-ul">
<li>General-purpose modules can be used to address a broad range of problems such that it may find unanticipated uses in the future (cf. investment mindset).</li>
<li>Special-purpose modules are specialized for today&rsquo;s needs, and can be refactored to make it general-purpose when additional uses are required (cf. incremental software development).</li>
<li>The author recommends a &ldquo;somewhat general-purpose&rdquo; fashion: the functionality should reflect the current needs, but the interface should be general enough to support multiple uses.</li>
<li>The following questions can be asked to find the balance between general-purpose and special-purpose approach:
<ul class="org-ul">
<li>What is the simplest interface that will cover all current needs?</li>
<li>How many situations will a method be used?</li>
<li>Is the API easy to use for the current needs (not go too far)?</li>
</ul></li>
</ul>
</div>
<div id="outline-container-orgac0f26f" class="outline-3">
<h3 id="orgac0f26f"><span class="section-number-3">6.1.</span> Example: GUI text editor design</h3>
<div class="outline-text-3" id="text-6-1">
<ul class="org-ul">
<li>Specialized design: use individual method in the text class to support each high-level features, e.g., <code>backspace(Cursor cursor)</code> deletes the character before the cursor; <code>delete(Cursor cursor)</code> deletes the character after the cursor; <code>deleteSelection(Selection selection)</code> deletes the selected section.</li>
<li>The specialized design creates a high cognitive load for the UI developers: the implementation ends up with a large number of shallow methods so a UI developer had to learn all of them.
<ul class="org-ul">
<li>E.g., <code>backspace</code> provides a false abstraction as it does not hide the information about which character to delete.</li>
</ul></li>
<li>The specialized design also creates information leakage: abstractions related to the UI such as backspace key and selection, are reflected in the text class, increasing the cognitive load for the text class developers.</li>
<li>General-purpose design define API only in terms of <b><b>basic</b></b> text features without reflecting the higher-level operations.
<ul class="org-ul">
<li>Only three methods are needed to modify a text: <code>insert(Position position, String newText)</code>,  <code>delete(Position start, Position end)</code> and <code>changePosition(Position position, int numChars)</code>.
<ul class="org-ul">
<li>The new API uses a more generic <code>Position</code> to replace a specific user interface <code>Cursor</code>.</li>
<li>The delete key can be implemented as <code>text.delete(cursor, text.ChangePosition(cursor, 1))</code>, the backspace key can be implemented as <code>text.delete(cursor, text.ChangePosition(cursor, -1))</code>.</li>
</ul></li>
</ul></li>
<li>The new design is more obvious, e.g., the UI developer knows which character to delete from the interface, and also has less code overall.</li>
<li>The general-purpose methods can also be used for new feature, e.g., search and replace text.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org49e9c8b" class="outline-2">
<h2 id="org49e9c8b"><span class="section-number-2">7.</span> Layers of abstractions</h2>
<div class="outline-text-2" id="text-7">
<ul class="org-ul">
<li>Software systems are composed into layers, where higher layers use the facilities provided by lower layers; each layer provides an abstraction different from the layers above or below it.
<ul class="org-ul">
<li>E.g., a file in the uppermost layer is an array of bytes and is a memory cache of fixed-size disk blocks in the next lower layer.</li>
</ul></li>
<li>A system contains adjacent layers with similar abstractions is a red flag of class decomposition problem.</li>
<li>The internal representations should be different from the abstractions that appear in the interface; if the interface and the implementation have similar abstractions, the class is shallow.</li>
<li>It is more important for a module to have a simple interface than a simple implementation to benefit more user.
<ul class="org-ul">
<li>Simple implementation example: throw an exception when don&rsquo;t know how to handle the condition; define configuration parameters (developers should compute reasonable defaults automatically for configuration parameters).</li>
<li>Simple interface example: make a text editor GUI character-oriented rather on line-oriented so users can insert and delete arbitrary ranges of text.</li>
</ul></li>
</ul>
</div>
<div id="outline-container-orgf68c15a" class="outline-3">
<h3 id="orgf68c15a"><span class="section-number-3">7.1.</span> Pass-through methods</h3>
<div class="outline-text-3" id="text-7-1">
<ul class="org-ul">
<li>A pass-through method is a method that does little except invoke another method, whose signature is similar or identical to the callee function.</li>
<li>Pass-through methods usually indicates there is not a clean <b><b>division of responsibility</b></b> between classes.</li>
<li>Pass-through methods also create dependencies between classes.</li>
<li>The solution is to refactor the classes, e.g., expose the lower level class directly to the higher level (b), redistribute the functionality (c) or merge them (d):</li>
</ul>


<figure id="orgbdaf39d">
<img src="./static/pass-through-methods.png" alt="pass-through-methods.png" align="center" width="400px">

<figcaption><span class="figure-number">Figure 2: </span>Refactor pass-through methods</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org0b297c6" class="outline-3">
<h3 id="org0b297c6"><span class="section-number-3">7.2.</span> Pass-through variables</h3>
<div class="outline-text-3" id="text-7-2">
<ul class="org-ul">
<li>A pass-through variable is a variable that is passed down through a long chain of methods.</li>
<li>Pass-through variables add complexity as all intermediate methods must be aware of the existence and need to be modified when a new variable is used.</li>
<li>The author&rsquo;s solution is to introduce a <b><b>context</b></b> object which stores all application&rsquo;s global states, e.g., configuration options and timeout value, and there is one context object per system instance.</li>
<li>To avoid passing through the context variable, a reference to the context can be saved in other objects.
<ul class="org-ul">
<li>When a new object is created, the context reference is passed to the constructor.</li>
</ul></li>
<li>Contexts should be immutable to avoid thread-safety issues and may create non-obvious dependencies.</li>
</ul>
</div>
</div>
<div id="outline-container-org1792615" class="outline-3">
<h3 id="org1792615"><span class="section-number-3">7.3.</span> Acceptable interface duplication</h3>
<div class="outline-text-3" id="text-7-3">
<ul class="org-ul">
<li>Dispatcher: a method that uses its arguments to select a specific method to invoke and passes most of its arguments.
<ul class="org-ul">
<li>E.g., when a web server receives an HTTP request, it invokes a dispatcher to examine the URL and selects a specific method to handle the request.</li>
</ul></li>
<li>Polymorphous methods, e.g., <code>len(string)</code> and <code>len(array)</code> reduces cognitive load; they are usally in the same layer and do not invoke each other.</li>
<li>Decorator: a wrapper that takes an existing object and extends its functionality.</li>
<li>Decorators are often shallow and contain pass-through methods, one should consider following alternatives before using them:
<ul class="org-ul">
<li>Add the new functionality directly to the class if it is relatively general-purpose; or merge it with the specific use case if it is specialized.</li>
<li>Merge the new functionality with an existing decorator to make the existing decorator deeper.</li>
<li>Implement it as a stand-alone class independent of the base class, e.g., <code>Window</code> and <code>ScrollableWindow</code>.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org7020788" class="outline-2">
<h2 id="org7020788"><span class="section-number-2">8.</span> Combine or separate functionality</h2>
<div class="outline-text-2" id="text-8">
<ul class="org-ul">
<li>The goal is to reduce the system complexity as a <b><b>whole</b></b> and improve its modularity.
<ul class="org-ul">
<li>Subdividing components create additional complexity, e.g. additional code.</li>
<li>Developers should separate one general-purpose code from special-purpose code, each special-purpose code should go in a different module, e.g., pull the special-purpose code into higher layers.
<ul class="org-ul">
<li>A general-purpose mechanism provides <b><b>interfaces</b></b> for special-purpose code to override.</li>
<li>Each special-purpose code implements particular logic which is unaware by other code, including the general-purpose mechanism.</li>
</ul></li>
<li>Combining codes is most beneficial if they are closely related:
<ul class="org-ul">
<li>They share information, e.g., HTTP request reader and parser.</li>
<li>They share repeated pattern, e.g., may <code>goto</code> same cleanup code.</li>
<li>The combination simplifies the interface, e.g., each code implement a part of the solution.</li>
<li>They are used together bi-directionally, e.g., a specific error message which is only invoked by one method.</li>
<li>They overlap conceptually in that there is single higher-level category including both code.</li>
</ul></li>
<li>Each method should do one thing and do it <b><b>completely</b></b>.
<ul class="org-ul">
<li>The length itself is rarely a good reason for splitting up methods.</li>
<li>If a method is subdivided, users should be able to understand the child method independently, which typically means the child method is relatively general-purpose, otherwise conjoined methods are created.</li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org5af7f08" class="outline-2">
<h2 id="org5af7f08"><span class="section-number-2">9.</span> Exception handling</h2>
<div class="outline-text-2" id="text-9">
<ul class="org-ul">
<li>Exceptions refer to any uncommon condition that alters the normal control flow.
<ul class="org-ul">
<li>E.g., bad arguments, an I/O operation fails, server timeout, packet loss, unprepared condition.</li>
</ul></li>
<li>It&rsquo;s difficult to ensure that exception handling code really works, especially in distributed data-intensive systems.</li>
<li>Classes with lots of exceptions have complex interfaces and are shallow.</li>
<li>The best way is to reduce the number of places where exceptions have to be handled.</li>
<li>The author proposes 4 techniques: define errors out of existence; exception handling; exception aggregation; crash.
<ul class="org-ul">
<li>For errors that are not worth trying to handle, or occur infrequently, abortion is the simplest thing to do; e.g., there is nothing the application can do when an out-of-memory exception occurs.</li>
</ul></li>
<li>Same as exceptions, special cases can result in code riddled with <code>if</code> statements, they should be eliminated by designing the normal case in a way that automatically handles the special cases.</li>
</ul>
</div>
<div id="outline-container-org1f06053" class="outline-3">
<h3 id="org1f06053"><span class="section-number-3">9.1.</span> Define errors out of existence</h3>
<div class="outline-text-3" id="text-9-1">
<ul class="org-ul">
<li>Example 1: instead of throwing an exception when a key does not exist in <code>remove</code>, simply return to ensure the key no longer exists.</li>
<li>Example 2: instead of throwing an exception when trying to delete a file that is still open in other processes, mark the file for deletion to deny any processes open the old file later, and delete the file after all processed have closed the file.</li>
<li>Example 3: instead of throwing an <code>IndexOutOfBoundsExeception</code> when <code>substring(s, begin, end)</code> takes out-of-range arguments, return the overlap substring.</li>
</ul>
</div>
</div>
<div id="outline-container-org8b716f2" class="outline-3">
<h3 id="org8b716f2"><span class="section-number-3">9.2.</span> Exception masking</h3>
<div class="outline-text-3" id="text-9-2">
<ul class="org-ul">
<li>An exceptional condition is detected and handled at a low level in the system so that higher levels need not be aware of the condition.</li>
<li>E.g., when a TCP packet is lost, the packet is resent within the implementation and clients are unaware of the dropped packets (they notice the hanging and can abort manually).</li>
<li>Exception masking results in deeper classes and pulls complexity downward.</li>
</ul>
</div>
</div>
<div id="outline-container-org1c1c0c9" class="outline-3">
<h3 id="org1c1c0c9"><span class="section-number-3">9.3.</span> Exception aggregation</h3>
<div class="outline-text-3" id="text-9-3">
<ul class="org-ul">
<li>Exception aggregation handles many special-purpose exceptions with a single general-purpose handler.</li>
<li>Example 1: instead of catching the exception for each individual missing parameter, let the single top-level exception handler aggregate the error message with a single <b><b>top-level</b></b> try-catch block.
<ul class="org-ul">
<li>The top-level handler encapsulates knowledge about how to generate error responses, but knows nothing about specific errors.</li>
<li>Each service knows how to generate errors, but does not know how to send the response.</li>
</ul></li>
<li>Example 2: promote rare exceptions (e.g., corrupted files) to more common exceptions (e.g., server crashes) so that the same handler can be used.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org074dfb1" class="outline-2">
<h2 id="org074dfb1"><span class="section-number-2">10.</span> Design it twice</h2>
<div class="outline-text-2" id="text-10">
<ul class="org-ul">
<li>Rather than picking the first idea that comes to mind, try to pick several approaches that are radically <b><b>different</b></b> from each other.
<ul class="org-ul">
<li>No need to pin down every feature of each alternative.</li>
</ul></li>
<li>Even if you are certain that there is only one reasonable approach, consider a second design anyway, no matter how bad it will be.
<ul class="org-ul">
<li>It will be instructive to think about the weaknesses of the second design and contrast with other designs.</li>
<li>It&rsquo;s easier to identify the best approach if one can compare a few alternatives.</li>
</ul></li>
<li>Make a list of the pros and cons of each rough design, e.g.,
<ul class="org-ul">
<li>Does one design have a simpler/ more general-purpose interface than another?</li>
<li>Does one interface enable a more efficient implementation?</li>
</ul></li>
<li>The design-it-twice principle can be applied at many levels in a system, e.g., decompose into modules, pick an interface, design an implementation (simplicity and performance).</li>
<li>No-one is good enough to get it right with their first try in large software system design.</li>
<li>The process of devising and comparing multiple approaches teach one about the factors that make designs better or worse.</li>
</ul>
</div>
</div>
<div id="outline-container-org531e52e" class="outline-2">
<h2 id="org531e52e"><span class="section-number-2">11.</span> Write comments</h2>
<div class="outline-text-2" id="text-11">
</div>
<div id="outline-container-org452c4d5" class="outline-3">
<h3 id="org452c4d5"><span class="section-number-3">11.1.</span> Why write comments</h3>
<div class="outline-text-3" id="text-11-1">
<ul class="org-ul">
<li>The correct process of writing comments will improve the system design.</li>
<li>A significant amount of design information that was in the mind of the designer cannot be represented in code, e.g., the <b><b>high-level</b></b> description of a method, the motivation for a particular design.</li>
<li>Comments are fundamental to abstractions: if users must read the code to use it, then there is no abstraction.
<ul class="org-ul">
<li>If there is no comment, the only abstraction of a method is its declaration which misses too much essential information to provide a useful abstraction by itself; e.g., whether <code>end</code> is inclusive.</li>
</ul></li>
<li>Good comments reduce cognitive load and unknown unknowns.</li>
</ul>
</div>
</div>
<div id="outline-container-org5ea44c7" class="outline-3">
<h3 id="org5ea44c7"><span class="section-number-3">11.2.</span> What are good comments</h3>
<div class="outline-text-3" id="text-11-2">
<ul class="org-ul">
<li>Follow the comment conventions, e.g., Doxygen for C++, godoc for Go.</li>
<li>Comments categories:
<ul class="org-ul">
<li>Interface: a comment block that precedes the declaration; describes the interface, e.g., overall behavior or abstraction, arguments, return values, side effects or exceptions and any requirements the caller must satisfy.</li>
<li>Data structure member: a comment next to the declaration of a field in a data structure, e.g., a variable.</li>
<li>Implementation comment: a comment inside the code to describe how the code work internally.</li>
<li>Cross-module comment: a comment describing dependencies that cross module boundaries.</li>
</ul></li>
<li>The interface and the data structure member comments are the most important and should be always present.</li>
<li>Don&rsquo;t repeat the code: if someone who has never seen the code can also write the comment by just looking at the code next to the comment, then the comment has no value.</li>
<li>Don&rsquo;t use the same words in the comment that appear in the name of the entity being described, pick words that provide additional information.</li>
<li>Comments should augment the code by providing information at a different level of detail.
<ul class="org-ul">
<li>Lower-level: add precision by clarifying the exact meaning of the code.</li>
<li>Higher-level: offer intuition behind the code.</li>
</ul></li>
</ul>
</div>
<div id="outline-container-org9f0b7f9" class="outline-4">
<h4 id="org9f0b7f9"><span class="section-number-4">11.2.1.</span> Lower-level comments</h4>
<div class="outline-text-4" id="text-11-2-1">
<ul class="org-ul">
<li>Precision is most useful when commenting variable declarations.</li>
<li>Missing details include: variable units; boundary conditions (inclusive/exclusive); whether a null value is permitted and what does it imply; who is responsible for a resource release; variable invariants that always true.
<ul class="org-ul">
<li>Avoid vague comments, e.g., &ldquo;current&rdquo;, not explicitly state the keys and values in a map.</li>
</ul></li>
<li>Comments on a variable focuses on what the variable <b><b>represents</b></b>, not how it will be modified.
<ul class="org-ul">
<li>E.g., instead of documenting when a boolean variable is toggled to true/false, document what true/false mean.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org8de8e4e" class="outline-4">
<h4 id="org8de8e4e"><span class="section-number-4">11.2.2.</span> Higher-level comments</h4>
<div class="outline-text-4" id="text-11-2-2">
<ul class="org-ul">
<li>Help the reader understand the overall intent and code structure, usually inside the code.</li>
<li>More difficult to write than lower-level comments as one must think about the code in a different way.
<ul class="org-ul">
<li>Comments can include why we need this code; what the code does on a high-level.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgb2dc86a" class="outline-4">
<h4 id="orgb2dc86a"><span class="section-number-4">11.2.3.</span> Interface comments</h4>
<div class="outline-text-4" id="text-11-2-3">
<ul class="org-ul">
<li>Separate interface comments from implementation comments: interface comments provide information for someone to use rather than maintain the entity.</li>
<li>A class interface comment documents the overall capability and limitation of a class and what each instance represents.</li>
<li>A method interface comment include both higher-level and lower-level information.
<ul class="org-ul">
<li>Starts with one or two sentences describing the method behavior and performance (e.g., whether concurrently).</li>
<li>Must be very precise about each argument and the return value, and must mention any constraint and dependencies on the arguments.</li>
<li>Must document any side effects that affect the system future behavior, e.g., modify a system data structure which can be read by other methods.</li>
<li>Must document any preconditions that must be satisfied before a method is invoked.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgf6d93df" class="outline-4">
<h4 id="orgf6d93df"><span class="section-number-4">11.2.4.</span> Implementation comments</h4>
<div class="outline-text-4" id="text-11-2-4">
<ul class="org-ul">
<li>The main goal is to help readers understand <b><b>what</b></b> the code is doing and <b><b>why</b></b> the code is needed (e.g., refer to a bug report), not how.</li>
<li>For long methods, add a comment before each of the major blocks to provide a abstract description of what the block does.</li>
<li>For complex loops, add a comment before the loop to describe what happens in each iteration at an intuitive level.</li>
<li>Document the local variables if they are used over a large span of code.</li>
</ul>
</div>
</div>
<div id="outline-container-org62b2ad3" class="outline-4">
<h4 id="org62b2ad3"><span class="section-number-4">11.2.5.</span> Cross-module comments</h4>
<div class="outline-text-4" id="text-11-2-5">
<ul class="org-ul">
<li>Real systems involve design decisions that affect multiple classes.</li>
<li>The biggest challenge of documenting cross-module decisions is to find a place.
<ul class="org-ul">
<li>E.g., when a new state is introduced, multiple updates are required to handle the state; an obvious place to document all required updates is inside the state enum where a new state will be added.</li>
</ul></li>
<li>When there is no obvious place, e.g., all updates depend on each other, the author recommends documenting them in a central design notes.
<ul class="org-ul">
<li>The file is divided up into clearly labeled section, one for each major topic.</li>
<li>Then in any code that relates to a topic, add a short comment &ldquo;see &rdquo;X&ldquo; in designNotes&rdquo;.</li>
<li>The disadvantage of this approach is to keep is up-to-date as the system envolves.</li>
</ul></li>
</ul>
</div>
</div>
</div>
</div>
<div id="outline-container-orgc96d377" class="outline-2">
<h2 id="orgc96d377"><span class="section-number-2">12.</span> Choose names</h2>
<div class="outline-text-2" id="text-12">
<ul class="org-ul">
<li>A good name conveys information about what the underlying entity is and is <b><b>not</b></b>.
<ul class="org-ul">
<li>Ask yourself: if someone sees this name in isolation without seeing its declaration or documentation, how closely can they guess?</li>
</ul></li>
<li>A good name has two properties: precision and consistency.</li>
<li>The greater the distance between a name&rsquo;s declaration and its last usage, the longer the name should be.</li>
</ul>
</div>
<div id="outline-container-org24c083f" class="outline-3">
<h3 id="org24c083f"><span class="section-number-3">12.1.</span> Precision</h3>
<div class="outline-text-3" id="text-12-1">
<ul class="org-ul">
<li>Vague name examples: &ldquo;count&rdquo;, &ldquo;status&rdquo;, &ldquo;x&rdquo;, &ldquo;result&rdquo; in a no return method.</li>
<li>It&rsquo;s fine to use generic &ldquo;i/j&rdquo; in a loop as long as the loop does not span large.</li>
<li>A name may also become too specific, e.g., <code>delete(Range Selection)</code> suggests the argument must be a selection, but it can also be passed with unselected range.</li>
<li>If you find it difficult to come up with a name that is precise, intuitive and not too long, then it is a red flag that the variable may not have a clear design.
<ul class="org-ul">
<li>Consider alternative factorings, e.g., separate the representation into multiple variables.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org9a759fc" class="outline-3">
<h3 id="org9a759fc"><span class="section-number-3">12.2.</span> Consistency</h3>
<div class="outline-text-3" id="text-12-2">
<ul class="org-ul">
<li>Always use the common name for and <b><b>only</b></b> for the given purpose, e.g., <code>ch</code> for a channel.</li>
<li>Make sure the purpose is narrow enough that all variables with the same name have the same behavior.
<ul class="org-ul">
<li>E.g., a <code>block</code> purpose is not narrow as it can have different behaviors for physical and logical blocks.</li>
</ul></li>
<li>When you need multiple variables that refer to the same general thing, use the common name for each variable and add a distinguishing <b><b>prefix</b></b>, e.g., <code>srcBlock</code> and <code>dstBlock</code>.</li>
<li>Always use <code>i</code> in outmost loops and <code>j</code> for nested loops.</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-book.html">book</a> <a href="https://chenyo.me/tag-software.html">software</a> <a href="https://chenyo.me/tag-design.html">design</a> </div>]]></description>
  <category><![CDATA[book]]></category>
  <category><![CDATA[software]]></category>
  <category><![CDATA[design]]></category>
  <link>https://chenyo.me/2024-10-23-book-notes:-a-philosophy-of-software-design-.html</link>
  <guid>https://chenyo.me/2024-10-23-book-notes:-a-philosophy-of-software-design-.html</guid>
  <pubDate>Wed, 23 Oct 2024 20:17:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Learning Dfinity P2P layer]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgb3fa791">1. Terminology</a>
<ul>
<li><a href="#orgd9ad074">1.1. IC design principle</a></li>
<li><a href="#org3aeea39">1.2. IC protocol stack</a>
<ul>
<li><a href="#org833bb8f">1.2.1. Execution layer</a></li>
<li><a href="#org9743eca">1.2.2. Message routing layer</a></li>
<li><a href="#org98cbd22">1.2.3. Consensus layer</a></li>
<li><a href="#orgb0017e0">1.2.4. P2P layer</a></li>
</ul>
</li>
<li><a href="#org1125642">1.3. State sync</a></li>
<li><a href="#org0686c84">1.4. QUIC protocol</a></li>
<li><a href="#org86435d1">1.5. Backpressure in blockchain</a></li>
</ul>
</li>
<li><a href="#org83ccea0">2. P2P layer</a>
<ul>
<li><a href="#org62678a1">2.1. Gossip protocol</a></li>
<li><a href="#orge37e9da">2.2. Artifacts</a></li>
<li><a href="#org1dc925b">2.3. Constraints</a></li>
<li><a href="#orgc1e2be6">2.4. Adverts</a>
<ul>
<li><a href="#orgd3871ab">2.4.1. Advert priority</a></li>
</ul>
</li>
<li><a href="#org75a5a00">2.5. Artifact pool</a></li>
<li><a href="#org96fdae6">2.6. Peer context</a></li>
<li><a href="#orgd5d43ee">2.7. Gossip protocol events</a>
<ul>
<li><a href="#orgb88b30b">2.7.1. Process a new advert received from peer \(i\)</a></li>
<li><a href="#orgbf423b6">2.7.2. Process a new received artifact from peer \(i\)</a></li>
</ul>
</li>
<li><a href="#org6c517fa">2.8. Common attacks</a>
<ul>
<li><a href="#orgfd1d522">2.8.1. Sybil attack</a></li>
<li><a href="#org870ea28">2.8.2. Eclipse attack</a></li>
<li><a href="#orgdba1aff">2.8.3. Routing table poisoning</a></li>
<li><a href="#org53f86f9">2.8.4. Bandwidth hogging</a></li>
</ul>
</li>
<li><a href="#org91251d1">2.9. Security</a></li>
</ul>
</li>
<li><a href="#orga591c0f">3. Transport component</a>
<ul>
<li><a href="#org5a5bb2f">3.1. Transient connection disturbances</a></li>
<li><a href="#org90425a4">3.2. Long disconnection with full TX queue</a></li>
</ul>
</li>
<li><a href="#orgca3424d">4. State sync protocol</a>
<ul>
<li><a href="#org3c8ed8a">4.1. Monolithic P2P layer not suitable for the state sync</a></li>
</ul>
</li>
<li><a href="#orga14cf38">5. Fully QUIC-based P2P layer</a>
<ul>
<li><a href="#org82401b7">5.1. Properties for consensus-related clients</a></li>
<li><a href="#orgaa2f888">5.2. Slot table</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for learning DFINITY Internet Computer (IC) P2P layer.
</p>

<p>
The learning resources include:
</p>

<ul class="org-ul">
<li><a href="https://internetcomputer.org/how-it-works/peer-to-peer-p2p/">IC wiki: How P2P works</a>;</li>
<li><a href="https://www.youtube.com/watch?v=HOQb0lKIy9I">Youtube: Inside the IC | P2P (July 2021)</a>;</li>
<li><a href="https://medium.com/dfinity/secure-scalability-the-internet-computers-peer-to-peer-layer-6662d451f2cc">Medium: IC P2P layer&rsquo;s secure scalability (Oct 2021)</a>;</li>
<li><a href="https://medium.com/dfinity/new-p2p-layer-of-the-internet-computer-introduces-quic-for-state-sync-984764fe9976">Medium: QUIC for state sync to simplify P2P (Sep 2023)</a>;</li>
<li><a href="https://www.youtube.com/watch?v=31J8PoLW9iM">Youtube: QUIC Tutorial (SIGCOMM 2020)</a>;</li>
<li><a href="https://medium.com/dfinity/a-new-p2p-layer-is-coming-to-the-internet-computer-772ac2a29484">Medium: Fully asynchronous IC P2P layer (Jan 2024)</a>.</li>
</ul>
<div id="outline-container-orgb3fa791" class="outline-2">
<h2 id="orgb3fa791"><span class="section-number-2">1.</span> Terminology</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-orgd9ad074" class="outline-3">
<h3 id="orgd9ad074"><span class="section-number-3">1.1.</span> IC design principle</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>Secure, reliable and scalable.</li>
<li>Scalability relies on the network message distribution efficiency; hence the IC network is divided into subnets.</li>
</ul>
</div>
</div>
<div id="outline-container-org3aeea39" class="outline-3">
<h3 id="org3aeea39"><span class="section-number-3">1.2.</span> IC protocol stack</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>From top to down: execution, message routing, consensus, P2P.</li>
</ul>
</div>
<div id="outline-container-org833bb8f" class="outline-4">
<h4 id="org833bb8f"><span class="section-number-4">1.2.1.</span> Execution layer</h4>
<div class="outline-text-4" id="text-1-2-1">
<ul class="org-ul">
<li>Manages a safe environment for deterministic execution of software messages.</li>
</ul>
</div>
</div>
<div id="outline-container-org9743eca" class="outline-4">
<h4 id="org9743eca"><span class="section-number-4">1.2.2.</span> Message routing layer</h4>
<div class="outline-text-4" id="text-1-2-2">
<ul class="org-ul">
<li>Routes user and system-generated messages between subnets.</li>
<li>Manages the input and output queues for applications.</li>
<li>Schedules messages for execution.</li>
</ul>
</div>
</div>
<div id="outline-container-org98cbd22" class="outline-4">
<h4 id="org98cbd22"><span class="section-number-4">1.2.3.</span> Consensus layer</h4>
<div class="outline-text-4" id="text-1-2-3">
<ul class="org-ul">
<li>Arranges messages received from users and different subnets into blocks before delivering them to the message routing layer.</li>
</ul>
</div>
</div>
<div id="outline-container-orgb0017e0" class="outline-4">
<h4 id="orgb0017e0"><span class="section-number-4">1.2.4.</span> P2P layer</h4>
<div class="outline-text-4" id="text-1-2-4">
<ul class="org-ul">
<li>Collects and advertises messages from users and other nodes in the same subnet, e.g., IC consensus protocol, the state sync protocol.</li>
<li>Main challenges: security, performance and scalability.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org1125642" class="outline-3">
<h3 id="org1125642"><span class="section-number-3">1.3.</span> State sync</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>Enables nodes to synchronize the replicated state of the subnet by downloading the required state and verify its authenticity relative to the subnet&rsquo;s chain key with the state sync protocol.</li>
<li>Up-to-date nodes create a <b><b>checkpoint</b></b> regularly by writing the replicated state to disk, computing the state hash, the consensus layer tries to agree on the state by including the hash in the catch-up packages (CUPs).
<ul class="org-ul">
<li>A state recorded on the CUP implies the majority of nodes agree on the state and a majority of nodes can serve this state.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org0686c84" class="outline-3">
<h3 id="org0686c84"><span class="section-number-3">1.4.</span> QUIC protocol</h3>
<div class="outline-text-3" id="text-1-4">
<ul class="org-ul">
<li>A new transport protocol with TLS 1.3, new handshake, new packet structure, encryption, uni/bi-directional streams, etc.</li>
<li>Low latency: zero-handshake latency for recently visited sites, no head-of-line (HOL) blocking.
<ul class="org-ul">
<li>HOL blocking: the delivery of subsequent packets in a data stream is delayed due to the need to process or retransmit an earlier packet.</li>
</ul></li>
<li>Encrypted transport: encrypt most of the packet header by using the connection IDs.
<ul class="org-ul">
<li>The connection IDs also tracks migrated connections securely.</li>
<li>Packet numbers are also encrypted to avoid cross-network correlation.</li>
</ul></li>
<li>Packetization: support multiple stream frames in a single packet.
<ul class="org-ul">
<li>Allow unaffected streams to continue processing even if one stream has packet loss.</li>
<li>Enable multiplexing of different data streams over a single connection.</li>
</ul></li>
<li>Stateless design: each QUIC packets contain enough information to be processed independently  and has built-in mechanism to match responses to requests.</li>
</ul>
</div>
</div>
<div id="outline-container-org86435d1" class="outline-3">
<h3 id="org86435d1"><span class="section-number-3">1.5.</span> Backpressure in blockchain</h3>
<div class="outline-text-3" id="text-1-5">
<ul class="org-ul">
<li>If the receiver slows down the message consumption, the sender&rsquo;s buffer fills up and the sender&rsquo;s networking layer must take one of the three paths:
<ul class="org-ul">
<li>Propagate the backpressure to the application layer to slow down data production; would be a DoS attack vector.</li>
<li>Buffer messages (indefinitely); also an attack vector.</li>
<li>Drop egress messages; risks the liveness, i.e., no delivery guarantee.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org83ccea0" class="outline-2">
<h2 id="org83ccea0"><span class="section-number-2">2.</span> P2P layer</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Send out artifacts created by the above layers.</li>
<li>Receive, validate and distribute artifacts from users and other nodes.</li>
<li>Guarantees the secure <b>eventual</b> broadcast delivery to all nodes.
<ul class="org-ul">
<li><b><b>asynchronous</b></b> communication network assumption provides no time upper bound.</li>
<li>Provide <b><b>bounded time delivery</b></b> under some network assumptions.</li>
</ul></li>
</ul>
</div>
<div id="outline-container-org62678a1" class="outline-3">
<h3 id="org62678a1"><span class="section-number-3">2.1.</span> Gossip protocol</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>When a subnet node creates an artifact or receives it from its peer, it gossips this artifact to all its peers, i.e., other connected subnet nodes.
<ul class="org-ul">
<li>Each artifact eventually propagates through the whole subnet.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orge37e9da" class="outline-3">
<h3 id="orge37e9da"><span class="section-number-3">2.2.</span> Artifacts</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li>Network messages to be broadcast in the subnet, e.g.,
<ul class="org-ul">
<li>Users input to canister smart contracts;</li>
<li>Protocol-originating messages, e.g., blocks produced by the consensus layer or state synchronization certification.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org1dc925b" class="outline-3">
<h3 id="org1dc925b"><span class="section-number-3">2.3.</span> Constraints</h3>
<div class="outline-text-3" id="text-2-3">
<ul class="org-ul">
<li>P2P layer should provide the above guarantee under the following constraints:
<ul class="org-ul">
<li>Bounded-time delivery or eventual (under weaker assumptions) delivery.</li>
<li>Tolerate up to a certain threshold of dropped artifacts or byzantine nodes (1/3).</li>
<li>Each peer has its own share of the resources available at other peers and the resource usage by each peer is bounded.</li>
<li>Should be able to prioritize different artifacts.</li>
<li>Provide high throughput (rather than low latency) and avoid data duplication to utilize the network.</li>
<li>Resilient to DoS/Spam and enable encryption, authenticity and integrity.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgc1e2be6" class="outline-3">
<h3 id="orgc1e2be6"><span class="section-number-3">2.4.</span> Adverts</h3>
<div class="outline-text-3" id="text-2-4">
<ul class="org-ul">
<li>Simply flooding all artifacts consumes unnecessary network bandwidth, instead artifacts previews called adverts are sent first.</li>
<li>An advert includes fields used by the gossip protocol and its application components (which process the messages) for integrity verification and decision-making (e.g., which artifacts to prioritize)</li>
<li>Other nodes may request the corresponding artifact from one or more of its peers who send the adverts.</li>
<li>In the new P2P layer, if the artifact is small enough (&lt; 1KB), adverts are not used.</li>
</ul>
</div>
<div id="outline-container-orgd3871ab" class="outline-4">
<h4 id="orgd3871ab"><span class="section-number-4">2.4.1.</span> Advert priority</h4>
<div class="outline-text-4" id="text-2-4-1">
<ul class="org-ul">
<li>Consensus provides the gossip protocol with a priority function, which takes an advert and its attributes and returns a priority value.</li>
<li>Each P2P client decide how to request the artifact (e.g.,drop or fetch immediately).</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org75a5a00" class="outline-3">
<h3 id="org75a5a00"><span class="section-number-3">2.5.</span> Artifact pool</h3>
<div class="outline-text-3" id="text-2-5">
<ul class="org-ul">
<li>A data structure maintained by the gossip protocol.</li>
<li>Contain all available artifacts for each application component.</li>
<li>P2P informs consensus and other client components about the pool changes by calling <code>on_state_change()</code>, each component determines its next action, e.g., validation.
<ul class="org-ul">
<li>Each call returns a set of <code>ChangeActions</code> corresponding to the addition and deletion of artifacts from the validated pool of a client; the corresponding adverts are then broadcasted.</li>
</ul></li>
<li>The artifacts can be persistent to non-volatile storage.</li>
<li>Separated into validated and unvalidated sections; the size of each unvalidated section for each peer is bounded to prevent bad peers from filling up the pool.</li>
</ul>
</div>
</div>
<div id="outline-container-org96fdae6" class="outline-3">
<h3 id="org96fdae6"><span class="section-number-3">2.6.</span> Peer context</h3>
<div class="outline-text-3" id="text-2-6">
<ul class="org-ul">
<li>Advert queue: a priority queue of all adverts the peer has received from another peer, ordered by their priority.</li>
<li>Requested set: contains all adverts whose artifacts have been requested.</li>
<li>Received check cache: used to prevent duplicated artifact requests.</li>
</ul>
</div>
</div>
<div id="outline-container-orgd5d43ee" class="outline-3">
<h3 id="orgd5d43ee"><span class="section-number-3">2.7.</span> Gossip protocol events</h3>
<div class="outline-text-3" id="text-2-7">
<ul class="org-ul">
<li>Create a new advert for a new artifact added by application component locally and sends to all peers;</li>
<li>Process a new advert.</li>
<li>Process a new artifact.</li>
<li>Handle recovery and reconnection.</li>
</ul>
</div>
<div id="outline-container-orgb88b30b" class="outline-4">
<h4 id="orgb88b30b"><span class="section-number-4">2.7.1.</span> Process a new advert received from peer \(i\)</h4>
<div class="outline-text-4" id="text-2-7-1">
<ul class="org-ul">
<li>If the advert is already in peer \(i\)&rsquo;s received check cache, or the priority is &ldquo;drop&rdquo;, ignore;</li>
<li>If the advert is not in the pool, adds to the advert queue for peer \(i\);</li>
<li>If enough space for peer \(i\)&rsquo;s unvalidated section in the artifact pool, call <code>download_next(i)</code> (with a timeout) to ask for the next artifact with the highest priority (not necessarily corresponds to the last received advert).</li>
<li><code>download_next(i)</code> sends the request to peer \(i\) and moves the advert with the highest priority from advert queue to the requested set of peer \(i\);</li>
<li>If <code>download_next(i)</code> is timeout, check whether the advert is also received from other advert queue and try to fetch it from them before retrying with peer \(i\) (as peer \(i\) may be misbehaving).</li>
</ul>
</div>
</div>
<div id="outline-container-orgbf423b6" class="outline-4">
<h4 id="orgbf423b6"><span class="section-number-4">2.7.2.</span> Process a new received artifact from peer \(i\)</h4>
<div class="outline-text-4" id="text-2-7-2">
<ul class="org-ul">
<li>First check the received artifact has been requested and verify its integrity;</li>
<li>Remove all corresponding adverts from all advert queues and requested sets;</li>
<li>Add the artifact to peer \(i\)&rsquo;s unvalidated pool and wait for the client component to validate;</li>
<li>Add the artifact hash to peer \(i\)&rsquo;s received check cache for a grace period to ignore further adverts for the same artifact;
<ul class="org-ul">
<li>If the artifact is removed from the unvalidated section later (e.g., the artifact is invalid), the application component may request it again from peer \(i\), with the received cache mechanism the gossip protocol does not send out the request again in a short time.</li>
</ul></li>
<li>If enough space for peer \(i\)&rsquo;s unvalidated section, call <code>download_next(i)</code>.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org6c517fa" class="outline-3">
<h3 id="org6c517fa"><span class="section-number-3">2.8.</span> Common attacks</h3>
<div class="outline-text-3" id="text-2-8">
</div>
<div id="outline-container-orgfd1d522" class="outline-4">
<h4 id="orgfd1d522"><span class="section-number-4">2.8.1.</span> Sybil attack</h4>
<div class="outline-text-4" id="text-2-8-1">
<ul class="org-ul">
<li>An attack creates multiple nodes to gain influences.</li>
</ul>
</div>
</div>
<div id="outline-container-org870ea28" class="outline-4">
<h4 id="org870ea28"><span class="section-number-4">2.8.2.</span> Eclipse attack</h4>
<div class="outline-text-4" id="text-2-8-2">
<ul class="org-ul">
<li>All peers of a correct node are byzantine nodes to disconnect the correct node from the subnet (though they cannot send spoofed artifacts due to artifact authentication).</li>
<li>Mitigation: use overlays with large min cut and expansion so that at least one peer is correct for each node.
<ul class="org-ul">
<li>Each node uses a different overlap.</li>
<li>Small enough subnets can be a complete graph, large subnets use more sparse overlays.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgdba1aff" class="outline-4">
<h4 id="orgdba1aff"><span class="section-number-4">2.8.3.</span> Routing table poisoning</h4>
<div class="outline-text-4" id="text-2-8-3">
<ul class="org-ul">
<li>Malicious nodes provide false routing information to disrupt network topology.</li>
</ul>
</div>
</div>
<div id="outline-container-org53f86f9" class="outline-4">
<h4 id="org53f86f9"><span class="section-number-4">2.8.4.</span> Bandwidth hogging</h4>
<div class="outline-text-4" id="text-2-8-4">
<ul class="org-ul">
<li>Attackers consume excessive network resources.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org91251d1" class="outline-3">
<h3 id="org91251d1"><span class="section-number-3">2.9.</span> Security</h3>
<div class="outline-text-3" id="text-2-9">
<ul class="org-ul">
<li>NNS manages the subnet membership, each node only requests and accepts connections with nodes in the same subnet to prevent DoS attack.</li>
<li>NNS canisters guarantee that all communication between two nodes are encrypted and authenticated by TLS.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orga591c0f" class="outline-2">
<h2 id="orga591c0f"><span class="section-number-2">3.</span> Transport component</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Below the P2P component to main the actual network connections between peers.</li>
<li>Have its own send buffers and internal heartbeat mechanism, which are important for bounded time delivery.</li>
<li>Frame gossip message with its own 7 headers.</li>
</ul>
</div>
<div id="outline-container-org5a5bb2f" class="outline-3">
<h3 id="org5a5bb2f"><span class="section-number-3">3.1.</span> Transient connection disturbances</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>Transport keeps buffering ongoing messages in TX queues;</li>
<li>When the connection works again, transmit all buffered messages and empty TX queues.</li>
</ul>
</div>
</div>
<div id="outline-container-org90425a4" class="outline-3">
<h3 id="org90425a4"><span class="section-number-3">3.2.</span> Long disconnection with full TX queue</h3>
<div class="outline-text-3" id="text-3-2">
<ul class="org-ul">
<li>Transport notifies the receiver gossip protocol, sends retransmission request with artifact filter to tell the sender the latest advert the receiver has seen;
<ul class="org-ul">
<li>The receiver may not need to catch up all artifacts since they may have received the same adverts from other peers before sending the retransmission.</li>
</ul></li>
<li>When receiving a retransmission request, the sender sends all relevant adverts according to the filter through the TX queue.</li>
<li>If the TX queue becomes full again, another retransmission takes place.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgca3424d" class="outline-2">
<h2 id="orgca3424d"><span class="section-number-2">4.</span> State sync protocol</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>Nodes periodically advertise all locally available state versions with adverts;
<ul class="org-ul">
<li>A version is the block height to which the state corresponds, and the state hash.</li>
</ul></li>
<li>If a node sees a more recent CUP, it can conclude it has fallen behind and can request the state from the peer which sends the CUP;
<ul class="org-ul">
<li>The protocol ensures unchanged pieces of a state are not re-downloaded, as the state can be viewed as a file tree and each file is split into chunks.</li>
<li>A node can simultaneously request chunks from multiple peers like BitTorrent.</li>
</ul></li>
<li>The resuming node starts by requesting the manifest chunk, which contains a list of all files and chunks as well as their hashes the state contains;
<ul class="org-ul">
<li>The manifest is peer-agnostic and the manifest hash is included in the CUP.</li>
<li>Once the manifest hash is verified, one can conclude all file and chunk hashes are authentic.</li>
</ul></li>
<li>The node then request missing chunks from multiple peers.</li>
</ul>
</div>
<div id="outline-container-org3c8ed8a" class="outline-3">
<h3 id="org3c8ed8a"><span class="section-number-3">4.1.</span> Monolithic P2P layer not suitable for the state sync</h3>
<div class="outline-text-3" id="text-4-1">
<ul class="org-ul">
<li>P2P layer is designed to distribute small messages, which is not the case for the state sync protocol.</li>
<li>To simplify the P2P layer, it is separated into 2: one for state sync and the other for the rest clients.</li>
<li>The P2P layer uses a new transport component to support two <b><b>async</b></b> APIs: <code>push(message, peer_id)</code> and <code>rpc(message, peer_id) -&gt; response</code>.
<ul class="org-ul">
<li>P2P periodically calls <code>push()</code> with the current states to advertise own current state to all peers.</li>
<li>When noticing itself is behind, it calls <code>rpc()</code> to request specific chunks</li>
</ul></li>
<li>Using a single TCP steam is impossible to relate requests to responses without tracking states, therefore QUIC protocol is used to <b><b>multiplex</b></b> multiple streams in one connection.
<ul class="org-ul">
<li>P2P layer can be completely asynchronous to better utilize CPU and bandwidth resources, e.g., congestion on state synchronization does not necessarily affect other adverts.</li>
<li>Every response is tied to a corresponding request without having to maintain states.</li>
<li>Can help dynamically prioritize traffic of different clients.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orga14cf38" class="outline-2">
<h2 id="orga14cf38"><span class="section-number-2">5.</span> Fully QUIC-based P2P layer</h2>
<div class="outline-text-2" id="text-5">
<ul class="org-ul">
<li>IC&rsquo;s P2P layer stops using TCP altogether, which means a shift to a fully asynchronous implementation of the P2P layer.
<ul class="org-ul">
<li>Each request is sent as a new QUIC stream and handled independently from other requests.</li>
<li>Each client (e.g., consensus,state sync, key distribution) uses a separate instance of the P2P layer (state sync uses the specific one).</li>
</ul></li>
<li>Uses a new abstract data structure slot table to track the content of the validated artifact pool and the process of updating the peers.</li>
<li>Reduces the block rate under heavy load.</li>
<li>Will eventually shift all clients to use the new P2P layer.</li>
</ul>
</div>
<div id="outline-container-org82401b7" class="outline-3">
<h3 id="org82401b7"><span class="section-number-3">5.1.</span> Properties for consensus-related clients</h3>
<div class="outline-text-3" id="text-5-1">
<ul class="org-ul">
<li>Bounded number of active artifacts in the validated artifact pool; the consensus protocol uses checkpoints to purge artifacts periodically, hence a maximal pool size \(C\).</li>
<li>Explicit expiry of artifacts; if an artifact is purged from a pool, it is no longer disseminated to peers; if no peer of a node has an artifact, the node is guaranteed to not need that artifact even if it failed to receive it.
<ul class="org-ul">
<li>During state synchronization, nodes use artifacts to update own states, once states are updated, artifacts can be safely purged after some time, e.g., to help other nodes to synchronize states.</li>
<li>Newly joined nodes use CUP for offline state sync.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgaa2f888" class="outline-3">
<h3 id="orgaa2f888"><span class="section-number-3">5.2.</span> Slot table</h3>
<div class="outline-text-3" id="text-5-2">
<ul class="org-ul">
<li>Maintained on the sender side and inferred on the receiver side.</li>
<li>The table size corresponds to the number of active artifacts in the validated pool.</li>
<li>Whenever an artifact is added to the validated pool, it is added in the slot table on the sender side.
<ul class="org-ul">
<li>The sender sends out a slot update message to all peers.</li>
<li>Receivers infer the slot table state based on the arrived slot update messages.</li>
<li>Deletions are implicitly propagated by new artifact reusing the slot.</li>
<li>Allows nodes to notice when an artifact no longer exists in any peer&rsquo;s slot tables and can remove it from the unvalidated pool.</li>
</ul></li>
<li>Each slot maintains a version number for the slot artifact; receivers only accept update messages with higher version numbers than the one it already has.</li>
<li>A lightweight thread is spawn for each slot per peer to reliably push the slot update message.</li>
<li>The approach combines buffering messages and dropping messages in handling the backpressure to achieve resilience and liveness.</li>
<li>Bounds on the unvalidated pool: \(C\) artifacts from an honest peer and \(2C\) from a malicious peer.</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-dfinity.html">dfinity</a> <a href="https://chenyo.me/tag-network.html">network</a> <a href="https://chenyo.me/tag-p2p.html">p2p</a> </div>]]></description>
  <category><![CDATA[dfinity]]></category>
  <category><![CDATA[network]]></category>
  <category><![CDATA[p2p]]></category>
  <link>https://chenyo.me/2024-10-04-dfinity-networking-layer.html</link>
  <guid>https://chenyo.me/2024-10-04-dfinity-networking-layer.html</guid>
  <pubDate>Fri, 04 Oct 2024 08:16:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Build a free Telegram Mensa bot]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org4663c8f">1. Previously on my Telegram bot</a></li>
<li><a href="#org3be2547">2. Why do I need a Mensa bot</a></li>
<li><a href="#orgdb88c92">3. How to get the data</a>
<ul>
<li><a href="#org0a2800a">3.1. Scrape menus locally</a></li>
<li><a href="#orgd2ff214">3.2. Scrape menus on Render</a></li>
</ul>
</li>
<li><a href="#org36f6131">4. Performance</a></li>
<li><a href="#org3e53350">5. Conclusion</a></li>
</ul>
</div>
</nav>
<div id="outline-container-org4663c8f" class="outline-2">
<h2 id="org4663c8f"><span class="section-number-2">1.</span> Previously on my Telegram bot</h2>
<div class="outline-text-2" id="text-1">
<p>
In the post <a href="https://chenyo.me/2024-09-08-build-a-free-telegram-sticker-bot.html">Build a free Telegram sticker tag bot</a>, I detailed the process of integrating various online services to create a sticker tag bot.
After using it for a month, I encountered an intriguing production issue: on one occasion, the inline query result was incomplete.
Interestingly, restarting the Render deployment resolved the problem, though I never fully understood the root cause.
</p>

<p>
Despite this minor hiccup, the sticker tag bot has proven to be reliable most of the time.
However, I found myself not utilizing it as frequently as anticipated.
This was primarily because sending a recent sticker directly is often more convenient than invoking the bot by name.
</p>

<p>
At the conclusion of that post, I hinted at a second functionality I had in mind for the bot: a Mensa bot designed to inform me about the daily offerings at each Mensa (university cafeteria).
</p>
</div>
</div>
<div id="outline-container-org3be2547" class="outline-2">
<h2 id="org3be2547"><span class="section-number-2">2.</span> Why do I need a Mensa bot</h2>
<div class="outline-text-2" id="text-2">
<p>
One mobile app I frequently use on weekdays is <a href="https://github.com/famoser/Mensa">Mensa</a>, which lists daily menus for each Zürich Mensa to help people make their most important decision of the day.
However, it was merely an inconvenience for myself that the app lacked images of the meals.
I found it difficult to imagine the dishes based solely on the menu descriptions.
To fix this, I decide to add the meal images myself.
</p>
</div>
</div>
<div id="outline-container-orgdb88c92" class="outline-2">
<h2 id="orgdb88c92"><span class="section-number-2">3.</span> How to get the data</h2>
<div class="outline-text-2" id="text-3">
<p>
I couldn&rsquo;t find an official API for this, so I decided to scrape the webpage myself.
Here&rsquo;s where things got tricky: the Mensa web pages use JavaScript to render content.
This meant I couldn&rsquo;t just grab the page - I needed a browser to run the JavaScript first.
</p>
</div>
<div id="outline-container-org0a2800a" class="outline-3">
<h3 id="org0a2800a"><span class="section-number-3">3.1.</span> Scrape menus locally</h3>
<div class="outline-text-3" id="text-3-1">
<p>
On a local machine, it&rsquo;s pretty straightforward.
You just grab a scraper library like <a href="https://github.com/go-rod/rod">go-rod</a> and figure out the right API calls.
After you&rsquo;ve snagged the page, you can use an HTML parser like <a href="https://github.com/PuerkitoBio/goquery">goquery</a> to pull out all the menus.
</p>
</div>
</div>
<div id="outline-container-orgd2ff214" class="outline-3">
<h3 id="orgd2ff214"><span class="section-number-3">3.2.</span> Scrape menus on Render</h3>
<div class="outline-text-3" id="text-3-2">
<p>
The only snag with <code>go-rod</code> is it&rsquo;s too bulky for a Render free account.
It needs to install Chromium first, but Render&rsquo;s <a href="https://render.com/pricing">512M RAM</a> can&rsquo;t handle that.
I didn&rsquo;t want to hunt for another free host, so <code>go-rod</code> had to go.
</p>

<p>
Claude then pitched the idea of online scraping services.
Most I found were expensive, aimed at heavy-duty scraping.
But I lucked out with <a href="https://app.abstractapi.com/api/scrape/pricing">AbstractAPI</a>, offering 1000 total requests for free.
If I&rsquo;m smart, that could last me about half a year.
<a href="https://docs.scraperapi.com/v/faq/plans-and-billing/free-plan-and-7-day-free-trial">ScraperAPI</a> seemed promising with 1000 monthly free requests.
But it choked on Javascript rendering for my targeted pages even with <code>render=true</code>.
</p>

<p>
AbstractAPI has its quirks too.
The scraped result comes out messy, full of <code>\n</code> and <code>\&amp;#34</code>.
So I had to clean it up before <code>goquery</code> can make sense of it.
</p>
</div>
</div>
</div>
<div id="outline-container-org36f6131" class="outline-2">
<h2 id="org36f6131"><span class="section-number-2">4.</span> Performance</h2>
<div class="outline-text-2" id="text-4">
<p>
AbstractAPI&rsquo;s free plan only lets you make one request per second.
That&rsquo;s kinda slow when you factor in page rendering and parsing time.
The full HTML page is a whopping 3M, so I&rsquo;ve gotta wait a bit for each bot request.
</p>

<p>
I thought about caching results to cut down on requests.
But here&rsquo;s the thing: menu images usually update right before meal times.
If I didn&rsquo;t catch the image last time, I need the latest scoop.
So, I end up scraping fresh data for each Mensa every single time.
</p>
</div>
</div>
<div id="outline-container-org3e53350" class="outline-2">
<h2 id="org3e53350"><span class="section-number-2">5.</span> Conclusion</h2>
<div class="outline-text-2" id="text-5">
<p>
Here&rsquo;s a quick look at what the bot can do now: it tags stickers and scrapes Mensa menus.
Keep in mind the GIF is sped up to twice the normal speed.
</p>


<figure id="org85a53db">
<img src="./static/telegram.gif" alt="telegram.gif" align="center" width="700px" style="border: 1px solid black;">

<figcaption><span class="figure-number">Figure 1: </span>The current Telegram bot</figcaption>
</figure>

<p>
As in the previous post, I aim to demonstrate that while Internet services can be costly, there often remain free solutions for building hobby projects.
This may require more extensive research and additional processing, but it&rsquo;s still feasible.
I hope this continues to be the case in the years to come.
</p>

<p>
The <a href="https://github.com/chenyo-17/pbaobot">repository</a> is also public now.
</p>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-tool.html">tool</a> <a href="https://chenyo.me/tag-telegram.html">telegram</a> </div>]]></description>
  <category><![CDATA[tool]]></category>
  <category><![CDATA[telegram]]></category>
  <link>https://chenyo.me/2024-09-25-build-a-free-telegram-mensa-bot.html</link>
  <guid>https://chenyo.me/2024-09-25-build-a-free-telegram-mensa-bot.html</guid>
  <pubDate>Wed, 25 Sep 2024 20:30:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[C++ feature introduction]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org3319f27">1. Namespace</a></li>
<li><a href="#org6c5ab6f">2. Wrapper class</a></li>
<li><a href="#orge28eb5f">3. Iterator</a>
<ul>
<li><a href="#org22b3188">3.1. A doubly linked list (DLL) iterator</a></li>
</ul>
</li>
<li><a href="#orgabecb8b">4. STL containers</a>
<ul>
<li><a href="#org125b0e5">4.1. Vector</a></li>
<li><a href="#orgb13b64e">4.2. Set</a></li>
<li><a href="#org7084f8e">4.3. Unordered maps</a></li>
</ul>
</li>
<li><a href="#org4aebc03">5. <code>auto</code></a></li>
<li><a href="#org9a35959">6. Smart pointers</a>
<ul>
<li><a href="#org3f34e9b">6.1. <code>std::unique_ptr</code></a></li>
<li><a href="#orga6f4d50">6.2. <code>std::shared_ptr</code></a></li>
</ul>
</li>
<li><a href="#org0b2f277">7. Synchronization</a>
<ul>
<li><a href="#org2b7c7db">7.1. <code>std::mutex</code></a></li>
<li><a href="#orgace0084">7.2. <code>std::scoped_lock</code></a></li>
<li><a href="#org00ab3e7">7.3. <code>std::condition_variable</code></a></li>
<li><a href="#org4f057cc">7.4. Reader-writer lock</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal not for the <a href="https://github.com/cmu-db/15445-bootcamp">CMU 15-445 C++ bootcamp</a> along with some explanation from Claude.ai.
</p>
<div id="outline-container-org3319f27" class="outline-2">
<h2 id="org3319f27"><span class="section-number-2">1.</span> Namespace</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>Provides scopes to identifiers with <code>::</code>.</li>
<li><p>
Namespaces can be nested.
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef;">namespace</span> <span style="color: #a9a1e1;">ABC</span> <span style="color: #51afef;">{</span>
    <span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">spam</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">a</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span> <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Hello from ABC::spam"</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #c678dd;">}</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">declare a nested namespace</span>
    <span style="color: #51afef;">namespace</span> <span style="color: #a9a1e1;">DEF</span> <span style="color: #c678dd;">{</span>
    <span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">bar</span><span style="color: #98be65;">(</span><span style="color: #ECBE7B;">float</span> <span style="color: #dcaeea;">a</span><span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span> <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Hello from ABC::DEF::bar"</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #98be65;">}</span>
    <span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">use_spam</span><span style="color: #98be65;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">a</span><span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
    <span style="color: #a9a1e1;">ABC</span>::spam<span style="color: #a9a1e1;">(</span>a<span style="color: #a9a1e1;">)</span>;
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">no difference with ABC::spam(a) if DEF</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">does not have a spam function</span>
    spam<span style="color: #a9a1e1;">(</span>a<span style="color: #a9a1e1;">)</span>;
    <span style="color: #98be65;">}</span>
<span style="color: #c678dd;">}</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">namespace DEF</span>

    <span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">use_DEF_bar</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">float</span> <span style="color: #dcaeea;">a</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if a namespace outside of DEF wants to use DEF::bar</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">it must use the full namespace path ABC::DEF::bar</span>
    <span style="color: #a9a1e1;">DEF</span>::bar<span style="color: #98be65;">(</span>a<span style="color: #98be65;">)</span>;
    <span style="color: #c678dd;">}</span>

<span style="color: #51afef;">}</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">namespace ABC</span>
</pre>
</div></li>
<li>Two namespaces can define functions with the same name and signatures.</li>
<li>Name resolution rules: first check in the current scope, then enclosing scopes, finally going outward until it reaches the global scope.</li>
<li>Can use <code>using namespace B</code> to use identifiers in <code>B</code> in the current scope without specifying <code>B::</code>, this is not a good practice.</li>
<li>Can also only bring certain members of a namespace into the current scope, e.g., <code>using C::eggs</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-org6c5ab6f" class="outline-2">
<h2 id="org6c5ab6f"><span class="section-number-2">2.</span> Wrapper class</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li><p>
Used to manage a resource, e.g., memory, file sockets, network connections.
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">IntPtrManager</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">private</span>:
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">manages an int* to access the dynamic memory</span>
  <span style="color: #ECBE7B;">int</span> *<span style="color: #dcaeea;">ptr_</span>;
<span style="color: #51afef;">}</span>;
</pre>
</div></li>

<li>Use the RAII (Resource Acquisition is Initialization) idea: tie the lifetime of a resource to the lifetime of an object.
<ul class="org-ul">
<li>Goal: ensure resources are released even if an exception occurs.</li>
<li><p>
Acquisition: resources are acquired in the constructor.
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">IntPtrManager</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">public</span>:
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the constructor initializes a resource</span>
  <span style="color: #c678dd;">IntPtrManager</span><span style="color: #c678dd;">()</span> <span style="color: #c678dd;">{</span>
    ptr_ = <span style="color: #51afef;">new</span> <span style="color: #ECBE7B;">int</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">allocate the memory</span>
    *ptr_ = <span style="color: #da8548; font-weight: bold;">0</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">set the default value</span>
  <span style="color: #c678dd;">}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the second constructor takes an initial value</span>
  <span style="color: #c678dd;">IntPtrManager</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">val</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    ptr_ = <span style="color: #51afef;">new</span> <span style="color: #ECBE7B;">int</span>;
    *ptr_ = val;
  <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>;
</pre>
</div></li>
<li><p>
Release: resources are released in the destructor.
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">IntPtrManager</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">public</span>:
  ~<span style="color: #c678dd;">IntPtrManager</span><span style="color: #c678dd;">()</span> <span style="color: #c678dd;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">ptr_ may be null after the move</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">don't delete a null pointer</span>
    <span style="color: #51afef;">if</span> <span style="color: #98be65;">(</span>ptr_<span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
      <span style="color: #51afef;">delete</span> ptr_;
    <span style="color: #98be65;">}</span>
  <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>;
</pre>
</div></li>
</ul></li>

<li><p>
A wrapper class should not be copyable to avoid double deletion of the same resource in two destructors.
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">IntPtrManager</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">public</span>:
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">delete copy constructor</span>
  <span style="color: #c678dd;">IntPtrManager</span><span style="color: #c678dd;">(</span><span style="color: #51afef;">const</span> <span style="color: #ECBE7B;">IntPtrManager</span> &amp;<span style="color: #c678dd;">)</span> = <span style="color: #51afef;">delete</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">delete copy assignment operator</span>
  <span style="color: #ECBE7B;">IntPtrManager</span> &amp;<span style="color: #51afef;">operator</span><span style="color: #c678dd;">=</span><span style="color: #c678dd;">(</span><span style="color: #51afef;">const</span> <span style="color: #ECBE7B;">IntPtrManager</span> &amp;<span style="color: #c678dd;">)</span> = <span style="color: #51afef;">delete</span>;
<span style="color: #51afef;">}</span>;
</pre>
</div></li>

<li><p>
A wrapper class is still moveable from different lvalues/owners.
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">IntPtrManager</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">public</span>:
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a move constructor</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">called by IntPtrManager b(std::move(a))</span>
  <span style="color: #c678dd;">IntPtrManager</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">IntPtrManager</span> &amp;&amp;<span style="color: #dcaeea;">other</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">while other is a rvalue reference, other.ptr_ is a lvalue</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">therefore a copy happens here, not a move</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">in the constructor this.ptr_ has not pointed to anything</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">so no need to delete ptr_</span>
    ptr = other.ptr_;
    other.ptr_ = <span style="color: #a9a1e1;">nullptr</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">other.ptr_ becomes invalud</span>
  <span style="color: #c678dd;">}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">move assignment operator</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">this function is used by c = std::move(b) operation</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">note that calling std::move() does not require implementing this operator</span>
  <span style="color: #ECBE7B;">IntPtrManager</span> &amp;<span style="color: #51afef;">operator</span><span style="color: #c678dd;">=</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">IntPtrManager</span> &amp;&amp;<span style="color: #dcaeea;">other</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a self assignment should not delete its ptr_</span>
    <span style="color: #51afef;">if</span> <span style="color: #98be65;">(</span>ptr_ == other.ptr_<span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
      <span style="color: #51afef;">return</span> *<span style="color: #51afef;">this</span>;
    <span style="color: #98be65;">}</span>
    <span style="color: #51afef;">if</span> <span style="color: #98be65;">(</span>ptr_<span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
      <span style="color: #51afef;">delete</span> ptr_; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">release old resource to avoid leak</span>
    <span style="color: #98be65;">}</span>
    ptr_ = other.ptr_;
    other.ptr_ = <span style="color: #a9a1e1;">nullptr</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">invalidate other.ptr_</span>
    <span style="color: #51afef;">return</span> *<span style="color: #51afef;">this</span>;
  <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>;
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orge28eb5f" class="outline-2">
<h2 id="orge28eb5f"><span class="section-number-2">3.</span> Iterator</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li><p>
Iterators, e.g., pointers, are objects that point to an element inside a container.
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #ECBE7B;">int</span> *<span style="color: #dcaeea;">array</span> = malloc<span style="color: #51afef;">(</span><span style="color: #51afef;">sizeof</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">)</span> * <span style="color: #da8548; font-weight: bold;">10</span><span style="color: #51afef;">)</span>;
<span style="color: #ECBE7B;">int</span> *<span style="color: #dcaeea;">iter</span> = array;
<span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">zero_elem</span> = *iter;
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">use ++ to iterate through the C style array</span>
iter++;
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">deference the operator to return the value at the iterator</span>
<span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">first_elem</span> = *iter;
</pre>
</div></li>
<li>Two main components of an iterator:
<ul class="org-ul">
<li>Dereference operator <code>*</code>: return the value of the element of the current iterator position.</li>
<li>Increment <code>++</code>: increment the iterator&rsquo;s position by 1
<ul class="org-ul">
<li>Postfix <code>iter++</code>: return the iterator <b><b>before</b></b> the increment (<code>Iterator</code>).</li>
<li>Prefix <code>++iter</code>: return the result of the increment (<code>Iterator&amp;</code>).</li>
<li><code>++iter</code> is more efficient.</li>
</ul></li>
</ul></li>
<li>Often used to access and modify elements in C++ STL containers.</li>
</ul>
</div>
<div id="outline-container-org22b3188" class="outline-3">
<h3 id="org22b3188"><span class="section-number-3">3.1.</span> A doubly linked list (DLL) iterator</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li><p>
Define a link node:
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef;">struct</span> <span style="color: #ECBE7B;">Node</span> <span style="color: #51afef;">{</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">member initializer list, e.g., next_(nullptr) equals to next_ = nullptr</span>
  <span style="color: #c678dd;">Node</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">val</span><span style="color: #c678dd;">)</span> : next_<span style="color: #c678dd;">(</span><span style="color: #a9a1e1;">nullptr</span><span style="color: #c678dd;">)</span>, prev_<span style="color: #c678dd;">(</span><span style="color: #a9a1e1;">nullptr</span><span style="color: #c678dd;">)</span>, value_<span style="color: #c678dd;">(</span>val<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{}</span>

  <span style="color: #ECBE7B;">Node</span> *<span style="color: #dcaeea;">next_</span>;
  <span style="color: #ECBE7B;">Node</span> *<span style="color: #dcaeea;">prev_</span>;
  <span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">value_</span>;
<span style="color: #51afef;">}</span>;
</pre>
</div></li>

<li><p>
Define the iterator for the DLL:
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">DLLIterator</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">public</span>:
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">takes in a node to mark the start of the iteration</span>
  <span style="color: #c678dd;">DLLIterator</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">Node</span> *<span style="color: #dcaeea;">head</span><span style="color: #c678dd;">)</span> : curr_<span style="color: #c678dd;">(</span>head<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">prefix increment operator (++iter)</span>
  <span style="color: #ECBE7B;">DLLIterator</span> &amp;<span style="color: #51afef;">operator</span><span style="color: #c678dd;">++</span><span style="color: #c678dd;">()</span> <span style="color: #c678dd;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">must use -&gt; to access the member of a pointer!</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">use . if accessing the object itself</span>
    curr_ = curr_-&gt;next_;
    <span style="color: #51afef;">return</span> *<span style="color: #51afef;">this</span>;
  <span style="color: #c678dd;">}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">postfix increment operator (iter++)</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the (int) is a dummy parameter to differentiate</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the prefix and postfix increment</span>
  <span style="color: #ECBE7B;">DLLIterator</span> <span style="color: #51afef;">operator</span><span style="color: #c678dd;">++</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #ECBE7B;">DLLIterator</span> <span style="color: #dcaeea;">temp</span> = *<span style="color: #51afef;">this</span>;
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">this is a pointer to the current object</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">*this returns the iterator object</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">++*this calls the prefix increment operator,</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">which equals to `this-&gt;operator++()`</span>
    ++*<span style="color: #51afef;">this</span>;
    <span style="color: #51afef;">return</span> temp;
  <span style="color: #c678dd;">}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">implement the equality operator</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">an lvalue reference argument avoids the copy</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the const in the parameter means this function</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">cannot modify the argument</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the `const` outside the parameter list means</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the function cannot modify `this`</span>
  <span style="color: #ECBE7B;">bool</span> <span style="color: #51afef;">operator</span><span style="color: #c678dd;">==</span><span style="color: #c678dd;">(</span><span style="color: #51afef;">const</span> <span style="color: #ECBE7B;">DLLIterator</span> &amp;<span style="color: #dcaeea;">str</span><span style="color: #c678dd;">)</span> <span style="color: #51afef;">const</span> <span style="color: #c678dd;">{</span>
    <span style="color: #51afef;">return</span> itr.curr_ == <span style="color: #51afef;">this</span>-&gt;curr_;
  <span style="color: #c678dd;">}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">implement the dereference operator to return the value</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">at the current iterator position</span>
  <span style="color: #ECBE7B;">int</span> <span style="color: #51afef;">operator</span><span style="color: #c678dd;">*</span><span style="color: #c678dd;">()</span> <span style="color: #c678dd;">{</span> <span style="color: #51afef;">return</span> curr_-&gt;value_; <span style="color: #c678dd;">}</span>

<span style="color: #51afef;">private</span>:
  <span style="color: #ECBE7B;">Node</span> *<span style="color: #dcaeea;">curr_</span>;
<span style="color: #51afef;">}</span>;
</pre>
</div></li>

<li><p>
Define DLL:
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">DLL</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">public</span>:
  <span style="color: #c678dd;">DLL</span><span style="color: #c678dd;">()</span> : head_<span style="color: #c678dd;">(</span><span style="color: #a9a1e1;">nullptr</span><span style="color: #c678dd;">)</span>, size_<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">0</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the destructor deletes nodes one by one</span>
  ~<span style="color: #c678dd;">DLL</span><span style="color: #c678dd;">()</span> <span style="color: #c678dd;">{</span>
    <span style="color: #ECBE7B;">Node</span> *<span style="color: #dcaeea;">current</span> = head_;
    <span style="color: #51afef;">while</span> <span style="color: #98be65;">(</span>current != <span style="color: #a9a1e1;">nullptr</span><span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
      <span style="color: #ECBE7B;">Node</span> *<span style="color: #dcaeea;">next</span> = current-&gt;next_;
      <span style="color: #51afef;">delete</span> current;
      current = next;
    <span style="color: #98be65;">}</span>
    head_ = <span style="color: #a9a1e1;">nullptr</span>;
  <span style="color: #c678dd;">}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">after the insertion `new_node` becomes the new head</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">`head` is just a pointer to the node</span>
  <span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">InsertAtHead</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">val</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #ECBE7B;">Node</span> *<span style="color: #dcaeea;">new_node</span> = <span style="color: #51afef;">new</span> <span style="color: #ECBE7B;">Node</span><span style="color: #98be65;">(</span>val<span style="color: #98be65;">)</span>;
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">new_node-&gt;next points to the object pointed by head_</span>
    new_node-&gt;next_ = head_;

    <span style="color: #51afef;">if</span> <span style="color: #98be65;">(</span>head_ != <span style="color: #a9a1e1;">nullptr</span><span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
      head_-&gt;prev_ = new_node;
    <span style="color: #98be65;">}</span>

    head_ = new_node;
    size_ += <span style="color: #da8548; font-weight: bold;">1</span>;
  <span style="color: #c678dd;">}</span>

  <span style="color: #ECBE7B;">DLLIterator</span> <span style="color: #c678dd;">Begin</span><span style="color: #c678dd;">()</span> <span style="color: #c678dd;">{</span> <span style="color: #51afef;">return</span> DLLIterator<span style="color: #98be65;">(</span>head_<span style="color: #98be65;">)</span>; <span style="color: #c678dd;">}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">returns the pointer pointing one after the last element</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">used in the loop to determine whether the iteration ends</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">e.g., `for (DLLIterator iter = dll.Begin(); iter != dll.End(); ++iter)`</span>
  <span style="color: #ECBE7B;">DLLIterator</span> <span style="color: #c678dd;">End</span><span style="color: #c678dd;">()</span> <span style="color: #c678dd;">{</span> <span style="color: #51afef;">return</span> DLLIterator<span style="color: #98be65;">(</span><span style="color: #a9a1e1;">nullptr</span><span style="color: #98be65;">)</span>; <span style="color: #c678dd;">}</span>

  <span style="color: #ECBE7B;">Node</span> *<span style="color: #dcaeea;">head_</span><span style="color: #c678dd;">{</span><span style="color: #a9a1e1;">nullptr</span><span style="color: #c678dd;">}</span>;  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">in-class initializers</span>
  <span style="color: #ECBE7B;">size_t</span> <span style="color: #dcaeea;">size_</span>;
<span style="color: #51afef;">}</span>;
</pre>
</div></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgabecb8b" class="outline-2">
<h2 id="orgabecb8b"><span class="section-number-2">4.</span> STL containers</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>The C++ STL (standard library) is a generic collection of data structure and algorithm implementations, e.g., stacks, queues, hash tables.</li>
<li>Each container has own header, e.g., <code>std::vector</code>.</li>
<li>The <code>std::set</code> is implemented as a red-black tree.</li>
</ul>
</div>
<div id="outline-container-org125b0e5" class="outline-3">
<h3 id="org125b0e5"><span class="section-number-3">4.1.</span> Vector</h3>
<div class="outline-text-3" id="text-4-1">
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">algorithm</span><span style="color: #51afef;">&gt;</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to use std::remove_if</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to use std::cout</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">vector</span><span style="color: #51afef;">&gt;</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">A helper class used for vector</span>
<span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">Point</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">public</span>:
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">constructors</span>
  <span style="color: #c678dd;">Point</span><span style="color: #c678dd;">()</span> : x_<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">0</span><span style="color: #c678dd;">)</span>, y_<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">0</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{}</span>
  <span style="color: #c678dd;">Point</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">x</span>, <span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">y</span><span style="color: #c678dd;">)</span> : x_<span style="color: #c678dd;">(</span>x<span style="color: #c678dd;">)</span>, y_<span style="color: #c678dd;">(</span>y<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">inline asks the compiler to substitute the function</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">directly at the calling location instead of performing</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a normal function call, to improve performance for small functions</span>
  <span style="color: #51afef;">inline</span> <span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">GetX</span><span style="color: #c678dd;">()</span> <span style="color: #51afef;">const</span> <span style="color: #c678dd;">{</span> <span style="color: #51afef;">return</span> x_; <span style="color: #c678dd;">}</span>
  <span style="color: #51afef;">inline</span> <span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">SetX</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">x</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span> x_ = x; <span style="color: #c678dd;">}</span>

  <span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">PrintPoint</span><span style="color: #c678dd;">()</span> <span style="color: #51afef;">const</span> <span style="color: #c678dd;">{</span>
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Point: ("</span> &lt;&lt; x_ &lt;&lt; <span style="color: #98be65;">", "</span> &lt;&lt; <span style="color: #98be65;">"y_"</span> &lt;&lt; <span style="color: #98be65;">")\n"</span>;
  <span style="color: #c678dd;">}</span>

<span style="color: #51afef;">private</span>:
  <span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">x_</span>;
  <span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">y_</span>;
<span style="color: #51afef;">}</span>;

<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">vector</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">Point</span><span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">point_vector</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">approach 1 to append to a vector</span>
  point_vector.push_back<span style="color: #c678dd;">(</span>Point<span style="color: #98be65;">(</span><span style="color: #da8548; font-weight: bold;">35</span>, <span style="color: #da8548; font-weight: bold;">36</span><span style="color: #98be65;">)</span><span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">approach 2, pass the argument to Point(x,y) constructor</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">slightly faster than push_back</span>
  point_vector.emplace_back<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">37</span>, <span style="color: #da8548; font-weight: bold;">38</span><span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">iterate through index</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">size_t: unsigned integers specifially used in loop or counting</span>
  <span style="color: #51afef;">for</span> <span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">size_t</span> <span style="color: #dcaeea;">i</span> = <span style="color: #da8548; font-weight: bold;">0</span>; i &lt; point_vector.size<span style="color: #98be65;">()</span>; ++i<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    point_vector<span style="color: #98be65;">[</span>i<span style="color: #98be65;">]</span>.PrintPoint<span style="color: #98be65;">()</span>;
  <span style="color: #c678dd;">}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">iterate through mutable reference</span>
  <span style="color: #51afef;">for</span> <span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">Point</span> &amp;<span style="color: #dcaeea;">item</span> : point_vector<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    item.SetX<span style="color: #98be65;">(</span><span style="color: #da8548; font-weight: bold;">10</span><span style="color: #98be65;">)</span>;
  <span style="color: #c678dd;">}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">iterate through immutable reference</span>
  <span style="color: #51afef;">for</span> <span style="color: #c678dd;">(</span><span style="color: #51afef;">const</span> <span style="color: #ECBE7B;">Point</span> &amp;<span style="color: #dcaeea;">item</span> : point_vector<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    item.GetX<span style="color: #98be65;">()</span>;
  <span style="color: #c678dd;">}</span>

  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">initialize the vector with an initializer list</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">vector</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">int_vector</span> = <span style="color: #c678dd;">{</span><span style="color: #da8548; font-weight: bold;">0</span>, <span style="color: #da8548; font-weight: bold;">1</span>, <span style="color: #da8548; font-weight: bold;">2</span>, <span style="color: #da8548; font-weight: bold;">3</span><span style="color: #c678dd;">}</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">erase element given its index</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">int_vector.begin() returns a std::vector&lt;int&gt;::iterator</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">pointing to the first elemnt in the vector</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the vector iterator has a plus iterator</span>
  int_vector.erase<span style="color: #c678dd;">(</span>int_vector.begin<span style="color: #98be65;">()</span> + <span style="color: #da8548; font-weight: bold;">2</span><span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">{0, 1, 3}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">erase a range of elements</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">int_vector.end() points to the end of a vector (not the last element)</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">and cannot be accessed.</span>
  int_vector.erase<span style="color: #c678dd;">(</span>int_vector.begin<span style="color: #98be65;">()</span> + <span style="color: #da8548; font-weight: bold;">1</span>, int_vector.end<span style="color: #98be65;">()</span><span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">{0}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">erase elements via filtering</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">std::remove_if(range_begin, range_end, condition) returns an iterator</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">pointing to the first element to be erased</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">remove_if() also partitions point_vector so that unsatisfied elements are</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">moved before the point_vector.begin(), i.e., the vector is reordered</span>
  point_vector.erase<span style="color: #c678dd;">(</span>
      <span style="color: #a9a1e1;">std</span>::remove_if<span style="color: #98be65;">(</span>point_vector.begin<span style="color: #a9a1e1;">()</span>, point_vector.end<span style="color: #a9a1e1;">()</span>,
                     <span style="color: #a9a1e1;">[](</span><span style="color: #51afef;">const</span> <span style="color: #ECBE7B;">Point</span> &amp;<span style="color: #dcaeea;">point</span><span style="color: #a9a1e1;">)</span> <span style="color: #a9a1e1;">{</span> <span style="color: #51afef;">return</span> point.GetX<span style="color: #51afef;">()</span> == <span style="color: #da8548; font-weight: bold;">10</span>; <span style="color: #a9a1e1;">}</span><span style="color: #98be65;">)</span>,
      point_vector.end<span style="color: #98be65;">()</span><span style="color: #c678dd;">)</span>;

  <span style="color: #51afef;">return</span> <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgb13b64e" class="outline-3">
<h3 id="orgb13b64e"><span class="section-number-3">4.2.</span> Set</h3>
<div class="outline-text-3" id="text-4-2">
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">set</span><span style="color: #51afef;">&gt;</span>

<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">set</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">int_set</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">can insert element with .insert() or .emplace()</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">.emplace() allows to construct the object in place</span>
  <span style="color: #51afef;">for</span> <span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">i</span> = <span style="color: #da8548; font-weight: bold;">1</span>; i &lt;= <span style="color: #da8548; font-weight: bold;">5</span>; ++i<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    int_set.insert<span style="color: #98be65;">(</span>i<span style="color: #98be65;">)</span>;
  <span style="color: #c678dd;">}</span>
  <span style="color: #51afef;">for</span> <span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">i</span> = <span style="color: #da8548; font-weight: bold;">6</span>; i &lt;= <span style="color: #da8548; font-weight: bold;">10</span>; ++i<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    int_set.emplace<span style="color: #98be65;">(</span>i<span style="color: #98be65;">)</span>;
  <span style="color: #c678dd;">}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">iterate the set</span>
  <span style="color: #51afef;">for</span> <span style="color: #c678dd;">(</span><span style="color: #a9a1e1;">std</span>::<span style="color: #a9a1e1;">set</span><span style="color: #98be65;">&lt;</span><span style="color: #ECBE7B;">int</span><span style="color: #98be65;">&gt;</span>::<span style="color: #ECBE7B;">iterator</span> <span style="color: #dcaeea;">it</span> = int_set.begin<span style="color: #98be65;">()</span>; it != int_set.end<span style="color: #98be65;">()</span>;
       ++it<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; *it &lt;&lt; <span style="color: #98be65;">" "</span>;
  <span style="color: #c678dd;">}</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"\n"</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">.find(key) returns an iterator pointing to the key</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if it is in the set, otherwise returns .end()</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #a9a1e1;">set</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;</span>::<span style="color: #ECBE7B;">iterator</span> <span style="color: #dcaeea;">search</span> = int_set.find<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">2</span><span style="color: #c678dd;">)</span>;
  <span style="color: #51afef;">if</span> <span style="color: #c678dd;">(</span>search != int_set.end<span style="color: #98be65;">()</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"2 is not found\n"</span>;
  <span style="color: #c678dd;">}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">check whether the set contains a key with .count()</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">it returns either 0 or 1 as each key is unique</span>
  <span style="color: #51afef;">if</span> <span style="color: #c678dd;">(</span>int_set.count<span style="color: #98be65;">(</span><span style="color: #da8548; font-weight: bold;">11</span><span style="color: #98be65;">)</span> == <span style="color: #da8548; font-weight: bold;">0</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"11 is not in the set.\n"</span>;
  <span style="color: #c678dd;">}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">erase a key, returns the count of removed elements 0 or 1</span>
  int_set.erase<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">4</span><span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">erase a key given its position, returns the iterator to the next element</span>
  int_set.erase<span style="color: #c678dd;">(</span>int_set.begin<span style="color: #98be65;">()</span><span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">erase a range of elements</span>
  int_set.erase<span style="color: #c678dd;">(</span>int_set.find<span style="color: #98be65;">(</span><span style="color: #da8548; font-weight: bold;">9</span><span style="color: #98be65;">)</span>, int_set.end<span style="color: #98be65;">()</span><span style="color: #c678dd;">)</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org7084f8e" class="outline-3">
<h3 id="org7084f8e"><span class="section-number-3">4.3.</span> Unordered maps</h3>
<div class="outline-text-3" id="text-4-3">
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">string</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">unordered_map</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">utility</span><span style="color: #51afef;">&gt;</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to use std::make_pair</span>

<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unordered_map</span><span style="color: #c678dd;">&lt;</span><span style="color: #a9a1e1;">std</span>::string, <span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">map</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">insert items</span>
  map.insert<span style="color: #c678dd;">(</span><span style="color: #98be65;">{</span><span style="color: #98be65;">"foo"</span>, <span style="color: #da8548; font-weight: bold;">2</span><span style="color: #98be65;">}</span><span style="color: #c678dd;">)</span>;
  map.insert<span style="color: #c678dd;">(</span><span style="color: #98be65;">{</span><span style="color: #a9a1e1;">{</span><span style="color: #98be65;">"bar"</span>, <span style="color: #da8548; font-weight: bold;">1</span><span style="color: #a9a1e1;">}</span>, <span style="color: #a9a1e1;">{</span><span style="color: #98be65;">"eggs"</span>, <span style="color: #da8548; font-weight: bold;">2</span><span style="color: #a9a1e1;">}</span><span style="color: #98be65;">}</span><span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">insert items via pairs</span>
  map.insert<span style="color: #c678dd;">(</span><span style="color: #a9a1e1;">std</span>::make_pair<span style="color: #98be65;">(</span><span style="color: #98be65;">"hello"</span>, <span style="color: #da8548; font-weight: bold;">10</span><span style="color: #98be65;">)</span><span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">insert items in an array-style</span>
  <span style="color: #ECBE7B;">map</span><span style="color: #c678dd;">[</span><span style="color: #98be65;">"world"</span><span style="color: #c678dd;">]</span> = <span style="color: #da8548; font-weight: bold;">3</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">update the value</span>
  <span style="color: #ECBE7B;">map</span><span style="color: #c678dd;">[</span><span style="color: #98be65;">"foo"</span><span style="color: #c678dd;">]</span> = <span style="color: #da8548; font-weight: bold;">9</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">.find() returns an iterator pointing to the item</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">or the end</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #a9a1e1;">unordered_map</span><span style="color: #c678dd;">&lt;</span><span style="color: #a9a1e1;">std</span>::string, <span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;</span>::<span style="color: #ECBE7B;">iterator</span> <span style="color: #dcaeea;">result</span> = map.find<span style="color: #c678dd;">(</span><span style="color: #98be65;">"bar"</span><span style="color: #c678dd;">)</span>;
  <span style="color: #51afef;">if</span> <span style="color: #c678dd;">(</span>result != map.end<span style="color: #98be65;">()</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">one way to access the item</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">both '\n' and std::endl prints newliine, but std::endl</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">also flushes the output buffer, so use '\n' is better</span>
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"key: "</span> &lt;&lt; result-&gt;first &lt;&lt; <span style="color: #98be65;">" value: "</span> &lt;&lt; result-&gt;second
              &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl;
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">another way is dereferencing</span>
    <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">pair</span><span style="color: #98be65;">&lt;</span><span style="color: #a9a1e1;">std</span>::string, <span style="color: #ECBE7B;">int</span><span style="color: #98be65;">&gt;</span> <span style="color: #dcaeea;">pair</span> = *result;
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"key: "</span> &lt;&lt; pair.first &lt;&lt; <span style="color: #98be65;">" value: "</span> &lt;&lt; pair.second
              &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl;
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">check whether a key exists with .count()</span>
    <span style="color: #51afef;">if</span> <span style="color: #98be65;">(</span>map.count<span style="color: #a9a1e1;">(</span><span style="color: #98be65;">"foo"</span><span style="color: #a9a1e1;">)</span> == <span style="color: #da8548; font-weight: bold;">0</span><span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
      <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"foo does not exist\n"</span>;
    <span style="color: #98be65;">}</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">erase an item via a key</span>
    map.erase<span style="color: #98be65;">(</span><span style="color: #98be65;">"world"</span><span style="color: #98be65;">)</span>;
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">or via an iterator</span>
    map.erase<span style="color: #98be65;">(</span>map.find<span style="color: #a9a1e1;">(</span><span style="color: #98be65;">"bar"</span><span style="color: #a9a1e1;">)</span><span style="color: #98be65;">)</span>;
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">can iterate the map via iterator or via for-each</span>
    <span style="color: #51afef;">for</span> <span style="color: #98be65;">(</span><span style="color: #a9a1e1;">std</span>::<span style="color: #a9a1e1;">unordered_map</span><span style="color: #a9a1e1;">&lt;</span><span style="color: #a9a1e1;">std</span>::string, <span style="color: #ECBE7B;">int</span><span style="color: #a9a1e1;">&gt;</span>::<span style="color: #ECBE7B;">iterator</span> <span style="color: #dcaeea;">it</span> = map.begin<span style="color: #a9a1e1;">()</span>;
         it != map.end<span style="color: #a9a1e1;">()</span>; ++it<span style="color: #98be65;">)</span> <span style="color: #98be65;">{</span>
      <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"("</span> &lt;&lt; it-&gt;first &lt;&lt; <span style="color: #98be65;">", "</span> &lt;&lt; it-&gt;second &lt;&lt; <span style="color: #98be65;">"), "</span>;
    <span style="color: #98be65;">}</span>
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"\n"</span>;
  <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org4aebc03" class="outline-2">
<h2 id="org4aebc03"><span class="section-number-2">5.</span> <code>auto</code></h2>
<div class="outline-text-2" id="text-5">
<ul class="org-ul">
<li><code>auto</code> keyword tells the compiler to infer the type via its initialization expression.</li>
</ul>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">vector</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span><span style="color: #51afef;">&lt;</span><span style="color: #98be65;">unordered_map</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span><span style="color: #51afef;">&lt;</span><span style="color: #98be65;">string</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span><span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">create very long class and function</span>
<span style="color: #51afef;">template</span> <span style="color: #51afef;">&lt;</span><span style="color: #51afef;">typename</span> <span style="color: #ECBE7B;">T</span>, <span style="color: #51afef;">typename</span> <span style="color: #ECBE7B;">U</span><span style="color: #51afef;">&gt;</span> <span style="color: #51afef;">class</span> <span style="color: #ECBE7B;">VeryLongTemplateClass</span> <span style="color: #51afef;">{</span>
<span style="color: #51afef;">public</span>:
  <span style="color: #c678dd;">VeryLongTemplateClass</span><span style="color: #c678dd;">(</span><span style="color: #ECBE7B;">T</span> <span style="color: #dcaeea;">instance1</span>, <span style="color: #ECBE7B;">U</span> <span style="color: #dcaeea;">instance2</span><span style="color: #c678dd;">)</span>
      : instance1_<span style="color: #c678dd;">(</span>instance1<span style="color: #c678dd;">)</span>, instance2_<span style="color: #c678dd;">(</span>instance2<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{}</span>

<span style="color: #51afef;">private</span>:
  <span style="color: #ECBE7B;">T</span> <span style="color: #dcaeea;">instance1_</span>;
  <span style="color: #ECBE7B;">U</span> <span style="color: #dcaeea;">instance2_</span>;
<span style="color: #51afef;">}</span>;

<span style="color: #51afef;">template</span> <span style="color: #51afef;">&lt;</span><span style="color: #51afef;">typename</span> <span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #ECBE7B;">VeryLongTemplateClass</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">T</span>, <span style="color: #ECBE7B;">T</span><span style="color: #51afef;">&gt;</span> <span style="color: #c678dd;">construct_obj</span><span style="color: #51afef;">(</span><span style="color: #ECBE7B;">T</span> <span style="color: #dcaeea;">instance</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{</span>
  <span style="color: #51afef;">return</span> VeryLongTemplateClass<span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">T</span>, <span style="color: #ECBE7B;">T</span><span style="color: #c678dd;">&gt;(</span>instance, instance<span style="color: #c678dd;">)</span>;
<span style="color: #51afef;">}</span>

<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #51afef;">auto</span> <span style="color: #dcaeea;">a</span> = <span style="color: #da8548; font-weight: bold;">1</span>;                        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a is int</span>
  <span style="color: #51afef;">auto</span> <span style="color: #dcaeea;">obj1</span> = construct_obj<span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;(</span><span style="color: #da8548; font-weight: bold;">2</span><span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">can infer</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">auto defaults to copy objects rather than taking the reference</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">vector</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">int_values</span> = <span style="color: #c678dd;">{</span><span style="color: #da8548; font-weight: bold;">1</span>, <span style="color: #da8548; font-weight: bold;">2</span>, <span style="color: #da8548; font-weight: bold;">3</span>, <span style="color: #da8548; font-weight: bold;">4</span><span style="color: #c678dd;">}</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a deep-copy happens</span>
  <span style="color: #51afef;">auto</span> <span style="color: #dcaeea;">copy_int_values</span> = int_values;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">this creates a reference</span>
  <span style="color: #51afef;">auto</span> &amp;<span style="color: #dcaeea;">ref_int_values</span> = int_values;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">use auto in the for loop is very common</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unordered_map</span><span style="color: #c678dd;">&lt;</span><span style="color: #a9a1e1;">std</span>::string, <span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">map</span>;
  <span style="color: #51afef;">for</span> <span style="color: #c678dd;">(</span><span style="color: #51afef;">auto</span> <span style="color: #dcaeea;">it</span> = map.begin<span style="color: #98be65;">()</span>; it != map.end<span style="color: #98be65;">()</span>; ++it<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
  <span style="color: #c678dd;">}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">another exmaple</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">vector</span><span style="color: #c678dd;">&lt;</span><span style="color: #ECBE7B;">int</span><span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">vec</span> = <span style="color: #c678dd;">{</span><span style="color: #da8548; font-weight: bold;">1</span>, <span style="color: #da8548; font-weight: bold;">2</span>, <span style="color: #da8548; font-weight: bold;">3</span>, <span style="color: #da8548; font-weight: bold;">4</span><span style="color: #c678dd;">}</span>;
  <span style="color: #51afef;">for</span> <span style="color: #c678dd;">(</span><span style="color: #51afef;">const</span> <span style="color: #51afef;">auto</span> &amp;<span style="color: #dcaeea;">elem</span> : vec<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; elem &lt;&lt; <span style="color: #98be65;">" "</span>;
  <span style="color: #c678dd;">}</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl;
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org9a35959" class="outline-2">
<h2 id="org9a35959"><span class="section-number-2">6.</span> Smart pointers</h2>
<div class="outline-text-2" id="text-6">
<ul class="org-ul">
<li>A smart pointer is a data structure used in languages that do not have built-in memory management (e.g., with garbage collection, e.g., Python, Java) to handle memory allocation and deallocation.</li>
<li><code>std::unique_ptr</code> and <code>std::shared_ptr</code> are two C++ standard library smart pointers, they are wrapper classes over raw pointers.</li>
<li><code>std::unique_ptr</code> retains sole ownership of an object, i.e., no two instances of <code>unique_ptr</code> can manage the same object, a <code>unique_ptr</code> cannot be copied.</li>
<li><code>std::shared_ptr</code> retains shared ownership of an object, i.e., multiple shared pointers can own the same object and can be copied.</li>
</ul>
</div>
<div id="outline-container-org3f34e9b" class="outline-3">
<h3 id="org3f34e9b"><span class="section-number-3">6.1.</span> <code>std::unique_ptr</code></h3>
<div class="outline-text-3" id="text-6-1">
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">memory</span><span style="color: #51afef;">&gt;</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to use std::unique_ptr</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">utility</span><span style="color: #51afef;">&gt;</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to use std::move</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">class Point is the same as before</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">takes in a unique point reference and changes its x value</span>
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">SetXTo10</span><span style="color: #51afef;">(</span><span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> &amp;<span style="color: #dcaeea;">ptr</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{</span> ptr-&gt;SetX<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">10</span><span style="color: #c678dd;">)</span>; <span style="color: #51afef;">}</span>
<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">initialize an empty unique pointer</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">u1</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">initialize a unique pointer with constructors</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">u2</span> = <span style="color: #a9a1e1;">std</span>::make_unique<span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;()</span>;
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">u3</span> = <span style="color: #a9a1e1;">std</span>::make_unique<span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;(</span><span style="color: #da8548; font-weight: bold;">2</span>, <span style="color: #da8548; font-weight: bold;">3</span><span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">can treat a unique pointer as a boolean to determine whether</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the pointer contains data</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Pointer u1 is "</span> &lt;&lt; <span style="color: #c678dd;">(</span>u1 ? <span style="color: #98be65;">"not empty"</span> : <span style="color: #98be65;">"empty"</span><span style="color: #c678dd;">)</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl;
  <span style="color: #51afef;">if</span> <span style="color: #c678dd;">(</span>u2<span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; u2-&gt;GetX<span style="color: #98be65;">()</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl;
  <span style="color: #c678dd;">}</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">unique_ptr has no copy constructor!</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">u4</span> = u3; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">won't compile!</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">can transfer ownership with std::move</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">u5</span> = <span style="color: #a9a1e1;">std</span>::move<span style="color: #c678dd;">(</span>u3<span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">then u3 becomes empty!</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">pass the pointer as a reference so the ownership does not change</span>
  SetXTo10<span style="color: #c678dd;">(</span>u5<span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">can still access u5 afterwards</span>
  <span style="color: #51afef;">return</span> <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>

<ul class="org-ul">
<li>Note that the compiler does not prevent 2 unique pointers from pointing to the same object.</li>
</ul>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #5B6268;">// </span><span style="color: #5B6268;">the following code can compile</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">but it causes a double deletion!</span>
<span style="color: #ECBE7B;">MyClass</span> *<span style="color: #dcaeea;">obj</span> = <span style="color: #51afef;">new</span> <span style="color: #ECBE7B;">MyClass</span><span style="color: #51afef;">()</span>;
<span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_ptr</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">MyClass</span><span style="color: #51afef;">&gt;</span> <span style="color: #c678dd;">ptr1</span><span style="color: #51afef;">(</span>obj<span style="color: #51afef;">)</span>;
<span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_ptr</span><span style="color: #51afef;">&lt;</span><span style="color: #ECBE7B;">MyClass</span><span style="color: #51afef;">&gt;</span> <span style="color: #c678dd;">ptr2</span><span style="color: #51afef;">(</span>obj<span style="color: #51afef;">)</span>;
</pre>
</div>
</div>
</div>
<div id="outline-container-orga6f4d50" class="outline-3">
<h3 id="orga6f4d50"><span class="section-number-3">6.2.</span> <code>std::shared_ptr</code></h3>
<div class="outline-text-3" id="text-6-2">
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">memory</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">utility</span><span style="color: #51afef;">&gt;</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">class Point is the same as before</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">modify a Point inside a shared_ptr by passing the reference</span>
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">modify_ptr_via_ref</span><span style="color: #51afef;">(</span><span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> &amp;<span style="color: #dcaeea;">point</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{</span> point-&gt;SetX<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">10</span><span style="color: #c678dd;">)</span>; <span style="color: #51afef;">}</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">modify a Point inside a shared_ptr by passing the rvalue reference</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">If an object is passed by rvalue reference, one should assume the ownership</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">is moved after the function call, so the original object cannot be used</span>
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">modify_ptr_via_rvalue_ref</span><span style="color: #51afef;">(</span><span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> &amp;&amp;<span style="color: #dcaeea;">point</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{</span>
  point-&gt;SetY<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">11</span><span style="color: #c678dd;">)</span>;
<span style="color: #51afef;">}</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">copy a shared_pointer with the default constructor</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">so one should define own copy constructor and assignment when an object</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">contains pointers</span>
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">copy_shard_ptr_in_function</span><span style="color: #51afef;">(</span><span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">point</span><span style="color: #51afef;">)</span> <span style="color: #51afef;">{</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Use count of the shared pointer: "</span> &lt;&lt; point.use_count<span style="color: #c678dd;">()</span>
            &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">add by 1</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the copy is destroyed at the end, so the count is decremented</span>
<span style="color: #51afef;">}</span>

<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the pointer constructors are the same as unique_ptr</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">s1</span>;
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">s2</span> = <span style="color: #a9a1e1;">std</span>::make_shared<span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;()</span>;
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">s3</span> = <span style="color: #a9a1e1;">std</span>::make_shared<span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;(</span><span style="color: #da8548; font-weight: bold;">2</span>, <span style="color: #da8548; font-weight: bold;">3</span><span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">copy a shared pointer via copy assignment or copy constructor</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">increment the reference count, which can be tracked by .use_count</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Use count of s3"</span> &lt;&lt; s3.use_count<span style="color: #c678dd;">()</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">1</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">s4</span> = s3; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">copy assignment</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Use count of s3"</span> &lt;&lt; s3.use_count<span style="color: #c678dd;">()</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">2</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">s5</span><span style="color: #c678dd;">(</span>s4<span style="color: #c678dd;">)</span>;
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Use count of s3"</span> &lt;&lt; s3.use_count<span style="color: #c678dd;">()</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">3</span>
  s3-&gt;SetX<span style="color: #c678dd;">(</span><span style="color: #da8548; font-weight: bold;">100</span><span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">also changes the data in s4 and s5</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_ptr</span><span style="color: #c678dd;">&lt;</span>Point<span style="color: #c678dd;">&gt;</span> <span style="color: #dcaeea;">s6</span> = <span style="color: #a9a1e1;">std</span>::move<span style="color: #c678dd;">(</span>s5<span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">s5 transfer the ownership to s6</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Use count of s3"</span> &lt;&lt; s3.use_count<span style="color: #c678dd;">()</span>
            &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">still 3: s3, s4, s6</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">as unique_ptr, shared_ptr can be passed by references and rvalue references</span>
  modify_ptr_via_ref<span style="color: #c678dd;">(</span>s2<span style="color: #c678dd;">)</span>;                   <span style="color: #5B6268;">// </span><span style="color: #5B6268;">setX(11)</span>
  modify_ptr_via_rvalue_ref<span style="color: #c678dd;">(</span><span style="color: #a9a1e1;">std</span>::move<span style="color: #98be65;">(</span>s2<span style="color: #98be65;">)</span><span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">setY(12)</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"s2.x = "</span> &lt;&lt; s2-&gt;GetX<span style="color: #c678dd;">()</span>
            &lt;&lt; <span style="color: #98be65;">" , s2.y = "</span> &lt;&lt; s2-&gt;GetY<span style="color: #c678dd;">()</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">(11, 12)</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">shared_ptr can also be passed by value/copy</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Use count of s2"</span> &lt;&lt; s2.use_count<span style="color: #c678dd;">()</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">1</span>
  copy_shared_ptr_in_function<span style="color: #c678dd;">(</span>s2<span style="color: #c678dd;">)</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">inside the function, the use count is 2</span>
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Use count of s2"</span> &lt;&lt; s2.use_count<span style="color: #c678dd;">()</span>
            &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">1 again as the copy is detroyed</span>
  <span style="color: #51afef;">return</span> <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org0b2f277" class="outline-2">
<h2 id="org0b2f277"><span class="section-number-2">7.</span> Synchronization</h2>
<div class="outline-text-2" id="text-7">
</div>
<div id="outline-container-org2b7c7db" class="outline-3">
<h3 id="org2b7c7db"><span class="section-number-3">7.1.</span> <code>std::mutex</code></h3>
<div class="outline-text-3" id="text-7-1">
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">mutex</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">thread</span><span style="color: #51afef;">&gt;</span>

<span style="color: #5B6268;">// </span><span style="color: #5B6268;">define a global variable to be modified</span>
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">by multiple threads</span>
<span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">count</span> = <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">declare a mutex</span>
<span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">mutex</span> <span style="color: #dcaeea;">m</span>;
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">add_count</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  m.lock<span style="color: #c678dd;">()</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">acquire the lock</span>
  count += <span style="color: #da8548; font-weight: bold;">1</span>;
  m.unlock<span style="color: #c678dd;">()</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">release the lock</span>
<span style="color: #51afef;">}</span>
<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">thread</span> <span style="color: #dcaeea;">t1</span><span style="color: #c678dd;">(</span>add_count<span style="color: #c678dd;">)</span>;
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">thread</span> <span style="color: #dcaeea;">t2</span><span style="color: #c678dd;">(</span>add_count<span style="color: #c678dd;">)</span>;
  t1.join<span style="color: #c678dd;">()</span>;
  t2.join<span style="color: #c678dd;">()</span>;
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; count &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">always 2</span>
  <span style="color: #51afef;">return</span> <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgace0084" class="outline-3">
<h3 id="orgace0084"><span class="section-number-3">7.2.</span> <code>std::scoped_lock</code></h3>
<div class="outline-text-3" id="text-7-2">
<ul class="org-ul">
<li>A mutex wrapper that provides a RAII-style of obtaining and releasing the lock.</li>
<li>When the object is constructed, the locks are acquired; when the object is destructured, the locks are released.</li>
<li>Better than <code>std::mutex</code> since it provides exception safety.</li>
</ul>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">mutex</span><span style="color: #51afef;">&gt;</span>

<span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">count</span> = <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">mutex</span> <span style="color: #dcaeea;">m</span>;
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">add_count</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the scoped_lock constructor allows for the thread</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to acquire the mutex m</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">scoped_lock</span> <span style="color: #dcaeea;">slk</span><span style="color: #c678dd;">(</span>m<span style="color: #c678dd;">)</span>;
  count += <span style="color: #da8548; font-weight: bold;">1</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">once the function finishes, slk is destructurd and</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">m is released</span>
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org00ab3e7" class="outline-3">
<h3 id="org00ab3e7"><span class="section-number-3">7.3.</span> <code>std::condition_variable</code></h3>
<div class="outline-text-3" id="text-7-3">
<ul class="org-ul">
<li>Allow threads to wait until a particular condition before acquiring a mutex.</li>
<li>Allow other threads to signal waiting threads to alert them that the condition may be true.
<code>notify_one</code></li>
</ul>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">condition_variable</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">mutex</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">thread</span><span style="color: #51afef;">&gt;</span>

<span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">count</span> = <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">mutex</span> <span style="color: #dcaeea;">m</span>;
<span style="color: #5B6268;">// </span><span style="color: #5B6268;">declare a condition variable</span>
<span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">condition_variable</span> <span style="color: #dcaeea;">cv</span>;
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">add_count_and_notify</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">scoped_lock</span> <span style="color: #dcaeea;">slk</span><span style="color: #c678dd;">(</span>m<span style="color: #c678dd;">)</span>;
  count += <span style="color: #da8548; font-weight: bold;">1</span>;
  <span style="color: #51afef;">if</span> <span style="color: #c678dd;">(</span>count == <span style="color: #da8548; font-weight: bold;">2</span><span style="color: #c678dd;">)</span> <span style="color: #c678dd;">{</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">notidy one waiting thread</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">otherwise the waiter thread hangs forever</span>
    cv.notify_one<span style="color: #98be65;">()</span>;
  <span style="color: #c678dd;">}</span>
<span style="color: #51afef;">}</span>
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">waiter_thread</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a unique_lock is movable but not copiable</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">more flexible than scoped_lock as it can unlock</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">and relock manually, while scoped_lock can only be</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">unlocked automatically.</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">scoped_lock cannot be used with condition variables</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_lock</span> <span style="color: #dcaeea;">lk</span><span style="color: #c678dd;">(</span>m<span style="color: #c678dd;">)</span>;
  cv.wait<span style="color: #c678dd;">(</span>lk, <span style="color: #98be65;">[]</span> <span style="color: #98be65;">{</span> <span style="color: #51afef;">return</span> count == <span style="color: #da8548; font-weight: bold;">2</span>; <span style="color: #98be65;">}</span><span style="color: #c678dd;">)</span>;
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; count &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl;
<span style="color: #51afef;">}</span>
<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">thread</span> <span style="color: #dcaeea;">t1</span><span style="color: #c678dd;">(</span>waiter_thread<span style="color: #c678dd;">)</span>;
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">make t1 really waits</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #a9a1e1;">this_thread</span>::sleep_for<span style="color: #c678dd;">(</span><span style="color: #a9a1e1;">std</span>::<span style="color: #a9a1e1;">chrono</span>::milliseconds<span style="color: #98be65;">(</span><span style="color: #da8548; font-weight: bold;">100</span><span style="color: #98be65;">)</span><span style="color: #c678dd;">)</span>;
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">thread</span> <span style="color: #dcaeea;">t2</span><span style="color: #c678dd;">(</span>add_count_and_notify<span style="color: #c678dd;">)</span>;
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">thread</span> <span style="color: #dcaeea;">t3</span><span style="color: #c678dd;">(</span>add_count_and_notify<span style="color: #c678dd;">)</span>;
  t1.join<span style="color: #c678dd;">()</span>;
  t2.join<span style="color: #c678dd;">()</span>;
  t3.join<span style="color: #c678dd;">()</span>;
  <span style="color: #51afef;">return</span> <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #51afef;">}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org4f057cc" class="outline-3">
<h3 id="org4f057cc"><span class="section-number-3">7.4.</span> Reader-writer lock</h3>
<div class="outline-text-3" id="text-7-4">
<ul class="org-ul">
<li>A reader-writer lock allows multiple threads to have shared read access (no writers are allowed during read operations) and exclusive write access, i.e., no other readers or writers are allowed during the write.</li>
<li>C++ does not have a specific reader-writer&rsquo;s lock library, but can be emulated with <code>std::shared_mutex</code>, <code>std::shared_lock</code> and <code>std::unique_lock</code>.</li>
<li><code>std::shared_mutex</code> is a mutex that allows for both shared read-only locking and exclusive write-only locking.</li>
<li><code>std::shared_lock</code> can be used as an RAII-style read lock.</li>
<li><p>
<code>std::unique_lock</code> can be used a RAII-style exclusive write lock.
</p>
<div class="org-src-container">
<pre class="src src-cpp"><span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">iostream</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">mutex</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">shared_mutex</span><span style="color: #51afef;">&gt;</span>
<span style="color: #51afef; font-weight: bold;">#include</span> <span style="color: #51afef;">&lt;</span><span style="color: #98be65;">thread</span><span style="color: #51afef;">&gt;</span>

<span style="color: #ECBE7B;">int</span> <span style="color: #dcaeea;">count</span> = <span style="color: #da8548; font-weight: bold;">0</span>; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">resource</span>
<span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_mutex</span> <span style="color: #dcaeea;">m</span>;
<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">read_value</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">use shared_lock to gain read-only, shared access</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">shared_lock</span> <span style="color: #dcaeea;">lk</span><span style="color: #c678dd;">(</span>m<span style="color: #c678dd;">)</span>;
  <span style="color: #a9a1e1;">std</span>::cout &lt;&lt; <span style="color: #98be65;">"Reading "</span> + <span style="color: #a9a1e1;">std</span>::to_string<span style="color: #c678dd;">(</span>count<span style="color: #c678dd;">)</span> &lt;&lt; <span style="color: #a9a1e1;">std</span>::endl;
<span style="color: #51afef;">}</span>

<span style="color: #ECBE7B;">void</span> <span style="color: #c678dd;">write_value</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">use unique_lock to gain exclusive access</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">unique_lock</span> <span style="color: #dcaeea;">lk</span><span style="color: #c678dd;">(</span>m<span style="color: #c678dd;">)</span>;
  count += <span style="color: #da8548; font-weight: bold;">3</span>;
<span style="color: #51afef;">}</span>
<span style="color: #ECBE7B;">int</span> <span style="color: #c678dd;">main</span><span style="color: #51afef;">()</span> <span style="color: #51afef;">{</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">since all 3 threads run in parallel,</span>
  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the output is not deterministic</span>
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">thread</span> <span style="color: #dcaeea;">t1</span><span style="color: #c678dd;">(</span>read_value<span style="color: #c678dd;">)</span>;
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">thread</span> <span style="color: #dcaeea;">t2</span><span style="color: #c678dd;">(</span>write_value<span style="color: #c678dd;">)</span>;
  <span style="color: #a9a1e1;">std</span>::<span style="color: #ECBE7B;">thread</span> <span style="color: #dcaeea;">t3</span><span style="color: #c678dd;">(</span>read_value<span style="color: #c678dd;">)</span>;
  t1.join<span style="color: #c678dd;">()</span>;
  t2.join<span style="color: #c678dd;">()</span>;
  t3.join<span style="color: #c678dd;">()</span>;
  <span style="color: #51afef;">return</span> <span style="color: #da8548; font-weight: bold;">0</span>;
<span style="color: #51afef;">}</span>
</pre>
</div></li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-c++.html">c++</a> <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-cmu.html">cmu</a> </div>]]></description>
  <category><![CDATA[c++]]></category>
  <category><![CDATA[study]]></category>
  <category><![CDATA[cmu]]></category>
  <link>https://chenyo.me/2024-09-24-cpp-feature-introduction.html</link>
  <guid>https://chenyo.me/2024-09-24-cpp-feature-introduction.html</guid>
  <pubDate>Tue, 24 Sep 2024 11:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Build a free Telegram sticker tag bot]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgc861b35">1. What happened</a></li>
<li><a href="#orgfd6d509">2. What do I need</a></li>
<li><a href="#orge256bde">3. How to build a bot</a>
<ul>
<li><a href="#org9cd67f8">3.1. How to build a sticker tag bot</a></li>
<li><a href="#org2dd28c4">3.2. How to make the bot private</a></li>
</ul>
</li>
<li><a href="#org445c8e2">4. How to deploy the bot on Render</a></li>
<li><a href="#orge5152d6">5. How to connect to the Firebase</a></li>
<li><a href="#orgc70c80e">6. How to configure UptimeRobot</a></li>
<li><a href="#org6e130c1">7. Conclusion</a></li>
</ul>
</div>
</nav>
<div id="outline-container-orgc861b35" class="outline-2">
<h2 id="orgc861b35"><span class="section-number-2">1.</span> What happened</h2>
<div class="outline-text-2" id="text-1">
<p>
When I started to use Telegram, I really missed being able to search stickers by text, like I can in WeChat.
Sadly, Telegram only lets you search emojis by text, or find stickers using emojis.
</p>

<p>
After digging around, I discovered the easiest way to add this cool feature was through Telegram bots.
The idea? Store a tag-to-sticker map in the bot, then fetch all matching stickers when given a tag in the bot&rsquo;s <a href="https://core.telegram.org/bots/inline">inline mode</a>.
There are a few sticker tag bots on Telegram already, but they&rsquo;re either dead or <a href="https://github.com/vitaly-rudenko/tag-sticker-bot">can&rsquo;t handle</a> Unicode input like Chinese characters.
Plus, I&rsquo;m not super keen on trusting my data to someone else&rsquo;s database.
Moreover, I might want to use a bot for other personal stuff later.
</p>

<p>
So, I decided to build my own Telegram bot.
</p>
</div>
</div>
<div id="outline-container-orgfd6d509" class="outline-2">
<h2 id="orgfd6d509"><span class="section-number-2">2.</span> What do I need</h2>
<div class="outline-text-2" id="text-2">
<p>
My goal was to create a bot using only free services, including cloud storage for key-value pairs and a hosting platform to keep the bot running.
</p>

<p>
I stumbled upon <a href="https://render.com">Render</a> from an X recommendation which offers <a href="https://docs.render.com/free#monthly-usage-limits">750 hours per month</a> for free deployment (which equals 31 days), so I deployed my bot there once I got the bot running locally.
But then I found out Render&rsquo;s free tier doesn&rsquo;t offer permanent storage and shuts down services after <a href="https://docs.render.com/free#spinning-down-on-idle">15 minutes of inactivity</a>.
</p>

<p>
A sticker tag bot without memory isn&rsquo;t much use to anyone, so I went hunting for free cloud storage.
With some help from Claude and Perplexity, I discovered <a href="https://firebase.google.com/products/realtime-database/">Firebase Realtime database</a>, which offers 1GB storage and 10GB throughput per month on its <a href="https://firebase.google.com/pricing">free tier</a>.
</p>

<p>
Even with cloud storage, a bot that konks out every 15 minutes just won&rsquo;t cut it - I need my stickers now!
So my next quest was finding a way to keep the bot awake, which led me to <a href="https://uptimerobot.com">UptimeRobot</a>.
It&rsquo;s actually a web monitoring tool, but I can use it to ping the bot regularly, tricking it into staying &ldquo;active&rdquo; instead of dozing off.
</p>

<p>
So, to sum it up, building this sticker tag bot required:
</p>
<ul class="org-ul">
<li>a Telegram bot from <a href="https://t.me/botfather">BotFather</a>,</li>
<li>a free Render deployment,</li>
<li>a Firebase&rsquo;s free key-value storage, and</li>
<li>an UptimeRobot&rsquo;s free monitoring service.</li>
</ul>

<p>
However, these services do not work together automatically. Gluing them together required additional effort.
</p>
</div>
</div>
<div id="outline-container-orge256bde" class="outline-2">
<h2 id="orge256bde"><span class="section-number-2">3.</span> How to build a bot</h2>
<div class="outline-text-2" id="text-3">
<p>
The first step in building any bot is asking BotFather for a new bot and keeping the bot token secure.
Telegram offers a helpful <a href="https://core.telegram.org/bots/tutorial#executing-commands">tutorial</a> that explains the process using Java.
Examples in other languages can be found in their <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.go">Gitlab repo</a>.
In my opinion, the most challenging part here is creating a unique bot username that is still available.
</p>

<p>
The next step involves working with the <a href="https://core.telegram.org/bots/api">Telegram bot API</a> in the chosen programming language.
This includes learning how to handle messages effectively.
For example, I used <a href="https://github.com/go-telegram-bot-api/telegram-bot-api">tgbotapi(Golang)</a>.
</p>
</div>
<div id="outline-container-org9cd67f8" class="outline-3">
<h3 id="org9cd67f8"><span class="section-number-3">3.1.</span> How to build a sticker tag bot</h3>
<div class="outline-text-3" id="text-3-1">
<p>
A sticker tag bot needs two main functionalities:
</p>
<ul class="org-ul">
<li>Handle direct messages to add new sticker tags.</li>
<li>Handle inline queries to search for stickers using a given tag.</li>
</ul>

<p>
To implement the first functionality, I created a simple state machine with two states:
</p>
<ol class="org-ol">
<li>The initial state waits for a sticker input and then moves to the tag state.</li>
<li>The tag state waits for any text input to use as the tag for the previous sticker.</li>
</ol>

<p>
To implement the second functionality, one needs to use the <a href="https://core.telegram.org/bots/api#inlinequeryresultcachedsticker">InlineQueryResultCachedSticker</a> method.
</p>

<p>
For local testing, one can use a lightweight local key-value storage to store and search sticker tags.
I used <a href="https://github.com/dgraph-io/badger">BadgerDB(Golang)</a> for example.
</p>

<p>
I noticed that the generated file ID for the same sticker is different each time, making it hard to check for duplicates when adding new tags.
To address this, I added a <code>/delete</code> method to remove tags when needed.
</p>
</div>
</div>
<div id="outline-container-org2dd28c4" class="outline-3">
<h3 id="org2dd28c4"><span class="section-number-3">3.2.</span> How to make the bot private</h3>
<div class="outline-text-3" id="text-3-2">
<p>
I couldn&rsquo;t find an official way to make a bot visible only to me.
Suggested by Claude, I predefined a list of authorized users.
Then I performed a sanity check before handling any messages.
</p>
</div>
</div>
</div>
<div id="outline-container-org445c8e2" class="outline-2">
<h2 id="org445c8e2"><span class="section-number-2">4.</span> How to deploy the bot on Render</h2>
<div class="outline-text-2" id="text-4">
<p>
Deploying a service on Render with a free account is challenging due to the lack of shell access, disk access, and non-so-live logs.
The process of making everything work at this stage was time-consuming and I even contacted Render&rsquo;s technical support although they only responded &ldquo;Ok I will close the ticket&rdquo; after the issue was self-resolved.
</p>

<p>
Three main steps are required here:
</p>
<ol class="org-ol">
<li>start an HTTP server with several endpoints at the bot, and</li>
<li>configure the web service and environment variables on Render&rsquo;s dashboard,</li>
<li>configure the <a href="https://blog.domotz.com/product-bytes/telegram-webhook-and-bot-api/">Telegram webhook</a> at the bot.</li>
</ol>

<p>
In step 1, starting an HTTP server at <code>0.0.0.0:&lt;some-port&gt;</code> is necessary.
One should also enable GET methods for the root and a health check endpoint to allow Render to scan the service regularly.
</p>

<p>
In step 2, one needs to fill in the service configuration and environment variables in different boxes.
This includes settings such as port, build command, and health check endpoint.
The issue I encountered was Render could not scan any port even if I have triple-checked that everything worked fine locally.
In the end, I solved this issue by adding the Golang build tag <code>-tags netgo</code> in the build command.
Actually this flag was configured by default, but I initially replaced it with a simpler build command.
</p>

<p>
In step 3, one needs to configure the webhook with the Bot API and to enable the POST method for the webhook at the HTTP server (this can also be handled by the Bot API).
The webhook can be <code>https: //&lt;your project&gt;.onrender.com/&lt;your-token&gt;</code> (or another unique URL).
This URL informs Telegram where to send and receive all messages for the bot.
</p>
</div>
</div>
<div id="outline-container-orge5152d6" class="outline-2">
<h2 id="orge5152d6"><span class="section-number-2">5.</span> How to connect to the Firebase</h2>
<div class="outline-text-2" id="text-5">
<p>
The Firebase Realtime database stores key-value pairs in the JSON format.
Connecting the bot with the database requires the following steps:
</p>
<ol class="org-ol">
<li>Create the app and the database on Firebase&rsquo;s dashboard.
Specifically, one needs to store the following 3 values for interaction:
<ul class="org-ul">
<li>The database URL, which looks like <code>https: //&lt;your-app&gt;-default-rtdb.*.firebasedatabase.app</code>.</li>
<li>The credential file, which can be downloaded at <code>Project settings-&gt;Service accounts-&gt;Firebase Admin SDK</code> (and should also be added to Render).</li>
</ul></li>
<li>Import the language-specific Firebase API to configure the database in the bot.
For example, I use <a href="https://pkg.go.dev/firebase.google.com/go/v4">firebase(Golang)</a>.</li>
<li>Update the database rules in Firebase dashboard to only allow authorized writes for specific tags, e.g., one name/path to refer to those key-value pairs.</li>
</ol>

<p>
It&rsquo;s worth noting that connecting to the database on Render may take some time after a fresh start.
During this initialization period, the log may display a <code>502 Bad Gateway</code> error to the database.
</p>
</div>
</div>
<div id="outline-container-orgc70c80e" class="outline-2">
<h2 id="orgc70c80e"><span class="section-number-2">6.</span> How to configure UptimeRobot</h2>
<div class="outline-text-2" id="text-6">
<p>
Before configuring UptimeRobot, an attempt was made to ping the bot from within itself, but this approach did not function for Render.
</p>

<p>
Using UptimeRobot to maintain the bot&rsquo;s active status involves two primary steps:
</p>
<ol class="org-ol">
<li>Enable the HEAD method (the sole method available for a free account) for any endpoint on the HTTP server.</li>
<li>Configure an HTTP(S) monitor for that endpoint, which appears as <code>&lt;you-project&gt;.onrender.com/&lt;endpoint&gt;</code>, and establish the monitoring interval to less than 15 minutes.</li>
</ol>
</div>
</div>
<div id="outline-container-org6e130c1" class="outline-2">
<h2 id="org6e130c1"><span class="section-number-2">7.</span> Conclusion</h2>
<div class="outline-text-2" id="text-7">
<p>
This post isn&rsquo;t meant to be a step-by-step guide for building a Telegram bot.
It skips some steps and doesn&rsquo;t include screenshots.
But don&rsquo;t worry, most of the missing bits can be figured out using AI language models these days.
The rest really depends on each specific situation.
The main point here is to show how to set up a free small web service, even when there&rsquo;s no single platform that does it all.
</p>

<p>
When I first wrote this, my bot had been up and running for 10 days.
It only had 30 minutes of downtime, which I think happened because UptimeRobot couldn&rsquo;t reach Render&rsquo;s IP address during that time.
</p>

<p>
Right now, the repository is private since I plan to add a second functionality to the bot soon.
</p>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-tool.html">tool</a> <a href="https://chenyo.me/tag-telegram.html">telegram</a> </div>]]></description>
  <category><![CDATA[tool]]></category>
  <category><![CDATA[telegram]]></category>
  <link>https://chenyo.me/2024-09-08-build-a-free-telegram-sticker-bot.html</link>
  <guid>https://chenyo.me/2024-09-08-build-a-free-telegram-sticker-bot.html</guid>
  <pubDate>Sun, 08 Sep 2024 17:01:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Install Doom Emacs with Lisp native compilation in WSL2]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orge91b227">1. Assumptions</a></li>
<li><a href="#org8201261">2. Install prerequisite packages</a></li>
<li><a href="#orgda5f7b6">3. Install Emacs 29.4</a>
<ul>
<li><a href="#org244f9bd">3.1. Before building</a></li>
<li><a href="#org3ef3440">3.2. Build Emacs 29.4 with native-comp</a></li>
</ul>
</li>
<li><a href="#org2281547">4. Install <code>ripgrep</code></a></li>
<li><a href="#org0af8d00">5. Install Doom Emacs</a></li>
<li><a href="#org4a4cfc4">6. Some issues with running Emacs in WSL2</a></li>
</ul>
</div>
</nav>
<p>
Today I installed Doom Emacs for my husband on his WSL2.
Although the entire process was guided by Claude, there were some back-and-forth during the interaction.
Therefore I would like to record the full commands I have used here in sequence for any potential reference.
</p>
<div id="outline-container-orge91b227" class="outline-2">
<h2 id="orge91b227"><span class="section-number-2">1.</span> Assumptions</h2>
<div class="outline-text-2" id="text-1">
<p>
This installation guide assumes a fresh installation of WSL2 Ubuntu 22.04 on Windows 11 in 2024 September.
</p>
</div>
</div>
<div id="outline-container-org8201261" class="outline-2">
<h2 id="org8201261"><span class="section-number-2">2.</span> Install prerequisite packages</h2>
<div class="outline-text-2" id="text-2">
<p>
According to the Doom Emacs <a href="https://github.com/doomemacs/doomemacs#prerequisites">documentation</a>, the following packages are recommended:
</p>
<ul class="org-ul">
<li>Git 2.23+: this is already installed by default.</li>
<li>Emacs 29.4 with <a href="https://www.emacswiki.org/emacs/GccEmacs">Lisp native compilation</a>: this is finicky and will be elaborated later.</li>
<li>ripgrep 14.0+: the documentation says 11.0+ suffices, but <code>doom doctor</code> still complains the latest version (13.0) installed from <code>apt</code> is not advanced, so we need to install it from its Github released package later.</li>
<li>GNU find: also installed already.</li>
<li>fd: <code>sudo apt install fd-find</code> suffices.</li>
</ul>
</div>
</div>
<div id="outline-container-orgda5f7b6" class="outline-2">
<h2 id="orgda5f7b6"><span class="section-number-2">3.</span> Install Emacs 29.4</h2>
<div class="outline-text-2" id="text-3">
</div>
<div id="outline-container-org244f9bd" class="outline-3">
<h3 id="org244f9bd"><span class="section-number-3">3.1.</span> Before building</h3>
<div class="outline-text-3" id="text-3-1">
<p>
First, let&rsquo;s install some build dependencies:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">sudo</span> apt update
<span style="color: #ECBE7B;">sudo</span> apt upgrade  <span style="color: #5B6268;"># </span><span style="color: #5B6268;">update packages</span>
<span style="color: #ECBE7B;">sudo</span> apt install build-essential libjansson4 libjansson-dev <span style="color: #98be65;">\</span>
    libgnutls28-dev libtree-sitter-dev libsqlite3-dev
<span style="color: #ECBE7B;">sudo</span> apt install texinfo  <span style="color: #5B6268;"># </span><span style="color: #5B6268;">to generate documentation</span>
</pre>
</div>

<p>
<code>build-essnetial</code> should install necessary tools to build C/C++ programs such as gcc, g++, make, gdb and dpkg.
The rest packages install pre-compiled libraries.
</p>

<p>
Besides these packages, there are two important packages to support Lisp native compilation:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">sudo</span> apt install ibgccjit0 libgccjit-11-dev  <span style="color: #5B6268;"># </span><span style="color: #5B6268;">11 is my gcc version</span>
</pre>
</div>

<p>
After installing them, make sure to export the path in the current session, otherwise the compiler will not realize it.
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #c678dd;">export</span> <span style="color: #dcaeea;">LD_LIBRARY_PATH</span>=/usr/lib/gcc/x86_64-linux-gnu/11:$<span style="color: #dcaeea;">LD_LIBRARY_PATH</span>
</pre>
</div>

<p>
The last thing to do is install a bunch of X and GTK-3 development libraries for Emacs GUI, and another bunch of image processing libraries.
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">sudo</span> apt install libx11-dev libtiff-dev libgtk-3-dev libncurses-dev
<span style="color: #ECBE7B;">sudo</span> apt install libtiff5-dev libgif-dev libjpeg-dev libpng-dev libxpm-dev
</pre>
</div>

<p>
Without the above packages, one may encounter the following error when configuring the Emacs build:
</p>

<blockquote>
<p>
You seem to be running X, but no X development libraries
were found.  You should install the relevant development files for X
and for the toolkit you want, such as Gtk+ or Motif. Also make
sure you have development files for image handling, i.e.
tiff, gif, jpeg, png and xpm.
</p>
</blockquote>
</div>
</div>
<div id="outline-container-org3ef3440" class="outline-3">
<h3 id="org3ef3440"><span class="section-number-3">3.2.</span> Build Emacs 29.4 with native-comp</h3>
<div class="outline-text-3" id="text-3-2">
<p>
At this moment, we can start to download Emacs source code:
</p>

<div class="org-src-container">
<pre class="src src-bash">wget https://ftp.gnu.org/gnu/emacs/emacs-29.4.tar.xz
tar xvf emacs-29.4.tar.xz
<span style="color: #ECBE7B;">cd</span> emacs-29.4
</pre>
</div>

<p>
Then we can configure the build (i.e., generate Makefile) with the following command.
</p>

<div class="org-src-container">
<pre class="src src-bash">./configure --with-native-compilation --with-x-toolkit=gtk3 --without-pop
</pre>
</div>

<ul class="org-ul">
<li><code>--with-native-compilation</code>: with this flag the Emacs source code is compiled to native machine code to achieve better performance.
<ul class="org-ul">
<li>Otherwise it is compiled to bytecode and then interpreted by Emacs virtual machine during runtime.</li>
</ul></li>
<li><code>--with-x-toolkit=gtk3</code>: this is recommended by Claude.</li>
<li><code>--without-pop</code>: if we are not using Emacs as the email client, we don&rsquo;t need to bother configure the protocol.</li>
</ul>

<p>
If everything goes well, one should see the following line in the output.
If not, make sure <code>libgccjit</code> has been installed and exported.
</p>

<blockquote>
<p>
Does Emacs have native lisp compiler? yes
</p>
</blockquote>

<p>
Now we can finally start compiling the Emacs:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">make</span> -j$<span style="color: #51afef;">(</span>nproc<span style="color: #51afef;">)</span>
</pre>
</div>

<p>
If some error occurs, we may want to start again, to do this:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">sudo</span> apt install autoconf automake
<span style="color: #ECBE7B;">rm</span> -f Makefile
./autogen.sh  <span style="color: #5B6268;"># </span><span style="color: #5B6268;">regenerate the configuration file</span>
<span style="color: #5B6268;"># </span><span style="color: #5B6268;">then rebuild</span>
<span style="color: #ECBE7B;">make</span> -j$<span style="color: #51afef;">(</span>nproc<span style="color: #51afef;">)</span>
</pre>
</div>

<p>
Finally, install Emacs globally:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">sudo</span> <span style="color: #ECBE7B;">make</span> install
</pre>
</div>

<p>
To confirm the Emacs indeed used the native Lisp compiler, one can evaluate inside the vanilla Emacs with <code>M-:</code> (<code>M</code> is <code>Alt</code> in WSL2):
</p>

<div class="org-src-container">
<pre class="src src-lisp">(native-comp-available-p) <span style="color: #5B6268;">;; </span><span style="color: #5B6268;">should return t</span>
</pre>
</div>

<p>
Congratulations! You have now installed the latest and fastest Emacs on WSL2.
</p>
</div>
</div>
</div>
<div id="outline-container-org2281547" class="outline-2">
<h2 id="org2281547"><span class="section-number-2">4.</span> Install <code>ripgrep</code></h2>
<div class="outline-text-2" id="text-4">
<p>
As mentioned in ripgrep <a href="https://github.com/BurntSushi/ripgrep?tab=readme-ov-file#installation">documentation</a>, for Debian/Ubuntu users, one should
install the latest ripgrep 14.0+ with the following commands.
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">curl</span> -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep_14.1.0-1_amd64.deb  <span style="color: #5B6268;"># </span><span style="color: #5B6268;">check the latest version on its documentation</span>
<span style="color: #ECBE7B;">sudo</span> dpkg -i ripgrep_14.1.0-1_amd64.deb  <span style="color: #5B6268;"># </span><span style="color: #5B6268;">dpkg has been installed before</span>
</pre>
</div>

<p>
Instead, if one installs it with <code>apt</code>, a 13.0+ version is installed and running <code>doom doctor</code> later returns the warning:
</p>

<blockquote>
<p>
The installed ripgrep binary was not built with support for PCRE lookaheads.
</p>
</blockquote>
</div>
</div>
<div id="outline-container-org0af8d00" class="outline-2">
<h2 id="org0af8d00"><span class="section-number-2">5.</span> Install Doom Emacs</h2>
<div class="outline-text-2" id="text-5">
<p>
Installing Doom Emacs is straightforward, but before that, one should first remove the default Emacs configuration folder:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">rm</span> -rf ~/.emacs.d
</pre>
</div>

<p>
Then, clone and install Doom Emacs, it could take a while.
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">git</span> clone --depth <span style="color: #da8548; font-weight: bold;">1</span> https://github.com/doomemacs/doomemacs ~/.config/emacs
~/.config/emacs/bin/doom install
</pre>
</div>

<p>
Don&rsquo;t forget to export <code>~/.config/emacs/bin</code> to <code>PATH</code>:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ECBE7B;">echo</span> <span style="color: #98be65;">'export PATH="$HOME/.config/emacs/bin:$PATH"'</span> &gt;&gt; ~/.bashrc
<span style="color: #c678dd;">source</span> ~/.bashrc
</pre>
</div>

<p>
Now one can run <code>doom doctor</code> to check any missing dependencies, e.g., <code>shellcheck</code>.
One common issue is the Nerd font is not installed by default so that some icons are not properly displayed.
To fix that, run <code>M-x nerd-icons-install-font</code> inside the Emacs, then update the font cache with:
</p>

<div class="org-src-container">
<pre class="src src-bash">fc-cache -fv
<span style="color: #5B6268;"># </span><span style="color: #5B6268;">fc-list | </span><span style="color: #5B6268;">grep</span><span style="color: #5B6268;"> Nerd  # to verify the font is installed</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org4a4cfc4" class="outline-2">
<h2 id="org4a4cfc4"><span class="section-number-2">6.</span> Some issues with running Emacs in WSL2</h2>
<div class="outline-text-2" id="text-6">
<ul class="org-ul">
<li><p>
The first thing is I cannot reload the configuration with <code>M-x doom/reload</code> as running this command always gives me the following error message so that I need to restart the Emacs every time the configuration is changed.
</p>

<blockquote>
<p>
%s sync -B -e
/bin/bash: line 1: fg: no job control
</p>
</blockquote></li>

<li>I really dislike the <a href="https://www.reddit.com/r/wsl2/comments/16b4skx/wsl_softwares_with_white_window_borders/">white border</a> that surrounds any application launched by WSL!</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-linux.html">linux</a> <a href="https://chenyo.me/tag-emacs.html">emacs</a> <a href="https://chenyo.me/tag-tool.html">tool</a> </div>]]></description>
  <category><![CDATA[linux]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[tool]]></category>
  <link>https://chenyo.me/2024-09-07-install-doom-emacs-with-lisp-native-compiler-in-wsl2.html</link>
  <guid>https://chenyo.me/2024-09-07-install-doom-emacs-with-lisp-native-compiler-in-wsl2.html</guid>
  <pubDate>Sat, 07 Sep 2024 12:38:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Hiked: Stoos]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgca2b0da">1. What happened?</a></li>
<li><a href="#org7e48416">2. What now?</a></li>
</ul>
</div>
</nav>
<div id="outline-container-orgca2b0da" class="outline-2">
<h2 id="orgca2b0da"><span class="section-number-2">1.</span> What happened?</h2>
<div class="outline-text-2" id="text-1">
<p>
About three weeks ago, I hiked Stoos and wrote a Redbook post.
Unfortunately, the post was only visible to me, apparently violating community guidelines.
</p>

<p>
I spent most of that day trying to identify the problematic content, repeatedly editing and reposting.
Later, I learned this behavior is discouraged on Redbook, e.g., I am not really authorized to edit my own content.
</p>

<p>
Frustrated, I abandoned my efforts, leaving my Redbook homepage cluttered with articles like &ldquo;10 Behaviors That Harm Your Redbook Account&rdquo; and &ldquo;100 Forbidden Words on Redbook&rdquo;.
</p>

<p>
Though brief, this experience instilled in me a tendency towards self-censorship, a feeling I deeply resent.
I also noticed the lack of competitive alternatives to this centralized platform where users share authentic life experiences through multimedia.
</p>

<p>
Well played, Redbook!
</p>
</div>
</div>
<div id="outline-container-org7e48416" class="outline-2">
<h2 id="org7e48416"><span class="section-number-2">2.</span> What now?</h2>
<div class="outline-text-2" id="text-2">
<p>
Anyway, given that I invested considerable effort in creating post figures, I will post them here instead.
</p>


<figure id="orge76e504">
<img src="./static/stoos-2.png" alt="stoos-2.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 1: </span>The Stoos roadmap</figcaption>
</figure>


<figure id="org6106d6c">
<img src="./static/stoos-3.png" alt="stoos-3.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 2: </span>The uphill view</figcaption>
</figure>


<figure id="org8c272ea">
<img src="./static/stoos-4.png" alt="stoos-4.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 3: </span>The top view</figcaption>
</figure>


<figure id="orgecff653">
<img src="./static/stoos-5.png" alt="stoos-5.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 4: </span>The ridge roadmap</figcaption>
</figure>


<figure id="org6b8cb5a">
<img src="./static/stoos-6.png" alt="stoos-6.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 5: </span>The ridge view</figcaption>
</figure>


<figure id="org53bb5ce">
<img src="./static/stoos-7.png" alt="stoos-7.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 6: </span>My trace</figcaption>
</figure>


<figure id="orgf5ad8c2">
<img src="./static/stoos-8.png" alt="stoos-8.png" align="center" width="500px">

<figcaption><span class="figure-number">Figure 7: </span>Recommended apps</figcaption>
</figure>


<figure id="org05e1a12">
<img src="./static/stoos-9.png" alt="stoos-9.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 8: </span>My favorite hike shoots</figcaption>
</figure>


<figure id="orgc055049">
<img src="./static/stoos-post.png" alt="stoos-post.png" align="center" width="700px">

<figcaption><span class="figure-number">Figure 9: </span>The Redbook post</figcaption>
</figure>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-personal.html">personal</a> <a href="https://chenyo.me/tag-trip.html">trip</a> <a href="https://chenyo.me/tag-stoos.html">stoos</a> </div>]]></description>
  <category><![CDATA[personal]]></category>
  <category><![CDATA[trip]]></category>
  <category><![CDATA[stoos]]></category>
  <link>https://chenyo.me/2024-09-06-hiked:-stoos.html</link>
  <guid>https://chenyo.me/2024-09-06-hiked:-stoos.html</guid>
  <pubDate>Fri, 06 Sep 2024 21:32:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[CMU 15-445 notes: Hash Tables]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org74635f1">1. DBMS data structure application</a>
<ul>
<li><a href="#orga35b654">1.1. Design decisions</a></li>
</ul>
</li>
<li><a href="#org081e74e">2. Hash tables</a>
<ul>
<li><a href="#orgd0ab04f">2.1. Where are hash tables used</a></li>
</ul>
</li>
<li><a href="#org20aad1f">3. Hash function</a></li>
<li><a href="#org7c3d96b">4. Hashing scheme</a></li>
<li><a href="#orge0763fd">5. Static hashing scheme</a>
<ul>
<li><a href="#org2f56a26">5.1. Linear probe hashing</a>
<ul>
<li><a href="#orga4681b6">5.1.1. Non-unique keys</a></li>
<li><a href="#org420fb71">5.1.2. Optimization</a></li>
</ul>
</li>
<li><a href="#org9e99260">5.2. Cuckoo hashing</a></li>
</ul>
</li>
<li><a href="#org2ec7a07">6. Dynamic hashing schemes</a>
<ul>
<li><a href="#orga1191db">6.1. Chained Hashing</a></li>
<li><a href="#orga4ab4bc">6.2. Extendible hashing</a></li>
<li><a href="#org5dd0b2f">6.3. Linear hashing</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://15445.courses.cs.cmu.edu/fall2023/notes/07-hashtables.pdf">CMU 15-445 L7 notes</a> as well as some explanation from Claude.ai.
</p>
<div id="outline-container-org74635f1" class="outline-2">
<h2 id="org74635f1"><span class="section-number-2">1.</span> DBMS data structure application</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>Internal meta-data: <a href="https://chenyo.me/2024-08-13-db-notes:-memory-management.html#org7a44495">page tables</a>, <a href="https://chenyo.me/2024-07-31-db-notes:-database-storage.html#org66626ef">page directories</a>.</li>
<li>Tuple storage on disk.</li>
<li>Table indices: easy to find specific tuples.</li>
</ul>
</div>
<div id="outline-container-orga35b654" class="outline-3">
<h3 id="orga35b654"><span class="section-number-3">1.1.</span> Design decisions</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>Data layout for efficient access.</li>
<li>Concurrent access to data structures.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org081e74e" class="outline-2">
<h2 id="org081e74e"><span class="section-number-2">2.</span> Hash tables</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Implements an associative array that maps keys to values.</li>
<li>On average \(O(1)\) operation complexity with the worst case \(O(n)\); \(O(n)\) storage complexity.
<ul class="org-ul">
<li>Optimization for constant complexity is important in real world.</li>
</ul></li>
</ul>
</div>
<div id="outline-container-orgd0ab04f" class="outline-3">
<h3 id="orgd0ab04f"><span class="section-number-3">2.1.</span> Where are hash tables used</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>For tuple indexing. While tuples are stored on pages with NSM or DSM, during the <b><b>query</b></b> the DBMS needs to quickly locate the page that stores specific tuples. It can achieve this with separately-stored hash tables, where each key can be a hash of a tuple id, and the value points the location.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org20aad1f" class="outline-2">
<h2 id="org20aad1f"><span class="section-number-2">3.</span> Hash function</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Maps a large key space into a smaller domain.</li>
<li>Takes in any key as input, and returns a deterministic integer representation.</li>
<li>Needs to consider the trade-off between fast execution and collision rate.
<ul class="org-ul">
<li>Does not need to be cryptographically.</li>
<li>The state-of-art (Fall 2023) hash function is XXHash3.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org7c3d96b" class="outline-2">
<h2 id="org7c3d96b"><span class="section-number-2">4.</span> Hashing scheme</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>Handles key collision after hashing.</li>
<li>Needs to consider the trade-off between large table allocation (to avoid collision) and additional instruction execution when a collision occurs.</li>
</ul>
</div>
</div>
<div id="outline-container-orge0763fd" class="outline-2">
<h2 id="orge0763fd"><span class="section-number-2">5.</span> Static hashing scheme</h2>
<div class="outline-text-2" id="text-5">
<ul class="org-ul">
<li>The hash table size is fixed; the DBMS has to rebuild a larger hash table (e.g., twice the size) from scratch when it runs out of space.</li>
</ul>
</div>
<div id="outline-container-org2f56a26" class="outline-3">
<h3 id="org2f56a26"><span class="section-number-3">5.1.</span> Linear probe hashing</h3>
<div class="outline-text-3" id="text-5-1">
<ul class="org-ul">
<li>Insertion: when a collision occurs, linearly search the adjacent slots in a circular buffer until a open one is found.</li>
<li>Lookup: search linearly from the first hashed slot until the desired entry or an empty slot is reached, or every slot has been iterated.
<ul class="org-ul">
<li>Requires to store both key and value in the slot.</li>
</ul></li>
<li>Deletion: simply deleting the entry prevents future lookups as it becomes empty; two solutions:
<ul class="org-ul">
<li>Replace the deleted entry with a dummy entry to tell future lookups to keep scanning.</li>
<li>Shift the adjacent entries which were originally shifted, i.e., those who were originally hashed to the same key.
<ul class="org-ul">
<li>Very expensive and rarely implemented in practice.</li>
</ul></li>
</ul></li>
<li>The state-of-art linear probe hashing is Google <code>absl::flat_hash_map</code>.</li>
</ul>
</div>
<div id="outline-container-orga4681b6" class="outline-4">
<h4 id="orga4681b6"><span class="section-number-4">5.1.1.</span> Non-unique keys</h4>
<div class="outline-text-4" id="text-5-1-1">
<ul class="org-ul">
<li>The same key may be associated with multiple different values.</li>
<li>Separate linked list: each value is a pointer to a linked list of all values, which may overflow to multiple pages.</li>
<li>Redundant keys: store the same key multiple times with different values.
<ul class="org-ul">
<li>A more common approach.</li>
<li>Linear probing still works, if it is fine to get one value.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org420fb71" class="outline-4">
<h4 id="org420fb71"><span class="section-number-4">5.1.2.</span> Optimization</h4>
<div class="outline-text-4" id="text-5-1-2">
<ul class="org-ul">
<li>Specialized hash table based on key types and size; e.g., for long string keys, one can store the pointer or the hash of the long string in the hash table.</li>
<li>Store metadata in a separate array, e.g., store empty slot in a bitmap to avoid looking up deleted keys.</li>
<li><b><b>Version control</b></b> of hash tables: invalidate entries by incrementing the version counter rather than explicitly marking the deletion.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org9e99260" class="outline-3">
<h3 id="org9e99260"><span class="section-number-3">5.2.</span> Cuckoo hashing</h3>
<div class="outline-text-3" id="text-5-2">
<ul class="org-ul">
<li>Maintains multiple hash tables with different hash functions to generate different hashes for the same key using different seeds.</li>
<li>Insertion: check each table and choose one with a free slot; if none table has free slot, choose and evict an old entry and find it another table.
<ul class="org-ul">
<li>If a rare cycle happens, rebuild all hash tables with new seeds or with larger tables.</li>
</ul></li>
<li>\(O(1)\) lookups and deletion (also needs to store keys), but insertion is more expensive.</li>
<li>Practical implementation maps a key to different slots in a single hash table.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org2ec7a07" class="outline-2">
<h2 id="org2ec7a07"><span class="section-number-2">6.</span> Dynamic hashing schemes</h2>
<div class="outline-text-2" id="text-6">
<ul class="org-ul">
<li>Resize the hash table on demand without rebuilding the entire table.</li>
</ul>
</div>
<div id="outline-container-orga1191db" class="outline-3">
<h3 id="orga1191db"><span class="section-number-3">6.1.</span> Chained Hashing</h3>
<div class="outline-text-3" id="text-6-1">
<ul class="org-ul">
<li>Maintains a linked list of buckets for each slot in the hash table; keys hashed to the same slot are inserted into the linked list.</li>
<li>Lookup: hash to the key&rsquo;s bucket and scan for it.</li>
<li>Optimization: store bloom filter in the bucket pointer list to tell if a key exist in the linked list.</li>
</ul>
</div>
</div>
<div id="outline-container-orga4ab4bc" class="outline-3">
<h3 id="orga4ab4bc"><span class="section-number-3">6.2.</span> Extendible hashing</h3>
<div class="outline-text-3" id="text-6-2">
<ul class="org-ul">
<li>Improve chained hashing to avoid letting chains grow forever.</li>
<li>Allow multiple slot locations in the hash table to point to the same chain.</li>
</ul>


<figure id="orgc062610">
<img src="./static/db-extendible-hashing.png" alt="db-extendible-hashing.png" align="center" width="700px">

<figcaption><span class="figure-number">Figure 1: </span>Extendible hashing example</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org5dd0b2f" class="outline-3">
<h3 id="org5dd0b2f"><span class="section-number-3">6.3.</span> Linear hashing</h3>
<div class="outline-text-3" id="text-6-3">
<ul class="org-ul">
<li>Maintains a split pointer to keep track of next bucket to split, even if the pointed bucket is not overflowed.</li>
</ul>


<figure id="orgff347c7">
<img src="./static/db-linear-hashing.png" alt="db-linear-hashing.png" align="center" width="750px">

<figcaption><span class="figure-number">Figure 2: </span>Linear hashing example</figcaption>
</figure>

<ul class="org-ul">
<li>There are always only 2 hash functions: \((key\ mod\ n)\) and \((key\ mod\ 2n)\) where \(n\) is the length of buckets when the split pointer is at the index 0 (i.e., the bucket length at any time is \(n + index(sp)\)).</li>
</ul>


<figure id="org2b2c445">
<img src="./static/db-linear-hashing-deletion.png" alt="db-linear-hashing-deletion.png" align="center" width="750px">

<figcaption><span class="figure-number">Figure 3: </span>Linear hashing deletion example</figcaption>
</figure>

<ul class="org-ul">
<li>Why does \(k\ mod\ 2n < n + sp\) hold?
<ul class="org-ul">
<li>A key is only mod by \(2n\) if the result of \((k\ mod\ n)\) is above the split pointer, i.e., \(0 \leq k\ mod\ n < sp)\).</li>
<li>Let \(r = k\ mod\ n\), then \(k = pn + r\) and \(0 \leq r < sp\).</li>
<li>Let \(r' = k\ mod\ 2n\), then \(k = q(2n) + r'\).</li>
<li>If \(p = 2m\), then we also have \(k = m(2n) + r = q(2n) + r'\), in this case \(0 \leq r = r' < sp\).</li>
<li>If \(p = 2m + 1\), then we have \(k = m(2n) + r + n = q(2n) + r'\), in this case \(n \leq r' = n + r < n + sp\).</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-database.html">database</a> <a href="https://chenyo.me/tag-cmu.html">cmu</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[database]]></category>
  <category><![CDATA[cmu]]></category>
  <link>https://chenyo.me/2024-09-05-db-notes:-hash-tables.html</link>
  <guid>https://chenyo.me/2024-09-05-db-notes:-hash-tables.html</guid>
  <pubDate>Thu, 05 Sep 2024 12:26:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[My blog search function]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org21822fe">1. What happened</a></li>
<li><a href="#orgeca00df">2. What is not enough with existing search functions?</a></li>
<li><a href="#orgef17a7b">3. What does the search function do in this blog?</a></li>
<li><a href="#org7e2eff7">4. How is it implemented?</a></li>
<li><a href="#orge1cbcfb">5. How can it be improved?</a></li>
</ul>
</div>
</nav>
<div id="outline-container-org21822fe" class="outline-2">
<h2 id="org21822fe"><span class="section-number-2">1.</span> What happened</h2>
<div class="outline-text-2" id="text-1">
<p>
Two months ago, I started to use the current blog to keep track of my study and personal notes.
</p>

<p>
This blog uses <a href="https://github.com/bastibe/org-static-blog">bastibe/org-static-blog</a>, which is a convenient Emacs package to publish a static blog from Org-mode files.
</p>

<p>
When I first started, this blog had no styling at all.
With the help of Claude, I gradually decorated it with the theme and fonts of my choice.
</p>

<p>
During this process, my husband made a feature request: a blog search function.
</p>
</div>
</div>
<div id="outline-container-orgeca00df" class="outline-2">
<h2 id="orgeca00df"><span class="section-number-2">2.</span> What is not enough with existing search functions?</h2>
<div class="outline-text-2" id="text-2">
<p>
Most default search tools provided by popular static website frameworks do not return complete search results and their context.
</p>

<p>
For instance, I am learning database design.
Assume I cannot remember what a &ldquo;slotted page&rdquo; is but I know I have noted it before.
If I enter &ldquo;slotted&rdquo; in the search box of a Jekyll-based blog, it will provide me with 2 post links implying these posts contain this keyword.
In the best case, it also highlights the first occurrence of &ldquo;slotted&rdquo; in each post with its context.
</p>

<p>
This does not really meet my needs.
I would like to see all notes I have made for &ldquo;slotted&rdquo; to better refresh my memory, but the current results force me to click each post and perform a local search myself to achieve this goal.
</p>

<p>
I understand that modern search tools consider scalability and intelligence.
However, for a personal blog, we can achieve greater breadth.
</p>
</div>
</div>
<div id="outline-container-orgef17a7b" class="outline-2">
<h2 id="orgef17a7b"><span class="section-number-2">3.</span> What does the search function do in this blog?</h2>
<div class="outline-text-2" id="text-3">

<figure id="orgf5365c9">
<img src="./static/blog-search.gif" alt="blog-search.gif" align="center" width="700px" style="border: 1px solid black;">

<figcaption><span class="figure-number">Figure 1: </span>A blog search example</figcaption>
</figure>

<p>
The current search function searches for all occurrences of the given search input and highlights each occurrence in an item surrounded by its context, e.g., 50 characters before and after the input.
If multiple occurrences are close to each other, they are displayed once in the same item.
Clicking each item opens a new tab and jumps to the closest header before the input.
</p>

<p>
In this way, I can immediately see all results and their context on one page, and I only click an item when the short context is not sufficient.
</p>
</div>
</div>
<div id="outline-container-org7e2eff7" class="outline-2">
<h2 id="org7e2eff7"><span class="section-number-2">4.</span> How is it implemented?</h2>
<div class="outline-text-2" id="text-4">
<p>
I implemented the search function along with all styling with the help of Cursor.
The full logic can be found in <a href="https://github.com/chenyo-17/org-static-blog/blob/main/assets/search.js">search.js</a>.
</p>

<p>
In short, every time I build the blog, a list of all post links is stored in <a href="https://github.com/chenyo-17/org-static-blog/blob/main/assets/post-list.json">post-list.json</a>.
When the page is loaded, for each post link, the blog caches the full post content and all header indices.
When a search input is detected, the search function iterates through each post to find each occurrence and the closest header.
It then wraps the occurrence with certain context and prepares the link by appending the header tag to the post link.
</p>
</div>
</div>
<div id="outline-container-orge1cbcfb" class="outline-2">
<h2 id="orge1cbcfb"><span class="section-number-2">5.</span> How can it be improved?</h2>
<div class="outline-text-2" id="text-5">
<p>
The current search function is simple and sub-optimal.
It always re-stores all posts when the page is reloaded and is not lazy at all.
The search is also neither fuzzy nor the most efficient.
</p>

<p>
It just works well so far for a personal blog with about 30 posts.
</p>

<p>
In addition, after I finished the implementation, my husband made another feature request: can you also highlight all occurrences in the opened link?
</p>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-personal.html">personal</a> <a href="https://chenyo.me/tag-blog.html">blog</a> </div>]]></description>
  <category><![CDATA[personal]]></category>
  <category><![CDATA[blog]]></category>
  <link>https://chenyo.me/2024-08-29-my-blog-search-function.html</link>
  <guid>https://chenyo.me/2024-08-29-my-blog-search-function.html</guid>
  <pubDate>Thu, 29 Aug 2024 13:59:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Web learning in practice]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgbedc934">1. Basic html structure</a></li>
<li><a href="#org656fb18">2. Tags</a></li>
<li><a href="#org9d4b42a">3. Attributes</a></li>
<li><a href="#org6e84bec">4. Javascript</a>
<ul>
<li><a href="#org3f61638">4.1. Fetch from an HTML URL</a></li>
<li><a href="#org5752bef">4.2. Modify a DOM</a></li>
<li><a href="#orgd1533ce">4.3. Syntax</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This post records the basic web development knowledge I have learned in practice.
</p>
<div id="outline-container-orgbedc934" class="outline-2">
<h2 id="orgbedc934"><span class="section-number-2">1.</span> Basic html structure</h2>
<div class="outline-text-2" id="text-1">
<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #51afef;">!DOCTYPE</span> html&gt;
&lt;<span style="color: #c678dd;">html</span> <span style="color: #dcaeea;">lang</span>=<span style="color: #98be65;">"en"</span>&gt;

    <span style="color: #5B6268;">&lt;!-- </span><span style="color: #5B6268;">A head</span><span style="color: #5B6268;"> --&gt;</span>
    &lt;<span style="color: #c678dd;">head</span>&gt;
        &lt;<span style="color: #c678dd;">meta</span> <span style="color: #dcaeea;">charset</span>=<span style="color: #98be65;">"UTF-8"</span>&gt;
        <span style="color: #5B6268;">&lt;!-- </span><span style="color: #5B6268;">to accommodate different screen size</span><span style="color: #5B6268;"> --&gt;</span>
        &lt;<span style="color: #c678dd;">meta</span> <span style="color: #dcaeea;">name</span>=<span style="color: #98be65;">"viewport"</span> <span style="color: #dcaeea;">content</span>=<span style="color: #98be65;">"width=device-width, initial-scale=1.0"</span>&gt;
        <span style="color: #5B6268;">&lt;!-- </span><span style="color: #5B6268;">A tab name</span><span style="color: #5B6268;"> --&gt;</span>
        &lt;<span style="color: #c678dd;">title</span>&gt;<span style="font-weight: bold; text-decoration: underline;">A website</span>&lt;/<span style="color: #c678dd;">title</span>&gt;
        &lt;<span style="color: #c678dd;">link</span> <span style="color: #dcaeea;">rel</span>=<span style="color: #98be65;">"stylesheet"</span> <span style="color: #dcaeea;">href</span>=<span style="color: #98be65;">"styles.css"</span>&gt;
    &lt;/<span style="color: #c678dd;">head</span>&gt;


    <span style="color: #5B6268;">&lt;!-- </span><span style="color: #5B6268;">A body</span><span style="color: #5B6268;"> --&gt;</span>
    &lt;&lt;<span style="color: #c678dd;">body</span>&gt;
    <span style="color: #5B6268;">&lt;!-- </span><span style="color: #5B6268;">A page header</span><span style="color: #5B6268;">  --&gt;</span>
    &lt;<span style="color: #c678dd;">header</span>&gt;
        &lt;<span style="color: #c678dd;">h1</span>&gt;<span style="font-weight: bold; text-decoration: underline;">Welcome</span>&lt;/<span style="color: #c678dd;">h1</span>&gt;
    &lt;/<span style="color: #c678dd;">header</span>&gt;

    <span style="color: #5B6268;">&lt;!-- </span><span style="color: #5B6268;">A navigation panel</span><span style="color: #5B6268;"> --&gt;</span>
    &lt;<span style="color: #c678dd;">nav</span>&gt;
        &lt;<span style="color: #c678dd;">ul</span>&gt;
        &lt;&lt;<span style="color: #c678dd;">li</span>&gt;&lt;<span style="color: #c678dd;">a</span> <span style="color: #dcaeea;">href</span>=<span style="color: #98be65;">"index.html"</span>&gt;Home&lt;/<span style="color: #c678dd;">a</span>&gt;&lt;/<span style="color: #c678dd;">li</span>&gt;
        &lt;/<span style="color: #c678dd;">ul</span>&gt;
    &lt;/<span style="color: #c678dd;">nav</span>&gt;

    <span style="color: #5B6268;">&lt;!-- </span><span style="color: #5B6268;">The main content</span><span style="color: #5B6268;"> --&gt;</span>
    &lt;<span style="color: #c678dd;">main</span>&gt;
        &lt;<span style="color: #c678dd;">section</span> <span style="color: #dcaeea;">id</span>=<span style="color: #98be65;">"home"</span>&gt;
        &lt;<span style="color: #c678dd;">h2</span>&gt;<span style="font-weight: bold; font-style: italic; text-decoration: underline;">Home</span>&lt;/<span style="color: #c678dd;">h2</span>&gt;
        &lt;<span style="color: #c678dd;">p</span>&gt;Welcome!&lt;/<span style="color: #c678dd;">p</span>&gt;
        &lt;/<span style="color: #c678dd;">section</span>&gt;
    &lt;/<span style="color: #c678dd;">main</span>&gt;

    <span style="color: #5B6268;">&lt;!-- </span><span style="color: #5B6268;">A footer</span><span style="color: #5B6268;"> --&gt;</span>
    &lt;<span style="color: #c678dd;">footer</span>&gt;
        &lt;<span style="color: #c678dd;">p</span>&gt;<span style="color: #dcaeea;">&amp;copy;</span> All rights reserved.&lt;/<span style="color: #c678dd;">p</span>&gt;
    &lt;/<span style="color: #c678dd;">footer</span>&gt;
    &lt;/<span style="color: #c678dd;">body</span>&gt;

&lt;/<span style="color: #c678dd;">html</span>&gt;
</pre>
</div>
</div>
</div>
<div id="outline-container-org656fb18" class="outline-2">
<h2 id="org656fb18"><span class="section-number-2">2.</span> Tags</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li><code class="src src-html">&lt;<span style="color: #c678dd;">a</span>&gt;</code>: contain links; have following attributes:
<ul class="org-ul">
<li><code class="src src-html"><span style="color: #dcaeea;">target</span>="_blank"</code>: open the link in a new tab.</li>
<li><code class="src src-html"><span style="color: #dcaeea;">title</span>="Go to the link"</code>: the tooltip message, i.e., the floating message when a user hovers over.</li>
</ul></li>
<li><code class="src src-html">&lt;<span style="color: #c678dd;">span</span>&gt;</code>: don&rsquo;t add line breaks before or after it.</li>
<li><code class="src src-html">&lt;<span style="color: #c678dd;">hr</span>&gt;</code>: horizontal rule.</li>
</ul>
</div>
</div>
<div id="outline-container-org9d4b42a" class="outline-2">
<h2 id="org9d4b42a"><span class="section-number-2">3.</span> Attributes</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li><code class="src src-html"><span style="color: #dcaeea;">id</span>="home"</code>:
<ul class="org-ul">
<li>allow specific styling of the element, e.g., <code class="src src-html">#home ul {...}</code> only styles the <code class="src src-html">ul</code> in the block with the same id.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org6e84bec" class="outline-2">
<h2 id="org6e84bec"><span class="section-number-2">4.</span> Javascript</h2>
<div class="outline-text-2" id="text-4">
</div>
<div id="outline-container-org3f61638" class="outline-3">
<h3 id="org3f61638"><span class="section-number-3">4.1.</span> Fetch from an HTML URL</h3>
<div class="outline-text-3" id="text-4-1">
<ol class="org-ol">
<li><code class="src src-js"><span style="color: #51afef;">await</span> fetch(url)</code>: returns a <code class="src src-js">Response</code> object.
<ul class="org-ul">
<li><code class="src src-js"><span style="color: #51afef;">await</span></code> waits for the method to complete.</li>
</ul></li>
<li><code class="src src-js"><span style="color: #51afef;">await</span> response.text()</code>: returns the <code class="src src-js">html</code> string.</li>
<li><code class="src src-js">DOMParser().parseFromString(postHtml, <span style="color: #98be65;">"text/html"</span>)</code>: returns a <code class="src src-js">Document</code> object, which is a complete DOM tree from the HTML string; <code class="src src-js">DOMParser</code> is a built-in browser API.</li>
<li><code class="src src-js">postDoc.getElementById(<span style="color: #98be65;">"content"</span>)</code>: returns an <code class="src src-js">Element</code> with the <code class="src src-js">content</code> id name.</li>
<li><code class="src src-js">content.querySelector(<span style="color: #98be65;">".post-title a"</span>)</code>: fetches the first <code class="src src-js">Element</code> with the <code class="src src-js">post-title</code> class name, and returns the first <code class="src src-js">Element</code> the first <code class="src src-js">&lt;a&gt;</code> (anchor) tag.
<ul class="org-ul">
<li><code class="src src-js">.</code> for classes, <code class="src src-js">#</code> for IDs (IDs should be unique within a page)</li>
</ul></li>
</ol>
</div>
</div>
<div id="outline-container-org5752bef" class="outline-3">
<h3 id="org5752bef"><span class="section-number-3">4.2.</span> Modify a DOM</h3>
<div class="outline-text-3" id="text-4-2">
<ul class="org-ul">
<li><code class="src src-js">content.querySelector(<span style="color: #98be65;">".taglist"</span>).remove()</code>: removes the element from the DOM, i.e., it modifies <code class="src src-js">content</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-orgd1533ce" class="outline-3">
<h3 id="orgd1533ce"><span class="section-number-3">4.3.</span> Syntax</h3>
<div class="outline-text-3" id="text-4-3">
<ul class="org-ul">
<li><code class="src src-js"><span style="color: #51afef;">const</span> <span style="color: #dcaeea;">escapedQuery</span> = query.replace(<span style="color: #98be65;">/[.*+?^${}()|[\]\\]/</span>g, <span style="color: #98be65;">"\\$&amp;"</span>)</code>: add a backslash to any special character in the query; <code>$&amp;</code> is a special pattern used in Javascript&rsquo;s <code class="src src-js">replacement</code> method.</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-web.html">web</a> <a href="https://chenyo.me/tag-app.html">app</a> </div>]]></description>
  <category><![CDATA[web]]></category>
  <category><![CDATA[app]]></category>
  <link>https://chenyo.me/2024-08-15-web-learning-in-practice.html</link>
  <guid>https://chenyo.me/2024-08-15-web-learning-in-practice.html</guid>
  <pubDate>Thu, 15 Aug 2024 19:26:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[CMU 15-445 notes: Memory Management]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org332791c">1. Goals</a></li>
<li><a href="#orgd8419a5">2. Locks &amp; Latches</a>
<ul>
<li><a href="#org18ca57b">2.1. Locks</a></li>
<li><a href="#orgbcdeae0">2.2. Latches</a></li>
</ul>
</li>
<li><a href="#org80e286c">3. Buffer pool</a>
<ul>
<li><a href="#orgc3cd8ae">3.1. Metadata</a></li>
<li><a href="#org04087f0">3.2. Memory allocation policies</a></li>
</ul>
</li>
<li><a href="#org786e72e">4. Buffer pool optimizations</a>
<ul>
<li><a href="#org0ed5859">4.1. Multiple buffer pools</a></li>
<li><a href="#org49a5234">4.2. Pre-fetching</a></li>
<li><a href="#orgb22eb92">4.3. Scan sharing</a></li>
<li><a href="#orgd54ba70">4.4. Buffer pool bypass</a></li>
</ul>
</li>
<li><a href="#orgcfefd22">5. Buffer replacement policies</a>
<ul>
<li><a href="#org1d3cf65">5.1. Least recently used (LRU)</a></li>
<li><a href="#org3a5197b">5.2. Clock</a></li>
<li><a href="#orgecb04b6">5.3. LRU-K</a>
<ul>
<li><a href="#org65db71b">5.3.1. MySQL approximate LRU-K</a></li>
</ul>
</li>
<li><a href="#org1ff1714">5.4. Localization</a></li>
<li><a href="#orgfa37cdd">5.5. Priority hint</a></li>
<li><a href="#org780bc45">5.6. Dirty pages</a></li>
</ul>
</li>
<li><a href="#orgeb1549d">6. Other memory pools</a></li>
<li><a href="#orgf63c003">7. OS cache bypass</a></li>
<li><a href="#orge55f148">8. I/O scheduling</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://15445.courses.cs.cmu.edu/fall2023/notes/06-bufferpool.pdf">CMU 15-445 L6 notes</a> as well as some explanation from Claude.ai.
</p>
<div id="outline-container-org332791c" class="outline-2">
<h2 id="org332791c"><span class="section-number-2">1.</span> Goals</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>Manage DBMS memory and move data between the memory and the disk, such that the execution engine does no worry about the data fetching.</li>
<li>Spatial control: keep relevant pages physically together on disk.</li>
<li>Temporal control: minimize the number of stalls to read data from the disk.</li>
</ul>
</div>
</div>
<div id="outline-container-orgd8419a5" class="outline-2">
<h2 id="orgd8419a5"><span class="section-number-2">2.</span> Locks &amp; Latches</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Both used to protect internal elements.</li>
</ul>
</div>
<div id="outline-container-org18ca57b" class="outline-3">
<h3 id="org18ca57b"><span class="section-number-3">2.1.</span> Locks</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>A high-level logical primitive to allow for transaction atomicity.</li>
<li>Exposed to users when queries are run.</li>
<li>Need to be able to rollback changes.</li>
</ul>
</div>
</div>
<div id="outline-container-orgbcdeae0" class="outline-3">
<h3 id="orgbcdeae0"><span class="section-number-3">2.2.</span> Latches</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li>A low-level protection primitive a DBMS uses in its internal data structures, e.g., hash tables.</li>
<li>Only held when the operation is being made, like a mutex.</li>
<li>Do not need to expose to users or used to rollback changes.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org80e286c" class="outline-2">
<h2 id="org80e286c"><span class="section-number-2">3.</span> Buffer pool</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>An in-memory cache of pages read from the disk.</li>
<li>The buffer pool&rsquo;s region of memory is organized as an array of fixed size pages; each array entry is called a frame.</li>
<li>When the DBMS requests a page, the buffer pool first searches its cache, if not found, it copies he page from the disk into one of its frame.</li>
<li>Dirty pages (i.e., modified pages) are buffered rather than writing back immediately.</li>
</ul>
</div>
<div id="outline-container-orgc3cd8ae" class="outline-3">
<h3 id="orgc3cd8ae"><span class="section-number-3">3.1.</span> Metadata</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>Page table: An in-memory hash mapping page ids to frame locations in the buffer pool.</li>
<li>Dirty flag: set by a thread whenever it modifies a page to indicate the pages must be written back to disk.</li>
<li>Pin/Reference counter: tracks the number of threads that are currently accessing the page; the storage manager is not allowed to evict a page if its pin count is greater than 0.</li>
</ul>
</div>
</div>
<div id="outline-container-org04087f0" class="outline-3">
<h3 id="org04087f0"><span class="section-number-3">3.2.</span> Memory allocation policies</h3>
<div class="outline-text-3" id="text-3-2">
<ul class="org-ul">
<li>The buffer pool decides when to allocate a frame for a page.</li>
<li>Global policies: decisions based on the overall workload, e.g., least recently used (LRU) or clock algorithm.</li>
<li>Local policies: decisions applying to specific query, e.g., priority-based page replacement.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org786e72e" class="outline-2">
<h2 id="org786e72e"><span class="section-number-2">4.</span> Buffer pool optimizations</h2>
<div class="outline-text-2" id="text-4">
</div>
<div id="outline-container-org0ed5859" class="outline-3">
<h3 id="org0ed5859"><span class="section-number-3">4.1.</span> Multiple buffer pools</h3>
<div class="outline-text-3" id="text-4-1">
<ul class="org-ul">
<li>Each database or page can have its own buffer pool and adopts local policies to reduce latch contention.</li>
<li>To map a page to a buffer pool, the DBMS can use object IDs or page IDs as the key.
<ul class="org-ul">
<li>Record ID: a unique identifier for a row in a table (cf. <a href="https://chenyo-17.github.io/org-static-blog/tag-database.html#org2317270">Tuple layout post</a>).</li>
<li>Object ID: a unique identifier for an object, used to reference a user-defined type.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org49a5234" class="outline-3">
<h3 id="org49a5234"><span class="section-number-3">4.2.</span> Pre-fetching</h3>
<div class="outline-text-3" id="text-4-2">
<ul class="org-ul">
<li>While the first set of pages is being processed, the DBMS can pre-fetch the second set into the buffer pool based on the dependency between pages.
<ul class="org-ul">
<li>E.g., If pages are index-organized, the sibling pages can be pre-fetched.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgb22eb92" class="outline-3">
<h3 id="orgb22eb92"><span class="section-number-3">4.3.</span> Scan sharing</h3>
<div class="outline-text-3" id="text-4-3">
<ul class="org-ul">
<li>Query cursors can reuse retrieved data.</li>
<li>When a query comes while a previous query is being processed by scanning the table, the new query can attach its scanning cursor to the first query&rsquo;s cursor.</li>
<li>The DBMS keeps track of where the second query joined to make sure it also completes the scan.</li>
</ul>
</div>
</div>
<div id="outline-container-orgd54ba70" class="outline-3">
<h3 id="orgd54ba70"><span class="section-number-3">4.4.</span> Buffer pool bypass</h3>
<div class="outline-text-3" id="text-4-4">
<ul class="org-ul">
<li>Scanned pages do not have to be stored in the buffer pool to avoid the overhead.</li>
<li>Use cases: a query needs to read a large sequence of contiguous pages; temporary pages like sorting or joins.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgcfefd22" class="outline-2">
<h2 id="orgcfefd22"><span class="section-number-2">5.</span> Buffer replacement policies</h2>
<div class="outline-text-2" id="text-5">
<ul class="org-ul">
<li>The DBMS decides which page to evict from the buffer pool to free up a frame.</li>
</ul>
</div>
<div id="outline-container-org1d3cf65" class="outline-3">
<h3 id="org1d3cf65"><span class="section-number-3">5.1.</span> Least recently used (LRU)</h3>
<div class="outline-text-3" id="text-5-1">
<ul class="org-ul">
<li>LRU maintains a timestamp of when each page was last accessed, and evicts the page with the oldest timestamp.
<ul class="org-ul">
<li>The timestamp can be stored in a queue for efficient sorting.</li>
</ul></li>
<li>Susceptible to sequential flooding, where the buffer pool is corrupted due to a sequential scan.
<ul class="org-ul">
<li>With the LRU policy the oldest pages are evicted, but they are more likely to be scanned soon.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org3a5197b" class="outline-3">
<h3 id="org3a5197b"><span class="section-number-3">5.2.</span> Clock</h3>
<div class="outline-text-3" id="text-5-2">
<ul class="org-ul">
<li>An approximation of LRU but replace the timestamp with a reference bit which is set to 1 when a page is accessed.</li>
<li>Regularly sweeping all pages, if a bit is set to 1, reset to 0; if a bit is 0, evict the page.</li>
</ul>
</div>
</div>
<div id="outline-container-orgecb04b6" class="outline-3">
<h3 id="orgecb04b6"><span class="section-number-3">5.3.</span> LRU-K</h3>
<div class="outline-text-3" id="text-5-3">
<ul class="org-ul">
<li>Tracks the last K accessed timestamps to predict the next accessed time, hence avoid the sequential flooding issue.</li>
</ul>
</div>
<div id="outline-container-org65db71b" class="outline-4">
<h4 id="org65db71b"><span class="section-number-4">5.3.1.</span> MySQL approximate LRU-K</h4>
<div class="outline-text-4" id="text-5-3-1">
<ul class="org-ul">
<li>Use a linked list with two entry points: &ldquo;old&rdquo; and &ldquo;young&rdquo;.</li>
<li>The new pages are always inserted to the head of &ldquo;old&rdquo;.</li>
<li>If a page in the &ldquo;old&rdquo; is accessed again, it is then inserted to the head of &ldquo;young&rdquo;.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org1ff1714" class="outline-3">
<h3 id="org1ff1714"><span class="section-number-3">5.4.</span> Localization</h3>
<div class="outline-text-3" id="text-5-4">
<ul class="org-ul">
<li>Instead of using a global replacement policy, the DBMS make eviction decisions based on each query.</li>
<li>Pages brought in by one query are less likely to evict pages that are important for other ongoing queries.</li>
<li>The DBMS can <b><b>predicts</b></b> more accurately which pages should stay or be evicted once the query is complete, so that the buffer pool is less polluted with less useful pages.</li>
</ul>
</div>
</div>
<div id="outline-container-orgfa37cdd" class="outline-3">
<h3 id="orgfa37cdd"><span class="section-number-3">5.5.</span> Priority hint</h3>
<div class="outline-text-3" id="text-5-5">
<ul class="org-ul">
<li>Transactions tell the buffer pool where pages are important based on the <b><b>context</b></b> of each page.</li>
</ul>
</div>
</div>
<div id="outline-container-org780bc45" class="outline-3">
<h3 id="org780bc45"><span class="section-number-3">5.6.</span> Dirty pages</h3>
<div class="outline-text-3" id="text-5-6">
<ul class="org-ul">
<li>Two ways to handle dirty pages in the buffer pool:
<ul class="org-ul">
<li>Fast: only drop clean pages.</li>
<li>Slow: write back dirty pages to ensure persistent change, and then evict them (if they will not be read again.).</li>
</ul></li>
<li>Can periodically walk through the page table and write back dirty pages in the background.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgeb1549d" class="outline-2">
<h2 id="orgeb1549d"><span class="section-number-2">6.</span> Other memory pools</h2>
<div class="outline-text-2" id="text-6">
<ul class="org-ul">
<li>A DBMS also maintains other pools to store:
<ul class="org-ul">
<li>query caches,</li>
<li>logs,</li>
<li>temporary tables, e.g., sorting, join,</li>
<li>dictionary caches.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgf63c003" class="outline-2">
<h2 id="orgf63c003"><span class="section-number-2">7.</span> OS cache bypass</h2>
<div class="outline-text-2" id="text-7">
<ul class="org-ul">
<li>Most DBMS use direct I/O (e.g., with <code>fsync</code> instead of <code>fwrite</code>) to bypass the OS cache to avoid redundant page copy and to manage eviction policies more intelligently (cf. <a href="https://chenyo-17.github.io/org-static-blog/tag-database.html#org611ff38">Why not OS post</a>).</li>
</ul>
</div>
</div>
<div id="outline-container-orge55f148" class="outline-2">
<h2 id="orge55f148"><span class="section-number-2">8.</span> I/O scheduling</h2>
<div class="outline-text-2" id="text-8">
<ul class="org-ul">
<li>The DBMS maintains internal <b><b>queue</b></b> to track page read/write.</li>
<li>The priority are determined by multi-facets, e.g., critical path task, SLAs.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-database.html">database</a> <a href="https://chenyo.me/tag-cmu.html">cmu</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[database]]></category>
  <category><![CDATA[cmu]]></category>
  <link>https://chenyo.me/2024-08-13-db-notes:-memory-management.html</link>
  <guid>https://chenyo.me/2024-08-13-db-notes:-memory-management.html</guid>
  <pubDate>Tue, 13 Aug 2024 07:46:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[CMU 15-445 notes: Storage Models & Compression]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org98ea5e6">1. Database workloads</a>
<ul>
<li><a href="#orgab6ffc5">1.1. OLTP (Online Transaction Processing)</a></li>
<li><a href="#org50a86ef">1.2. OLAP (Online Analytical Processing)</a></li>
<li><a href="#orgd7fbe6a">1.3. HTAP (Hybrid)</a></li>
</ul>
</li>
<li><a href="#orgbd839b0">2. Storage models</a>
<ul>
<li><a href="#org7957416">2.1. N-ary Storage Model (NSM)</a></li>
<li><a href="#org4db7d0f">2.2. Decomposition Storage Model (DSM)</a></li>
<li><a href="#org224a772">2.3. Partition Attributes Across (PAX)</a></li>
</ul>
</li>
<li><a href="#org3ae23b4">3. Database compression</a>
<ul>
<li><a href="#org33f70fe">3.1. Compression granularity</a></li>
<li><a href="#org2c90f72">3.2. Naive compression</a></li>
</ul>
</li>
<li><a href="#org262d967">4. Columnar compression</a>
<ul>
<li><a href="#org98b81b8">4.1. Dictionary encoding</a></li>
<li><a href="#orgd795973">4.2. Run-Length encoding (RLE)</a></li>
<li><a href="#orge221ad5">4.3. Bit-packing encoding</a></li>
<li><a href="#org76ccf6b">4.4. Mostly encoding</a></li>
<li><a href="#org4839601">4.5. Bitmap (One-hot) encoding</a></li>
<li><a href="#org8ff0598">4.6. Delta encoding</a></li>
<li><a href="#org869478e">4.7. Incremental encoding</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://15445.courses.cs.cmu.edu/fall2023/notes/05-storage3.pdf">CMU 15-445 L5 notes</a>.
</p>
<div id="outline-container-org98ea5e6" class="outline-2">
<h2 id="org98ea5e6"><span class="section-number-2">1.</span> Database workloads</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-orgab6ffc5" class="outline-3">
<h3 id="orgab6ffc5"><span class="section-number-3">1.1.</span> OLTP (Online Transaction Processing)</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>Characterized by fast, repetitive, simple queries that operator on a small amount of data, e.g., a user adds an item to its Amazon cart and pay.</li>
<li>Usually more writes than read.</li>
</ul>
</div>
</div>
<div id="outline-container-org50a86ef" class="outline-3">
<h3 id="org50a86ef"><span class="section-number-3">1.2.</span> OLAP (Online Analytical Processing)</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Characterized by complex read queries on large data.</li>
<li>E.g., compute the most popular item in a period.</li>
</ul>
</div>
</div>
<div id="outline-container-orgd7fbe6a" class="outline-3">
<h3 id="orgd7fbe6a"><span class="section-number-3">1.3.</span> HTAP (Hybrid)</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>OLTP + OLAP.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgbd839b0" class="outline-2">
<h2 id="orgbd839b0"><span class="section-number-2">2.</span> Storage models</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Different ways to store tuples in pages.</li>
</ul>
</div>
<div id="outline-container-org7957416" class="outline-3">
<h3 id="org7957416"><span class="section-number-3">2.1.</span> N-ary Storage Model (NSM)</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>Store all attributes for a single tuple contiguously in a single page, e.g., slotted pages.</li>
<li>Pros: good for queries that need the entire tuple, e.g., OLTP.</li>
<li>Cons: inefficient for scanning large data with a few attributes, e.g., OLAP.</li>
</ul>
</div>
</div>
<div id="outline-container-org4db7d0f" class="outline-3">
<h3 id="org4db7d0f"><span class="section-number-3">2.2.</span> Decomposition Storage Model (DSM)</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li>Store each attribute for all tuples contiguously in a block of data, i.e., column store.</li>
<li>Pros: save I/O; better data compression; ideal for bulk single attribute queries like OLAP.</li>
<li>Cons: slow for point queries due to tuple splitting, e.g., OLTP.</li>
<li>2 common ways to put back tuples:
<ul class="org-ul">
<li>Most common: use fixed-length offsets, e.g., the value in a given column belong to the same tuple as the value in another column at the same offset.</li>
<li>Less common: use embedded tuple ids, e.g., each attribute is associated with the tuple id, and the DBMS stores a mapping to jump to any attribute with the given tuple id.</li>
</ul></li>
</ul>


<figure id="org4fe28c0">
<img src="./static/db-dsm-storage-model.png" alt="db-dsm-storage-model.png" align="center" width="550px">

<figcaption><span class="figure-number">Figure 1: </span>DSM storage model (<a href="https://15445.courses.cs.cmu.edu/fall2023/slides/05-storage3.pdf">Source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org224a772" class="outline-3">
<h3 id="org224a772"><span class="section-number-3">2.3.</span> Partition Attributes Across (PAX)</h3>
<div class="outline-text-3" id="text-2-3">
<ul class="org-ul">
<li>Rows are horizontally partitioned into groups of rows; each row group uses a column store.</li>
<li>A PAX file has a global header containing a directory with each row group&rsquo;s offset; each row group maintains its own header with content metadata.</li>
</ul>


<figure id="org8524409">
<img src="./static/db-pax-storage-model.png" alt="db-pax-storage-model.png" align="center" width="300px">

<figcaption><span class="figure-number">Figure 2: </span>PAX storage model (<a href="https://15445.courses.cs.cmu.edu/fall2023/slides/05-storage3.pdf">Source</a>)</figcaption>
</figure>
</div>
</div>
</div>
<div id="outline-container-org3ae23b4" class="outline-2">
<h2 id="org3ae23b4"><span class="section-number-2">3.</span> Database compression</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Disk I/O is always the main bottleneck; read-only analytical workloads are popular; compression in advance allows for more I/O throughput.</li>
<li><b><b>Real-world</b></b> data sets have the following properties for compression:
<ul class="org-ul">
<li><b><b>Highly skewed</b></b> distributions for attribute values.</li>
<li><b><b>High correlation</b></b> between attributes of the same tuple, e.g., zip code to city.</li>
</ul></li>
<li>Requirements on the database compression:
<ul class="org-ul">
<li>Fixed-length values to follow word-alignment; variable length data stored in separate mappings.</li>
<li>Postpone decompression as long as possible during query execution, i.e., <b><b>late materialization</b></b>.</li>
<li>Lossless; any lossy compression can only be performed at the  application level.</li>
</ul></li>
</ul>
</div>
<div id="outline-container-org33f70fe" class="outline-3">
<h3 id="org33f70fe"><span class="section-number-3">3.1.</span> Compression granularity</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>Block level: compress all tuples for the same table.</li>
<li>Tuple level: compress each tuple (NSM only).</li>
<li>Attribute level: compress one or multiple values within one tuple.</li>
<li>Columnar level: compress one or multiple columns across multiple tuples (DSM only).</li>
</ul>
</div>
</div>
<div id="outline-container-org2c90f72" class="outline-3">
<h3 id="org2c90f72"><span class="section-number-3">3.2.</span> Naive compression</h3>
<div class="outline-text-3" id="text-3-2">
<ul class="org-ul">
<li>Engineers often use a general purpose compression algorithm with lower compression ratio in exchange for faster compression/decompression.</li>
<li>E.g., compress disk pages by padding them to a power of 2KBs and storing them in the buffer pool.
<ul class="org-ul">
<li>Why small chunk: must decompress before reading/writing the data every time, hence need o limit the compression scope.</li>
</ul></li>
<li>Does not consider the high-level data semantics, thus cannot utilize late materialization.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org262d967" class="outline-2">
<h2 id="org262d967"><span class="section-number-2">4.</span> Columnar compression</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>Works best with OLAP, may need additional support for writes.</li>
</ul>
</div>
<div id="outline-container-org98b81b8" class="outline-3">
<h3 id="org98b81b8"><span class="section-number-3">4.1.</span> Dictionary encoding</h3>
<div class="outline-text-3" id="text-4-1">
<ul class="org-ul">
<li>The most common database compression scheme, support late materialization.</li>
<li>Replace frequent value patterns with smaller codes, and use a dictionary to map codes to their original values.</li>
<li>Need to support fast encoding and decoding, so hash function is impossible.</li>
<li>Need to support order-preserving encodings, i.e., sorting codes in the same order as original values, to support <b><b>range queries</b></b>.
<ul class="org-ul">
<li>E.g., when <code>SELECT DISTINCT</code> with pattern-matching, the DBMS only needs to scan the encoding dictionary (but without <code>DISTINCT</code> it still needs to scan the whole column).</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgd795973" class="outline-3">
<h3 id="orgd795973"><span class="section-number-3">4.2.</span> Run-Length encoding (RLE)</h3>
<div class="outline-text-3" id="text-4-2">
<ul class="org-ul">
<li>Compress runs (consecutive instances) of the same value in a column into triplets <code>(value, offset, length)</code>.</li>
<li>Need to cluster same column values to maximize the compression.</li>
</ul>


<figure id="orgb11f502">
<img src="./static/db-rle-storage-model.png" alt="db-rle-storage-model.png" align="center" width="550px">

<figcaption><span class="figure-number">Figure 3: </span>Run-length encoding (<a href="https://15445.courses.cs.cmu.edu/fall2023/slides/05-storage3.pdf">Source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-orge221ad5" class="outline-3">
<h3 id="orge221ad5"><span class="section-number-3">4.3.</span> Bit-packing encoding</h3>
<div class="outline-text-3" id="text-4-3">
<ul class="org-ul">
<li>Use less bits to store an attribute.</li>
</ul>


<figure id="orgd7b5164">
<img src="./static/db-bit-packing-storage-model.png" alt="db-bit-packing-storage-model.png" align="center" width="250px">

<figcaption><span class="figure-number">Figure 4: </span>Bit-packing encoding (<a href="https://15445.courses.cs.cmu.edu/fall2023/slides/05-storage3.pdf">Source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org76ccf6b" class="outline-3">
<h3 id="org76ccf6b"><span class="section-number-3">4.4.</span> Mostly encoding</h3>
<div class="outline-text-3" id="text-4-4">
<ul class="org-ul">
<li>Use a special marker to indicate values that exceed the bit size and maintains a look-up table to store them.</li>
</ul>


<figure id="org7ef67c4">
<img src="./static/db-mostly-encoding-storage-model.png" alt="db-mostly-encoding-storage-model.png" align="center" width="550px">

<figcaption><span class="figure-number">Figure 5: </span>Mostly encoding (<a href="https://15445.courses.cs.cmu.edu/fall2023/slides/05-storage3.pdf">Source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org4839601" class="outline-3">
<h3 id="org4839601"><span class="section-number-3">4.5.</span> Bitmap (One-hot) encoding</h3>
<div class="outline-text-3" id="text-4-5">
<ul class="org-ul">
<li>Only practical if the value cardinality is low.</li>
</ul>


<figure id="org7fcb3e8">
<img src="./static/db-bitmap-encoding-storage-model.png" alt="db-bitmap-encoding-storage-model.png" align="center" width="400px">

<figcaption><span class="figure-number">Figure 6: </span>Bitmap encoding (<a href="https://15445.courses.cs.cmu.edu/fall2023/slides/05-storage3.pdf">Source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org8ff0598" class="outline-3">
<h3 id="org8ff0598"><span class="section-number-3">4.6.</span> Delta encoding</h3>
<div class="outline-text-3" id="text-4-6">
<ul class="org-ul">
<li>Record the difference between values; the base value can be stored in-line or in a separate look-up table.</li>
<li>Can be combined with RLE encoding.</li>
</ul>


<figure id="org055f5f6">
<img src="./static/db-delta-encoding-storage-model.png" alt="db-delta-encoding-storage-model.png" align="center" width="500px">

<figcaption><span class="figure-number">Figure 7: </span>Delta encoding (<a href="https://15445.courses.cs.cmu.edu/fall2023/slides/05-storage3.pdf">Source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org869478e" class="outline-3">
<h3 id="org869478e"><span class="section-number-3">4.7.</span> Incremental encoding</h3>
<div class="outline-text-3" id="text-4-7">
<ul class="org-ul">
<li>Common prefixes or suffixes and their lengths are recorded to avoid duplication.</li>
<li>Need to sort the data first.</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-database.html">database</a> <a href="https://chenyo.me/tag-cmu.html">cmu</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[database]]></category>
  <category><![CDATA[cmu]]></category>
  <link>https://chenyo.me/2024-08-08-db-notes:-storage-models-and-compression.html</link>
  <guid>https://chenyo.me/2024-08-08-db-notes:-storage-models-and-compression.html</guid>
  <pubDate>Thu, 08 Aug 2024 17:48:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Parallel EVM: Blockworks news (Sei, Monad, Solana)]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org0c5e7c0">1. Terminology</a>
<ul>
<li><a href="#org0184f8e">1.1. Ethereum sharding</a></li>
<li><a href="#org6e11b92">1.2. Blob</a></li>
<li><a href="#orgac91774">1.3. Erasure coding</a></li>
<li><a href="#org1b1a305">1.4. Data availability sampling (DAS)</a></li>
<li><a href="#org26b287a">1.5. Danksharding (L2 optimization)</a></li>
<li><a href="#org130582f">1.6. Relations between L1 and L2 scaling</a></li>
<li><a href="#org86f58af">1.7. Double spending prevention</a></li>
<li><a href="#orga5bdb9b">1.8. Sealevel (Solana)</a></li>
</ul>
</li>
<li><a href="#org4c7cc53">2. Ways to achieve parallel processing</a></li>
<li><a href="#orge20781b">3. Production-ready parallelized EVM projects (Jan 2024)</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note for <a href="https://blockworks.co/news/parallelized-evms-gaining-popularity">Blockworks news (12.01.2024)</a> as well as some terminology explained online, e.g., <a href="https://www.coindesk.com/learn/what-is-ethereum-sharding-a-beginners-guide/">Coindesk</a> and <a href="https://chatgpt.com/c/824f05c9-dc75-4eb6-aeda-59d057baf83a">GPT-4o</a>.
</p>
<div id="outline-container-org0c5e7c0" class="outline-2">
<h2 id="org0c5e7c0"><span class="section-number-2">1.</span> Terminology</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org0184f8e" class="outline-3">
<h3 id="org0184f8e"><span class="section-number-3">1.1.</span> Ethereum sharding</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>The Ethereum mainnet is divided into smaller interconnected networks called shards.</li>
<li>Each shard processes and validates its own transactions parallel to others.</li>
<li>Pros: increase scalability and <b><b>participation</b></b>.</li>
<li>Cons: a single unit can be compromised; lead to centralization.</li>
</ul>
</div>
</div>
<div id="outline-container-org6e11b92" class="outline-3">
<h3 id="org6e11b92"><span class="section-number-3">1.2.</span> Blob</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Rather than storing each transaction data directly in the blockchain, the data is aggregated into a blob (binary object).</li>
<li>Each blob performs erasure coding to dive the blob into multiple smaller pieces with redundancy.</li>
<li>Encoded pieces are stored separately, the block header contain pointers to the piece locations without storing actual data.</li>
<li>Transactions in a block may be distributed across multiple blobs.</li>
</ul>
</div>
</div>
<div id="outline-container-orgac91774" class="outline-3">
<h3 id="orgac91774"><span class="section-number-3">1.3.</span> Erasure coding</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>Allows one to encode blobs such that if at least half of the data in the blob is published, anyone in the network can reconstruct and re-publish the rest of the data.</li>
</ul>
</div>
</div>
<div id="outline-container-org1b1a305" class="outline-3">
<h3 id="org1b1a305"><span class="section-number-3">1.4.</span> Data availability sampling (DAS)</h3>
<div class="outline-text-3" id="text-1-4">
<ul class="org-ul">
<li>Validators randomly sample blob pieces to confirm the data can be reconstructed.g</li>
<li>If a client cannot get enough pieces to verify the blob availability, or the blob fails the integrity check, or transactions within the blob are invalid or inconsistent with the blockchain state, the blob is rejected.</li>
</ul>
</div>
</div>
<div id="outline-container-org26b287a" class="outline-3">
<h3 id="org26b287a"><span class="section-number-3">1.5.</span> Danksharding (L2 optimization)</h3>
<div class="outline-text-3" id="text-1-5">
<ul class="org-ul">
<li>A specific sharding implementation proposal.</li>
<li>Require data availability sampling and <a href="https://chenyo-17.github.io/org-static-blog/tag-evm.html#orgf2db0ef">proposer-builder separation</a>.</li>
<li>Can support hundreds of individual rollups.</li>
</ul>
</div>
</div>
<div id="outline-container-org130582f" class="outline-3">
<h3 id="org130582f"><span class="section-number-3">1.6.</span> Relations between L1 and L2 scaling</h3>
<div class="outline-text-3" id="text-1-6">
<ul class="org-ul">
<li>L1 scaling: optimizations directly to the Ethereum mainnet and core infrastructure, e.g., parallel EVM.</li>
<li>L2 scaling: building secondary rollup layers, e.g., optimistic rollups and ZK rollups, to offload mainnet computation and storage.</li>
</ul>
</div>
</div>
<div id="outline-container-org86f58af" class="outline-3">
<h3 id="org86f58af"><span class="section-number-3">1.7.</span> Double spending prevention</h3>
<div class="outline-text-3" id="text-1-7">
<ul class="org-ul">
<li>Bitcoin: uses UTXOs to track which inputs have been spent (no need to go through the entire chain).</li>
<li>Ethereum: uses a nounce to track the number of transactions sent from an account, the nounce is included in the transaction and is incremented by 1 for every new transaction, and all transactions must be executed in order.</li>
</ul>
</div>
</div>
<div id="outline-container-orga5bdb9b" class="outline-3">
<h3 id="orga5bdb9b"><span class="section-number-3">1.8.</span> Sealevel (Solana)</h3>
<div class="outline-text-3" id="text-1-8">
<ul class="org-ul">
<li>Solana&rsquo;s parallel smart contract runtime to process thousands of contracts in parallel.</li>
<li>Solana transactions describe all states a transaction accesses to efficiently recognize transaction dependency and to schedule parallel execution without accessing full blockchain state.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org4c7cc53" class="outline-2">
<h2 id="org4c7cc53"><span class="section-number-2">2.</span> Ways to achieve parallel processing</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Process independent transactions in parallel.</li>
<li>Sharding.</li>
</ul>
</div>
</div>
<div id="outline-container-orge20781b" class="outline-2">
<h2 id="orge20781b"><span class="section-number-2">3.</span> Production-ready parallelized EVM projects (Jan 2024)</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Sei: optimistic parallel execution.</li>
<li>Monad: custom EVM implementation, optimistic parallel execution, <b><b>custom state database</b></b>.
<ul class="org-ul">
<li>Commodity databases are not optimized for Merkle tree data read/write with SSD.</li>
</ul></li>
<li>Neon (Solana): transactions pre-specify dependencies.</li>
<li>See <a href="https://chenyo-17.github.io/org-static-blog/tag-evm.html#orgcb5510d">BNB chain post</a> for more solutions.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-evm.html">evm</a> <a href="https://chenyo.me/tag-parallel-evm.html">parallel-evm</a> <a href="https://chenyo.me/tag-blockworks.html">blockworks</a> </div>]]></description>
  <category><![CDATA[evm]]></category>
  <category><![CDATA[parallel-evm]]></category>
  <category><![CDATA[blockworks]]></category>
  <link>https://chenyo.me/2024-08-08-parallel-evm:-blockworks-bigger-picture.html</link>
  <guid>https://chenyo.me/2024-08-08-parallel-evm:-blockworks-bigger-picture.html</guid>
  <pubDate>Thu, 08 Aug 2024 09:19:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[My Exam Organization Experience]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgbe4c08c">1. What is it about?</a></li>
<li><a href="#orgdc9db0f">2. My first exam</a></li>
<li><a href="#org90c6e00">3. My second exam</a></li>
<li><a href="#orgb4af272">4. My third exam</a></li>
<li><a href="#org06ab3ca">5. My fourth exam</a></li>
<li><a href="#org6a22f0c">6. My feeling</a></li>
</ul>
</div>
</nav>
<p>
This post was co-authored with the assistance of Cursor and Claude AI.
</p>
<div id="outline-container-orgbe4c08c" class="outline-2">
<h2 id="orgbe4c08c"><span class="section-number-2">1.</span> What is it about?</h2>
<div class="outline-text-2" id="text-1">
<p>
Over the past years, I&rsquo;ve been involved in organizing and monitoring four exams.
Yesterday marked my fourth and likely final exam monitoring session for the foreseeable future.
Now seems like an opportune moment to reflect on my exam organization journey.
</p>
</div>
</div>
<div id="outline-container-orgdc9db0f" class="outline-2">
<h2 id="orgdc9db0f"><span class="section-number-2">2.</span> My first exam</h2>
<div class="outline-text-2" id="text-2">
<p>
My first exam experience was relatively straightforward.
As I was unfamiliar with the exam content, my primary responsibility was taking students to the restrooms.
I recall accompanying nearly 10 students during the session.
For the remainder of the time, I sat at the back of the room, occupying myself with some drawing.
</p>
</div>
</div>
<div id="outline-container-org90c6e00" class="outline-2">
<h2 id="org90c6e00"><span class="section-number-2">3.</span> My second exam</h2>
<div class="outline-text-2" id="text-3">
<p>
This exam was identical to the first, but I was tasked with designing a significant portion of the questions.
Initially, formulating questions seemed straightforward, but I later realized my inability to create effective ones.
My first draft incorporated connections between various questions.
During the review process, I was advised to maximize information density in questions, as stressed students prefer concise text.
Additional challenges emerged when I began grading the exams.
For example, open-ended questions consistently yielded unexpected answers, requiring me to modify the grading scheme while maintaining consistency with previous assessments.
</p>

<p>
The exam monitoring this time was more demanding as I began responding to student inquiries.
My limited knowledge of the entire exam often required me to seek assistance from colleagues, and occasionally I struggled to comprehend the questions.
</p>

<p>
Grading the exam proved to be the most challenging aspect of the process.
Evaluating over 100 exams, deciphering handwriting, determining fair point allocations, and recording scores was an incredibly tedious task.
Unlike traditional mathematics exams that focus primarily on calculations, our exam encouraged creative thinking.
Each answer contained implicit assumptions about the question, requiring careful interpretation to avoid excessive point deductions.
The process was extremely time-consuming and offered minimal personal benefit or satisfaction.
</p>
</div>
</div>
<div id="outline-container-orgb4af272" class="outline-2">
<h2 id="orgb4af272"><span class="section-number-2">4.</span> My third exam</h2>
<div class="outline-text-2" id="text-4">
<p>
This was a different exam, where I again designed one part and monitored its administration.
Fortunately, due to its advanced nature, few students registered for this exam.
This time, I had the privilege of collaborating with exceptional colleagues.
Despite these advantages, the design process still demanded considerable effort on my part.
</p>

<p>
A unique aspect of this exam was that I also developed the course material, as it was a newly introduced subject.
The topic proved challenging, and the exercises were demanding.
Students expressed concerns about the complexity of the material.
Consequently, we faced the task of devising ways to simplify the exam questions without compromising their effectiveness.
</p>
</div>
</div>
<div id="outline-container-org06ab3ca" class="outline-2">
<h2 id="org06ab3ca"><span class="section-number-2">5.</span> My fourth exam</h2>
<div class="outline-text-2" id="text-5">
<p>
Now comes the most recent exam, where I took on the role of a coordinator.
This position entailed not only designing my portion of the tasks but also finding colleagues to design other tasks, managing the timeline, reviewing drafts, printing exams, coordinating exam monitoring, and overseeing the grading process.
Fortunately, I had the support of proactive and helpful colleagues, which allowed everything to proceed smoothly.
</p>

<p>
The monitoring process proved particularly demanding this time.
As I was now familiar with the entire exam, I was responsible for reading instructions, making announcements, and answering as many questions as possible.
I had to arrive at the exam rooms by 8 AM, forgoing breakfast, and remained standing and focused until noon.
In retrospect, I may have been overly diligent due to inexperience and could have perhaps allowed myself to relax more. However, I&rsquo;ll never know for certain, as this marks the conclusion of my exam organization duties.
</p>

<p>
Well, not quite the end, as I still need to complete the grading and submit the results.
</p>
</div>
</div>
<div id="outline-container-org6a22f0c" class="outline-2">
<h2 id="org6a22f0c"><span class="section-number-2">6.</span> My feeling</h2>
<div class="outline-text-2" id="text-6">
<p>
After four instances of exam organization experience, I must admit that I do not recommend it.
This opinion is, of course, highly personal, as I am not particularly inclined towards teaching.
From my perspective, it is a job that demands significant effort while offering minimal returns.
I can confidently say that I invest more time in the exam process than any individual student taking it.
</p>

<p>
The process of designing and grading exams presents a complex optimization challenge.
There&rsquo;s an inverse relationship between the time spent on design and the time required for grading.
The less effort put into crafting the exam, the more time-consuming the grading process becomes.
Moreover, it&rsquo;s disheartening to spend two full days meticulously designing and reviewing a question,
only to have it attempted by a mere handful of students.
</p>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-personal.html">personal</a> <a href="https://chenyo.me/tag-teach.html">teach</a> </div>]]></description>
  <category><![CDATA[personal]]></category>
  <category><![CDATA[teach]]></category>
  <link>https://chenyo.me/2024-08-07-my-exam-organization-experience.html</link>
  <guid>https://chenyo.me/2024-08-07-my-exam-organization-experience.html</guid>
  <pubDate>Wed, 07 Aug 2024 20:16:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[CMU 15-445 notes: Database storage]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgc38b13b">1. Data storage</a>
<ul>
<li><a href="#org9ffbb37">1.1. Volatile device</a></li>
<li><a href="#org223e889">1.2. Non-volatile device</a></li>
<li><a href="#org1082ca9">1.3. Storage hierarchy</a></li>
<li><a href="#org038cc42">1.4. Persistent memory</a></li>
<li><a href="#orga246092">1.5. NVM (non-volatile memory express)</a></li>
</ul>
</li>
<li><a href="#org3097800">2. DBMS architecture</a>
<ul>
<li><a href="#org1979597">2.1. Why not OS</a></li>
</ul>
</li>
<li><a href="#org5b56588">3. Database pages</a>
<ul>
<li><a href="#orgd1b9e67">3.1. Hardware page</a></li>
</ul>
</li>
<li><a href="#orgf7c89de">4. Database heap</a></li>
<li><a href="#org7d4bcf8">5. Page layout</a>
<ul>
<li><a href="#orga4637bf">5.1. Slotted-pages</a></li>
<li><a href="#org6a0df02">5.2. Log-structured</a>
<ul>
<li><a href="#org20975f3">5.2.1. Log compaction</a></li>
</ul>
</li>
<li><a href="#org2527d1e">5.3. Index-organized storage</a></li>
</ul>
</li>
<li><a href="#org6c3f4d5">6. Tuple layout</a>
<ul>
<li><a href="#org5d23441">6.1. Denormalized tuple data</a></li>
</ul>
</li>
<li><a href="#org0fd4658">7. Data representation</a>
<ul>
<li><a href="#org6f4a717">7.1. Integers</a></li>
<li><a href="#org02ff80e">7.2. Variable precision numbers</a></li>
<li><a href="#org38805ab">7.3. Fixed-point precision numbers</a></li>
<li><a href="#org2cf83e4">7.4. Variable-length data</a></li>
<li><a href="#org9a6f19d">7.5. Dates/Times</a></li>
<li><a href="#org1f49635">7.6. Null</a></li>
</ul>
</li>
<li><a href="#orge4bd207">8. System catalogs</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://15445.courses.cs.cmu.edu/fall2023/notes/03-storage1.pdf">CMU 15-445 L3 notes</a> and <a href="https://15445.courses.cs.cmu.edu/fall2023/notes/04-storage2.pdf">CMU 15-445 L4 notes</a>.
</p>
<div id="outline-container-orgc38b13b" class="outline-2">
<h2 id="orgc38b13b"><span class="section-number-2">1.</span> Data storage</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org9ffbb37" class="outline-3">
<h3 id="org9ffbb37"><span class="section-number-3">1.1.</span> Volatile device</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>The data is lost once the power is off.</li>
<li>Support fast random access with byte-addressable locations, i.e., can jump to any byte address and access the data.</li>
<li>A.k.a memory, e.g., DRAM.</li>
</ul>
</div>
</div>
<div id="outline-container-org223e889" class="outline-3">
<h3 id="org223e889"><span class="section-number-3">1.2.</span> Non-volatile device</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>The data is retained after the power is off.</li>
<li>Block/Page addressable, i.e., in order to read a value at a particular offset, first need to load 4KB page into memory that holds the value.</li>
<li>Perform better for sequential access, i.e., contiguous chunks.</li>
<li>A.k.a disk, e.g., SSD (solid-state storage) and HDD (spinning hard drives).</li>
</ul>
</div>
</div>
<div id="outline-container-org1082ca9" class="outline-3">
<h3 id="org1082ca9"><span class="section-number-3">1.3.</span> Storage hierarchy</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>Close to CPU: faster, smaller, more expensive.</li>
</ul>
</div>
</div>
<div id="outline-container-org038cc42" class="outline-3">
<h3 id="org038cc42"><span class="section-number-3">1.4.</span> Persistent memory</h3>
<div class="outline-text-3" id="text-1-4">
<ul class="org-ul">
<li>As fast as DRAM, with the persistence of disk.</li>
<li>Not in widespread production use.</li>
<li>A.k.a, non-volatile memory.</li>
</ul>
</div>
</div>
<div id="outline-container-orga246092" class="outline-3">
<h3 id="orga246092"><span class="section-number-3">1.5.</span> NVM (non-volatile memory express)</h3>
<div class="outline-text-3" id="text-1-5">
<ul class="org-ul">
<li>NAND flash drives that connect over an improved hardware interface to allow faster transfer.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org3097800" class="outline-2">
<h2 id="org3097800"><span class="section-number-2">2.</span> DBMS architecture</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Primary storage location of the database is on disks.</li>
<li>The DBMS is responsible for data movement between disk and memory with a buffer pool.</li>
<li>The data is organized into pages by the storage manager; the first page is the directory page</li>
<li>To execute the query, the execution engine asks the buffer pool for a page; the buffer pool brings the page to the memory, gives the execution engine the page pointer, and ensures the page is retained in the memory while being executed.</li>
</ul>
</div>
<div id="outline-container-org1979597" class="outline-3">
<h3 id="org1979597"><span class="section-number-3">2.1.</span> Why not OS</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>The architecture is like virtual memory: a large address space and a place for the OS to bring the pages from the disk.</li>
<li>The OS way to achieve virtual memory is to use <code>mmap</code> to map the contents of a file in a process address space, and the OS is responsible for the data movement.</li>
<li>If <code>mmap</code> hits a page fault, the process is blocked; however a DBMS should be able to still process other queries.</li>
<li>A DBMS knows more about the data being processed (the OS cannot decode the file contents) and can do better than OS.</li>
<li>Can still use some OS operations:
<ul class="org-ul">
<li><code>madvise</code>: tell the OS when DBMS is planning on reading some page.</li>
<li><code>mlock</code>: tell the OS to not swap ranges outs of disk.</li>
<li><code>msync</code>: tell the OS to flush memory ranges out to disk, i.e., write.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org5b56588" class="outline-2">
<h2 id="org5b56588"><span class="section-number-2">3.</span> Database pages</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Usually fixed-sized blocks of data.</li>
<li>Can contain different data types, e.g., tuples, indexes; data of different types are usually not mixed within the same page.</li>
<li>Some DBMS requires each page is self-contained, i.e., a tuple does not point to another page.</li>
<li>Each page is given a unique id, which can be mapped to the file path and offset to find the page.</li>
</ul>
</div>
<div id="outline-container-orgd1b9e67" class="outline-3">
<h3 id="orgd1b9e67"><span class="section-number-3">3.1.</span> Hardware page</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>The storage that a device guarantees an atomic write, i.e., if the hardware page is 4KB and the DBMS tries to write 4KB to the disk, either all 4KB is written or none is.</li>
<li>If the database page is larger than the hardware page, the DBMS requires extra measures to ensure the writing atomicity itself.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgf7c89de" class="outline-2">
<h2 id="orgf7c89de"><span class="section-number-2">4.</span> Database heap</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>A heap file (e.g., a table) is an unordered collection of pages where tuples are stored in random order.</li>
<li>To locate a page in a heap file, a DBMS can use either a linked list or a page directory.
<ul class="org-ul">
<li>Linked list: the header page holds a pointer to a list of data and free pages; require a sequential scan when finding a specific page.</li>
<li>Page directory: a DBMS uses special pages to track the location of each data page and the free space in database files.
<ul class="org-ul">
<li>All changes to the page directory must be recorded on disk to allow the DBMS to find on restart.</li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org7d4bcf8" class="outline-2">
<h2 id="org7d4bcf8"><span class="section-number-2">5.</span> Page layout</h2>
<div class="outline-text-2" id="text-5">
<ul class="org-ul">
<li>Each page includes a header to record the page meta-data, e.g., page size, checksum, version.</li>
<li>Two main approaches to laying out data in pages: slotted-pages and log-structured.</li>
</ul>
</div>
<div id="outline-container-orga4637bf" class="outline-3">
<h3 id="orga4637bf"><span class="section-number-3">5.1.</span> Slotted-pages</h3>
<div class="outline-text-3" id="text-5-1">
<ul class="org-ul">
<li>The header keeps track of the number of used slots, the offset of the starting of each slot.</li>
<li>When adding a tuple, the slot array grows from the beginning to the end, the tuple data grows from the end to the beginning; the page is full when they meet.</li>
<li>Problems associated with this layout are:
<ul class="org-ul">
<li>Fragmentation: tuple deletions leave gaps in the pages.</li>
<li>Inefficient disk I/O: need to fetch the entire block to update a tuple; users could randomly jump to multiple different pages to update a tuple.</li>
</ul></li>
</ul>


<figure id="orgb5e90fd">
<img src="https://miro.medium.com/v2/resize:fit:935/1*7AuKrdEJQpfRYhavwWzwhg.png" alt="1*7AuKrdEJQpfRYhavwWzwhg.png" align="center" width="400px">

<figcaption><span class="figure-number">Figure 1: </span>Slotted pages (<a href="https://miro.medium.com/v2/resize:fit:935/1*7AuKrdEJQpfRYhavwWzwhg.png">Source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org6a0df02" class="outline-3">
<h3 id="org6a0df02"><span class="section-number-3">5.2.</span> Log-structured</h3>
<div class="outline-text-3" id="text-5-2">
<ul class="org-ul">
<li>Only allows creations of new pages and no overwrites.</li>
<li>Stores the log records of changes to the tuples; the DBMS appends new log entries to an in-memory buffer without checking previous records -&gt; fast writes.</li>
<li>Potentially slow reads; can be optimized by bookkeeping the latest write of each tuple.</li>
</ul>
</div>
<div id="outline-container-org20975f3" class="outline-4">
<h4 id="org20975f3"><span class="section-number-4">5.2.1.</span> Log compaction</h4>
<div class="outline-text-4" id="text-5-2-1">
<ul class="org-ul">
<li>Take only the most recent change for each tuple across several pages.</li>
<li>There is only one entry for each tuple after the compaction, and can be easily sorted by id for faster lookup -&gt; called Sorted String Table (SSTable).</li>
<li>Universal compaction: any log files can be compacted.</li>
<li>Level compaction: level 0 (smallest) files can be compacted to created a level 1 file.</li>
<li>Write amplification issue: for each logical write, there could be multiple physical writes.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org2527d1e" class="outline-3">
<h3 id="org2527d1e"><span class="section-number-3">5.3.</span> Index-organized storage</h3>
<div class="outline-text-3" id="text-5-3">
<ul class="org-ul">
<li>Both page-oriented and log-structured storage rely on additional index to find a tuple since tables are inherently unsorted.</li>
<li>In an index-organized storage scheme, the DBMS stores tuples as the value of an index data structure.</li>
<li>E.g., In a B-tree indexed DBMS, the index (i.e., primary keys) are stored as the intermediate nodes, and the data is stored in the leaf nodes.</li>
</ul>


<figure id="org705d6b3">
<img src="https://docs.oracle.com/en/database/oracle/oracle-database/21/cncpt/img/cncpt272.gif" alt="cncpt272.gif" align="center" width="400px">

<figcaption><span class="figure-number">Figure 2: </span>Index-organized storage (<a href="https://docs.oracle.com/en/database/oracle/oracle-database/21/cncpt/img/cncpt272.gif">Source</a>)</figcaption>
</figure>
</div>
</div>
</div>
<div id="outline-container-org6c3f4d5" class="outline-2">
<h2 id="org6c3f4d5"><span class="section-number-2">6.</span> Tuple layout</h2>
<div class="outline-text-2" id="text-6">
<ul class="org-ul">
<li>Tuple: a sequence of bytes for a DBMS to decode.</li>
<li>Tuple header: contains tuple meta-data, e.g., visibility information (which transactions write the tuple).</li>
<li>Tuple data: cannot exceed the size of a page.</li>
<li>Unique id: usually page id + offset/slot; an application cannot rely on it to mean anything.</li>
</ul>
</div>
<div id="outline-container-org5d23441" class="outline-3">
<h3 id="org5d23441"><span class="section-number-3">6.1.</span> Denormalized tuple data</h3>
<div class="outline-text-3" id="text-6-1">
<ul class="org-ul">
<li>If two tables are related, a DBMS can &ldquo;pre-join&rdquo; them so that the tables are on the same page.</li>
<li>The read is faster since only one page is required to load, but the write is more expensive since a tuple needs more space (<b><b>not free lunch in DB system!</b></b>).</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org0fd4658" class="outline-2">
<h2 id="org0fd4658"><span class="section-number-2">7.</span> Data representation</h2>
<div class="outline-text-2" id="text-7">
<ul class="org-ul">
<li>A data representation scheme specifies how a DBMS stores the bytes of a tuple.</li>
<li>Tuples can be word-aligned via padding or attribute reordering to make sure the CPU can access a tuple without unexpected behavior.</li>
<li>5 high level data types stored in a tuple: integer, variable-precision numbers, fixed-point precision numbers, variable length values, dates/times.</li>
</ul>
</div>
<div id="outline-container-org6f4a717" class="outline-3">
<h3 id="org6f4a717"><span class="section-number-3">7.1.</span> Integers</h3>
<div class="outline-text-3" id="text-7-1">
<ul class="org-ul">
<li>Fixed length, usually stored using the DBMS native C/C++ types.</li>
<li>E.g., <code>INTEGER</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-org02ff80e" class="outline-3">
<h3 id="org02ff80e"><span class="section-number-3">7.2.</span> Variable precision numbers</h3>
<div class="outline-text-3" id="text-7-2">
<ul class="org-ul">
<li>Inexact, variable-precision numeric types; fast than arbitrary precision numbers.</li>
<li>Could have rounding errors.</li>
<li>E.g., <code>REAL</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-org38805ab" class="outline-3">
<h3 id="org38805ab"><span class="section-number-3">7.3.</span> Fixed-point precision numbers</h3>
<div class="outline-text-3" id="text-7-3">
<ul class="org-ul">
<li>Arbitrary precision data type stored in exact, variable-length binary representation (almost like a string) with additional meta-data (e.g., length, decimal position).</li>
<li>E.g., <code>DECIMAL</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-org2cf83e4" class="outline-3">
<h3 id="org2cf83e4"><span class="section-number-3">7.4.</span> Variable-length data</h3>
<div class="outline-text-3" id="text-7-4">
<ul class="org-ul">
<li>Represent data of arbitrary length, usually stored with a header to keep the track of the length and the checksum.</li>
<li>Overflowed data is stored on a special overflow page referenced by the tuple, the overflow page can also contain pointers to next overflow pages.</li>
<li>Some DBMS allows to store files (e.g., photos) externally, but the DBMS cannot modify them.</li>
<li>E.g., <code>BLOB</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-org9a6f19d" class="outline-3">
<h3 id="org9a6f19d"><span class="section-number-3">7.5.</span> Dates/Times</h3>
<div class="outline-text-3" id="text-7-5">
<ul class="org-ul">
<li>Usually represented as unit time, e.g., micro/milli-seconds.</li>
<li>E.g., <code>TIMESTAMP</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-org1f49635" class="outline-3">
<h3 id="org1f49635"><span class="section-number-3">7.6.</span> Null</h3>
<div class="outline-text-3" id="text-7-6">
<ul class="org-ul">
<li>3 common approaches to represent nulls:
<ul class="org-ul">
<li>Most common: store a bitmap in a centralized header to specify which attributes are null.</li>
<li>Designate a value, e.g., <code>INT32_MIN</code>.</li>
<li>Not recommended: store a flag per attribute to mark a value is null; may need more bits to ensure word alignment.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orge4bd207" class="outline-2">
<h2 id="orge4bd207"><span class="section-number-2">8.</span> System catalogs</h2>
<div class="outline-text-2" id="text-8">
<ul class="org-ul">
<li>A DBMS maintains an internal catalog table for the table meta-data, e.g., tables/columns, user permissions, table statistics.</li>
<li>Bootstrapped by special code.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-database.html">database</a> <a href="https://chenyo.me/tag-cmu.html">cmu</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[database]]></category>
  <category><![CDATA[cmu]]></category>
  <link>https://chenyo.me/2024-07-31-db-notes:-database-storage.html</link>
  <guid>https://chenyo.me/2024-07-31-db-notes:-database-storage.html</guid>
  <pubDate>Wed, 31 Jul 2024 18:26:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Ethereum Merkle Patricia Trie]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org96df500">1. Blockchain fundamentals</a>
<ul>
<li><a href="#orgdc45558">1.1. RLP (Recursive Length Prefix)</a></li>
<li><a href="#org48d9faf">1.2. Merkle tree</a>
<ul>
<li><a href="#org0a936db">1.2.1. Complexity for \(N\) items.</a></li>
</ul>
</li>
<li><a href="#org4f18754">1.3. Patricia tree</a></li>
<li><a href="#orgcb1f482">1.4. Merkle Patricia Tree (MPT)</a>
<ul>
<li><a href="#org6678635">1.4.1. Prefix byte</a></li>
<li><a href="#org16b7883">1.4.2. Complexity for \(N\) items and key length \(K\)</a></li>
</ul>
</li>
<li><a href="#org919c8bd">1.5. Rollup state tree</a></li>
<li><a href="#orga5579af">1.6. PoI for Verkle tree (see MegaETH post for details)</a></li>
<li><a href="#orga757831">1.7. Polynomial/KZG commitment</a></li>
</ul>
</li>
<li><a href="#orgbddde28">2. Ethereum MPT data structure</a></li>
<li><a href="#org9d30c50">3. Ethereum MPT Functionality</a></li>
<li><a href="#orga8bf675">4. Proof of inclusion</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note of Ethereum Merkle Patricia Trie (MPT), resources are from:
</p>
<ul class="org-ul">
<li><a href="https://github.com/zhangchiqing/merkle-patricia-trie?tab=readme-ov-file">Simplified Go implementation of Ethereum MPT (2022)</a></li>
<li><a href="https://www.youtube.com/watch?v=Qn6sFmo8xGo">Blockchain trees Youtube (2022)</a></li>
<li><a href="https://claude.ai/chat/a3ee5b1f-4d83-46c1-b681-d2d7b170c7e1">Claude.ai</a></li>
</ul>
<div id="outline-container-org96df500" class="outline-2">
<h2 id="org96df500"><span class="section-number-2">1.</span> Blockchain fundamentals</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-orgdc45558" class="outline-3">
<h3 id="orgdc45558"><span class="section-number-3">1.1.</span> RLP (Recursive Length Prefix)</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>A serialization method to encode arbitrarily nested arrays of binary data.</li>
<li>RLP provides a simple (e.g., no type), space-efficient and deterministic encoding.</li>
</ul>
</div>
</div>
<div id="outline-container-org48d9faf" class="outline-3">
<h3 id="org48d9faf"><span class="section-number-3">1.2.</span> Merkle tree</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Used in Bitcoin to simplify proof of inclusion (PoI) of a transaction.</li>
<li>If one computes the hash of an array of \(N\):
<ul class="org-ul">
<li>Construction complexity: \(O(n)\) time and space.</li>
<li>PoI complexity: \(O(n)\) time and space (needs all other items).</li>
</ul></li>
</ul>
</div>
<div id="outline-container-org0a936db" class="outline-4">
<h4 id="org0a936db"><span class="section-number-4">1.2.1.</span> Complexity for \(N\) items.</h4>
<div class="outline-text-4" id="text-1-2-1">
<ul class="org-ul">
<li>Construction: \(O(2n)\) time and space.</li>
<li>PoI complexity:
<ul class="org-ul">
<li>\(O(logN)\) space: PoI requires one hash from each level from the leaf to the root (the Merkle tree is binary).</li>
<li>\(O(logN)\) time: \(O(logN)\) to collect all hashes, and \(O(logN)\) to generate the proof.</li>
</ul></li>
</ul>


<figure id="org70b3fc7">
<img src="https://blockonomi.com/wp-content/uploads/2018/06/merkle-tree.jpg" alt="merkle-tree.jpg" align="center" width="500px">

<figcaption><span class="figure-number">Figure 1: </span>Bitcoin Merkle Tree (<a href="https://blockonomi.com/wp-content/uploads/2018/06/merkle-tree.jpg">source</a>)</figcaption>
</figure>
</div>
</div>
</div>
<div id="outline-container-org4f18754" class="outline-3">
<h3 id="org4f18754"><span class="section-number-3">1.3.</span> Patricia tree</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>Trie: a data structure that stores key-value pair in a key&rsquo;s prefix tree.</li>
<li>Patricia tree: compress trie by merging nodes on the same path.</li>
<li>The structure the Patricia tree is independent of the item insertion order.</li>
<li>The time complexity for add, query and deletion is \(O(K)\), where \(K\) is the key length.</li>
</ul>


<figure id="orga05f50e">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Patricia_trie.svg/525px-Patricia_trie.svg.png" alt="525px-Patricia_trie.svg.png" align="center" width="400px">

<figcaption><span class="figure-number">Figure 2: </span>Patricia Tree (<a href="https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Patricia_trie.svg/525px-Patricia_trie.svg.png">source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-orgcb1f482" class="outline-3">
<h3 id="orgcb1f482"><span class="section-number-3">1.4.</span> Merkle Patricia Tree (MPT)</h3>
<div class="outline-text-3" id="text-1-4">
<ul class="org-ul">
<li>MPT is a hex-ary Merkle tree with an additional DB for hash lookup.</li>
<li>There are 4 types of nodes:
<ul class="org-ul">
<li>Empty node: the null node the root points to when first creating the tree.</li>
<li>Leaf node: stores the real data, e.g., account balance.</li>
<li>Branch node: stores the pointers to at most 16 other nodes, e.g., they have the common prefix (nibbles) before and differ at the current <b><b>nibble</b></b> (4 bit,0-f).</li>
<li>Extension node: record the compressed common prefix for a branch node.</li>
</ul></li>
<li>Each <b><b>pointer</b></b> in the tree is the <b><b>hash value</b></b> of the child node; the real node data is stored in a separate DB that maps from a node hash to its data.</li>
<li>If the child node is small, the parent node could also directly store the node data rather than the hash pointer.</li>
<li>In practical implementation, the <b><b>entire tree</b></b> is typically stored in a KV DB, and each node is stored with its hash as the key.</li>
</ul>


<figure id="orgc8f7bd8">
<img src="https://github.com/zhangchiqing/merkle-patricia-trie/raw/master/diagrams/4_add_4th_tx_kv.png" alt="4_add_4th_tx_kv.png" align="center" width="400px">

<figcaption><span class="figure-number">Figure 3: </span>MPT DB storage (<a href="https://github.com/zhangchiqing/merkle-patricia-trie/raw/master/diagrams/4_add_4th_tx_kv.png">source</a>)</figcaption>
</figure>
</div>
<div id="outline-container-org6678635" class="outline-4">
<h4 id="org6678635"><span class="section-number-4">1.4.1.</span> Prefix byte</h4>
<div class="outline-text-4" id="text-1-4-1">
<ul class="org-ul">
<li>Identify both the node type and the parity of the stored nibbles.</li>
<li>Leaf node: 2 if the <code>key-end</code> has even number of nibbles, e.g., the compressed ending of an account; 3X if the number is odd (so the last 4-bit is stored as X in the prefix).</li>
<li>Extension: 0 if the <code>shared nibbles</code> has even number; 1X if has odd number.</li>
</ul>
</div>
</div>
<div id="outline-container-org16b7883" class="outline-4">
<h4 id="org16b7883"><span class="section-number-4">1.4.2.</span> Complexity for \(N\) items and key length \(K\)</h4>
<div class="outline-text-4" id="text-1-4-2">
<ul class="org-ul">
<li>Construction:
<ul class="org-ul">
<li>Time: worst \(O(NK)\); average: \(O(Nlog_{16}N)\).</li>
<li>Space: \(O(N)\).</li>
</ul></li>
<li>Indexing (e.g., query an account balance):
<ul class="org-ul">
<li>Time: tree traversal worst \(O(K)\), average \(O(log_{16}N)\); <b><b>each traversal equals a DB query</b></b>.</li>
</ul></li>
<li>PoI: \(O(16log_{16}N)\) time and space.
<ul class="org-ul">
<li>Calculating the hash of a branch node requires the hash of all 16 child nodes.</li>
</ul></li>
</ul>


<figure id="orge104ac3">
<img src="https://i.sstatic.net/YZGxe.png" alt="YZGxe.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 4: </span>Merkle Patricia Tree (<a href="https://i.sstatic.net/YZGxe.png">source</a>)</figcaption>
</figure>
</div>
</div>
</div>
<div id="outline-container-org919c8bd" class="outline-3">
<h3 id="org919c8bd"><span class="section-number-3">1.5.</span> Rollup state tree</h3>
<div class="outline-text-3" id="text-1-5">
<ul class="org-ul">
<li>Rollup has a higher performance requirement for PoI.</li>
<li><b><b>Separate</b></b> the indexing and PoI with a sorted key-value arrays and a (binary) Merkle tree.
<ul class="org-ul">
<li>MPT: <code>{Addr0: State0, Addr1: State1,...}</code>.</li>
<li>Rollup: map: <code>{Addr0: Id0, Addr1: Id1,...}</code> + array: <code>[(Addr0, State0), (Addr1, State1),...]</code>.</li>
</ul></li>
<li>When a client wants to query an account, it first gets the key id from the map, then get the state from the array.</li>
<li>When a node wants to generate PoI, it follows the merkle path and collect hashes (more hashes than MPT).</li>
</ul>
</div>
</div>
<div id="outline-container-orga5579af" class="outline-3">
<h3 id="orga5579af"><span class="section-number-3">1.6.</span> PoI for Verkle tree (see <a href="https://chenyo-17.github.io/org-static-blog/2024-07-04-parallel-evm:-megaeth.html">MegaETH post</a> for details)</h3>
<div class="outline-text-3" id="text-1-6">
<ul class="org-ul">
<li>Stateless light nodes get a witness along with the new block, the witness is a PoI for the state change in the block.</li>
<li>Light nodes download related state information, e.g., changed account from other full nodes, or from the portal network.</li>
</ul>
</div>
</div>
<div id="outline-container-orga757831" class="outline-3">
<h3 id="orga757831"><span class="section-number-3">1.7.</span> Polynomial/KZG commitment</h3>
<div class="outline-text-3" id="text-1-7">
<ul class="org-ul">
<li>In MPT, PoI for a branch node requires the hash values of all branches.</li>
<li>KZG commitment reduce the proof size by adding a polynomial formula \(f(x)\) in the branch node, and each branch has a point \((x, y)\) such that \(y = f(x)\).</li>
<li>In this way, the proof no longer requires hashes of other branches, the proof space complexity \(O(log_{16}N)\) (no 16 coefficient).</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgbddde28" class="outline-2">
<h2 id="orgbddde28"><span class="section-number-2">2.</span> Ethereum MPT data structure</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Essentially is a key-value mapping; it provides <code>Get</code>, <code>Put</code> and <code>Del</code> functions.</li>
<li>Ethereum has 3 MPTs: transaction trie; receipt trie and state trie, each trie root hash is included in the block header.
<ul class="org-ul">
<li><code>transactionTrie</code>: all transactions included in the block.
<ul class="org-ul">
<li>The keys are the RLP encodings of an unsigned integer starting from 0.</li>
<li>The values are the RLP encodings of the transaction.</li>
</ul></li>
<li><code>stateTrie</code>: all account states in the network.</li>
<li><code>receiptTrie</code>: the outcomes of all transaction executions in the block, e.g., gas used, transaction status.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org9d30c50" class="outline-2">
<h2 id="org9d30c50"><span class="section-number-2">3.</span> Ethereum MPT Functionality</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Allows to verify <b><b>data integrity</b></b> with the <code>Hash</code> function to compute the Merkle root hash.</li>
<li>Allows to verify the <b><b>inclusion</b></b> of a key-value pair without the access to the entire key-value pairs.
<ul class="org-ul">
<li>A full node provide a merkle proof <code>Proof</code> for a key-value pair (e.g., an account and its balance).</li>
<li>A light node can verify a proof only against the root hash with <code>VerifyProf(rootHash, key, proof)</code>; if the proof does not match the hash (e.g., the balance mismatches), an error is thrown.</li>
</ul></li>
<li>Why would a light node trust the root hash: it trusts the consensus mechanism, e.g., other benign full nodes verify the hash, act honestly is more profitable.</li>
</ul>
</div>
</div>
<div id="outline-container-orga8bf675" class="outline-2">
<h2 id="orga8bf675"><span class="section-number-2">4.</span> Proof of inclusion</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>Proof: the path from the root to the leaf node.</li>
<li>Verification: start from the root, decode the node to match the nibbles until find the node that matches all the remaining nibbles; if not found, the proof is invalid.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-evm.html">evm</a> <a href="https://chenyo.me/tag-trie.html">trie</a> </div>]]></description>
  <category><![CDATA[evm]]></category>
  <category><![CDATA[trie]]></category>
  <link>https://chenyo.me/2024-07-28-ethereum-merkle-patricia-trie.html</link>
  <guid>https://chenyo.me/2024-07-28-ethereum-merkle-patricia-trie.html</guid>
  <pubDate>Sun, 28 Jul 2024 09:34:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[End of my first German course]]></title>
  <description><![CDATA[
<p>
It&rsquo;s been a while since I wanted to document my experience in my German course.
Now, having completed the first month, there couldn&rsquo;t be a better time to do so.
</p>

<p>
Initially, I approached the course with some dissatisfaction.
The pace felt too slow, and I was critical of my teacher&rsquo;s methods.
Boredom and impatience set in as I waited for others to catch up.
</p>

<p>
But then I began interacting with my classmates, and I had the chance to hear a different world.
</p>

<p>
One of the first people I met was a talkative Ukrainian woman.
When she is not satisfied with something, she interrupts and shouts.
She knows a lot about healthcare, and she told me this and that about refugee polices.
I admire her enviable energy.
</p>

<p>
When I first walked in the classroom, I noticed a young man who already spoke rapid German.
I asked him how he did it and he said since he started learning German four months ago, he only spoke German.
He is smart and also speaks English, Turkish and Afghanistan.
His experience reminds me a lot of the book &ldquo;The New Odyssey&rdquo;, and I am curious about more of his stories.
He is only 19 years old, I believe a bright future awaits him.
</p>


<figure id="org8f19a32">
<img src="https://m.media-amazon.com/images/I/71oHotKSYQL._AC_UF1000,1000_QL80_.jpg" alt="71oHotKSYQL._AC_UF1000,1000_QL80_.jpg" align="center" width="300px">

<figcaption><span class="figure-number">Figure 1: </span>The New Odyssey</figcaption>
</figure>

<p>
The man sitting next to me has a political asylum visa.
He was a political journalist not welcomed by the government.
He said so he lived at the borderline for many years before he came here.
He is no longer young and it was his second time to take the same course.
He has a beautiful handwriting.
</p>

<p>
Another young man I know a bit comes from Latin America, he often dozes off in the class due to his Uber delivery job.
I also met a young lady from Turkey, she is so charming with a wonderful personality.
There are also two resilient mothers who undertake childcare with their studies.
</p>

<p>
In the last week I finally got to know my teacher a bit.
He told us he worked 220 hours a month at the moment so that he can pay his expense for he and his girlfriend, and he used to work even more.
He said he had different trainings in different countries, and now he finally got a new passport.
He shared with us different information that help foreigners maintain a basic life here.
</p>

<p>
In the end, I still think the course is too easy for me, who has spent twenty years staying in schools.
But I wish I had talked more with everyone about their lives.
So many people come here, and each finds their own way to stay and live.
Life is always hard but also incredible, and I wish I don&rsquo;t ever forget it.
</p>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-personal.html">personal</a> <a href="https://chenyo.me/tag-german.html">german</a> </div>]]></description>
  <category><![CDATA[personal]]></category>
  <category><![CDATA[german]]></category>
  <link>https://chenyo.me/2024-07-27-finish-my-first-month-german-course.html</link>
  <guid>https://chenyo.me/2024-07-27-finish-my-first-month-german-course.html</guid>
  <pubDate>Sat, 27 Jul 2024 00:28:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Parallel EVM: Reth scaling plan]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org14e43c3">1. Blockchain fundamentals</a>
<ul>
<li><a href="#org2ed73c3">1.1. Ethereum engine API</a></li>
<li><a href="#org4eecc0e">1.2. Foundry</a></li>
<li><a href="#orgada97c2">1.3. Revm</a></li>
<li><a href="#org7979b64">1.4. Alloy</a></li>
<li><a href="#orgada29d4">1.5. Erigon &amp; Staged sync</a></li>
<li><a href="#org485b8d9">1.6. Storage engines</a>
<ul>
<li><a href="#org74d55ea">1.6.1. ACID</a></li>
<li><a href="#org6a4e519">1.6.2. MVCC (Multi-version concurrency control)</a></li>
<li><a href="#org0552070">1.6.3. Common database models</a></li>
<li><a href="#org67478c1">1.6.4. Common storage engines</a></li>
</ul>
</li>
<li><a href="#org7333675">1.7. Reth</a></li>
<li><a href="#org669fdff">1.8. Why gas per second as the performance metric</a></li>
<li><a href="#orgbd41f95">1.9. EVM cost models</a></li>
<li><a href="#org576a1be">1.10. TPC benchmark</a></li>
<li><a href="#org23607f8">1.11. State growth</a></li>
<li><a href="#orgdba6eb1">1.12. JIT (Just-In-Time) and AOT (Ahead-of-Time) EVM</a></li>
<li><a href="#org0fe236b">1.13. Actor model</a></li>
<li><a href="#org67c1822">1.14. Storage trie</a></li>
<li><a href="#org95ef93e">1.15. Serverless database</a></li>
</ul>
</li>
<li><a href="#org7610d61">2. Reth scaling plan</a>
<ul>
<li><a href="#orgbc723d9">2.1. Vertical scaling (2024)</a>
<ul>
<li><a href="#orgfbcc5f1">2.1.1. JIT/AOT EVM</a></li>
<li><a href="#orgb36991e">2.1.2. Parallel EVM</a></li>
<li><a href="#org9cd06d3">2.1.3. Optimized state commitment</a></li>
</ul>
</li>
<li><a href="#orgfa94edc">2.2. Horizontal scaling (2025)</a>
<ul>
<li><a href="#org4619f9b">2.2.1. Multi-Rollup (?)</a></li>
<li><a href="#orgb569cc7">2.2.2. Cloud-Native nodes.</a></li>
</ul>
</li>
<li><a href="#org8f4e1f7">2.3. Open questions</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for <a href="https://www.paradigm.xyz/2024/04/reth-perf">Reth-performance-blog</a> as well as some terminology explain online, e.g., <a href="https://github.com/paradigmxyz/reth">Reth-repo</a> and <a href="https://claude.ai/chat/6364436f-d279-4c6b-947e-237bfea26409">Claude.ai</a>.
</p>
<div id="outline-container-org14e43c3" class="outline-2">
<h2 id="org14e43c3"><span class="section-number-2">1.</span> Blockchain fundamentals</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org2ed73c3" class="outline-3">
<h3 id="org2ed73c3"><span class="section-number-3">1.1.</span> <a href="https://github.com/ethereum/execution-apis/blob/a0d03086564ab1838b462befbc083f873dcf0c0f/src/engine/paris.md">Ethereum engine API</a></h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>A collection of JSON-RPC methods that all execution clients implement.</li>
<li>Specify the interfaces between consensus and execution layers.</li>
</ul>
</div>
</div>
<div id="outline-container-org4eecc0e" class="outline-3">
<h3 id="org4eecc0e"><span class="section-number-3">1.2.</span> <a href="https://github.com/foundry-rs/foundry/">Foundry</a></h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>A Rust-written toolkit for Ethereum application development.</li>
<li>Consists of an Ethereum testing framework Forge; a framework to interact with the chain Cast; a local Ethereum node Anvil; and a Solidity REPL (Read-Eval-Print-Loop: an interactive environment) Chisel.</li>
</ul>
</div>
</div>
<div id="outline-container-orgada97c2" class="outline-3">
<h3 id="orgada97c2"><span class="section-number-3">1.3.</span> <a href="https://github.com/bluealloy/revm/">Revm</a></h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>A Rust-written EVM; responsible for executing transactions and contracts.</li>
</ul>
</div>
</div>
<div id="outline-container-org7979b64" class="outline-3">
<h3 id="org7979b64"><span class="section-number-3">1.4.</span> <a href="https://github.com/alloy-rs">Alloy</a></h3>
<div class="outline-text-3" id="text-1-4">
<ul class="org-ul">
<li>A library to interact with the Ethereum and other EVM-base chains.</li>
</ul>
</div>
</div>
<div id="outline-container-orgada29d4" class="outline-3">
<h3 id="orgada29d4"><span class="section-number-3">1.5.</span> <a href="https://erigon.tech/">Erigon</a> &amp; Staged sync</h3>
<div class="outline-text-3" id="text-1-5">
<ul class="org-ul">
<li>Erigon: a Go-written Ethereum client implementation (execution layer).</li>
<li>Staged sync: break the chain synchronization process into distinct stages in order to achieve better efficiency.</li>
</ul>
</div>
</div>
<div id="outline-container-org485b8d9" class="outline-3">
<h3 id="org485b8d9"><span class="section-number-3">1.6.</span> Storage engines</h3>
<div class="outline-text-3" id="text-1-6">
</div>
<div id="outline-container-org74d55ea" class="outline-4">
<h4 id="org74d55ea"><span class="section-number-4">1.6.1.</span> ACID</h4>
<div class="outline-text-4" id="text-1-6-1">
<ul class="org-ul">
<li>A set of properties for database transactions: atomicity, consistency, isolation, duration.</li>
<li>Atomicity: a transaction is treated as an indivisible unit; if any part of the transaction fails, the entire transaction is rolled back.</li>
<li>Consistency: a transaction brings the database from one valid state to another.</li>
<li>Isolation: concurrent transaction execution leave the database in the same state as if transactions are executed sequentially</li>
<li>Duration: a committed transaction remains committed even when the system fails.</li>
</ul>
</div>
</div>
<div id="outline-container-org6a4e519" class="outline-4">
<h4 id="org6a4e519"><span class="section-number-4">1.6.2.</span> MVCC (Multi-version concurrency control)</h4>
<div class="outline-text-4" id="text-1-6-2">
<ul class="org-ul">
<li>A concurrency control model used in DBMS.</li>
<li>MVCC keeps multiple version of data simultaneously, each transaction sees a snapshot of the database.</li>
</ul>
</div>
</div>
<div id="outline-container-org0552070" class="outline-4">
<h4 id="org0552070"><span class="section-number-4">1.6.3.</span> Common database models</h4>
<div class="outline-text-4" id="text-1-6-3">
<ul class="org-ul">
<li>Relational model, e.g., SQL.</li>
<li>Document model.</li>
<li>Network model.</li>
<li>key-value, e.g., NoSQL.</li>
</ul>
</div>
</div>
<div id="outline-container-org67478c1" class="outline-4">
<h4 id="org67478c1"><span class="section-number-4">1.6.4.</span> Common storage engines</h4>
<div class="outline-text-4" id="text-1-6-4">
<ul class="org-ul">
<li>MDBX: Ultra-fate key-value embedded database with ACID and MVCC supported.</li>
<li>LevelDB: Google-developed key-value store using log-structured merge-tree for high write throughput.</li>
<li>RocksDB: Meta&rsquo;s fork of LevelDB, optimized for fast storage.</li>
<li>LSM-based DBs, e.g., BadgerDB: optimized for write-heavy workloads with log-structured merge-tree.</li>
<li>BoltDB: Go-written key-value database with optimized B+ tree, ACID supported.</li>
<li>LMDB: memory-mapped key-value store with ACID and MVCC supported.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org7333675" class="outline-3">
<h3 id="org7333675"><span class="section-number-3">1.7.</span> Reth</h3>
<div class="outline-text-3" id="text-1-7">
<ul class="org-ul">
<li>A Rust implementation of an Ethereum full node; allows users to interact with the Ethereum blockchain.</li>
<li>An execution layer that implements all Ethereum engine APIs.</li>
<li>Modularity: every component is built as a library.</li>
<li>Performance: uses Erigon staged-sync node architecture and other Rust libraries (e.g., Alloy, revm); tests and optimizes on Foundry.</li>
<li>Database/Storage engine: MDBX.</li>
</ul>
</div>
</div>
<div id="outline-container-org669fdff" class="outline-3">
<h3 id="org669fdff"><span class="section-number-3">1.8.</span> Why gas per second as the performance metric</h3>
<div class="outline-text-3" id="text-1-8">
<ul class="org-ul">
<li>More nuanced than TPS.</li>
<li>Allows for a clear understanding for the capacity and efficiency.</li>
<li>Helps assessing the cost implications, e.g., DoS attacks.</li>
</ul>
</div>
</div>
<div id="outline-container-orgbd41f95" class="outline-3">
<h3 id="orgbd41f95"><span class="section-number-3">1.9.</span> EVM cost models</h3>
<div class="outline-text-3" id="text-1-9">
<ul class="org-ul">
<li>Determines the computational and storage costs for the execution.</li>
<li>Key aspects: gas, gas cost (for each operation), gas price (in Wei), gas limit.</li>
</ul>
</div>
</div>
<div id="outline-container-org576a1be" class="outline-3">
<h3 id="org576a1be"><span class="section-number-3">1.10.</span> TPC benchmark</h3>
<div class="outline-text-3" id="text-1-10">
<ul class="org-ul">
<li>Standardized performance tests for transaction processing and databases, e.g., how many transactions a system can process in a given period.</li>
<li>Offer benchmarks for different scenarios, e.g., TPC-C for online transaction processing.</li>
</ul>
</div>
</div>
<div id="outline-container-org23607f8" class="outline-3">
<h3 id="org23607f8"><span class="section-number-3">1.11.</span> State growth</h3>
<div class="outline-text-3" id="text-1-11">
<ul class="org-ul">
<li>State: the set of data for building and validating new Ethereum blocks.</li>
<li>State growth: the accumulation of new account and new contract storage.</li>
</ul>
</div>
</div>
<div id="outline-container-orgdba6eb1" class="outline-3">
<h3 id="orgdba6eb1"><span class="section-number-3">1.12.</span> JIT (Just-In-Time) and AOT (Ahead-of-Time) EVM</h3>
<div class="outline-text-3" id="text-1-12">
<ul class="org-ul">
<li>JIT: convert bytecode to native machine code just before execution to bypass the VM&rsquo;s interpretative process.</li>
<li>AOT: compile the highest demand contracts and store them on disk, to avoid untrusted bytecode absuing native-code compilation.</li>
</ul>
</div>
</div>
<div id="outline-container-org0fe236b" class="outline-3">
<h3 id="org0fe236b"><span class="section-number-3">1.13.</span> Actor model</h3>
<div class="outline-text-3" id="text-1-13">
<ul class="org-ul">
<li>A paradigm/framework for designing distributed systems.</li>
<li>Actor: each actor is an independent entity to receive, process and send messages; create new actors or modify its state.</li>
</ul>
</div>
</div>
<div id="outline-container-org67c1822" class="outline-3">
<h3 id="org67c1822"><span class="section-number-3">1.14.</span> Storage trie</h3>
<div class="outline-text-3" id="text-1-14">
<ul class="org-ul">
<li>Each contract account has its own storage trie, which is usually stored in a KV database.</li>
</ul>
</div>
</div>
<div id="outline-container-org95ef93e" class="outline-3">
<h3 id="org95ef93e"><span class="section-number-3">1.15.</span> Serverless database</h3>
<div class="outline-text-3" id="text-1-15">
<ul class="org-ul">
<li>Allow developers to focus on writing queries without managing database servers.</li>
<li>Automatically scales up or down base on the workload.</li>
<li>Pay-per-use pricing.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org7610d61" class="outline-2">
<h2 id="org7610d61"><span class="section-number-2">2.</span> Reth scaling plan</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Current status (April 2024): achieves 100-200 mg/s during live sync, including sender recovery, transaction execution and block trie calculation.</li>
<li>The scaling plan does not involve solving state growth.</li>
</ul>
</div>
<div id="outline-container-orgbc723d9" class="outline-3">
<h3 id="orgbc723d9"><span class="section-number-3">2.1.</span> Vertical scaling (2024)</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>Optimize how each system handle transactions and data.</li>
</ul>
</div>
<div id="outline-container-orgfbcc5f1" class="outline-4">
<h4 id="orgfbcc5f1"><span class="section-number-4">2.1.1.</span> JIT/AOT EVM</h4>
<div class="outline-text-4" id="text-2-1-1">
<ul class="org-ul">
<li>Reduce EVM interpreter overhead to speed up single-threaded transaction processing.</li>
<li>The processing costs \(\approx\) 50% EVM time</li>
<li>Released on <a href="https://www.paradigm.xyz/2024/06/revmc">June 2024</a>.</li>
</ul>


<figure id="orgfb3dde8">
<img src="https://www.paradigm.xyz/static/reth-perf/3.png" alt="3.png" align="center" width="500px">

<figcaption><span class="figure-number">Figure 1: </span>The JIT/AOT compiler (<a href="https://www.paradigm.xyz/static/reth-perf/3.png">source</a>)</figcaption>
</figure>
</div>
</div>
<div id="outline-container-orgb36991e" class="outline-4">
<h4 id="orgb36991e"><span class="section-number-4">2.1.2.</span> Parallel EVM</h4>
<div class="outline-text-4" id="text-2-1-2">
<ul class="org-ul">
<li>Utilize multiple cores during EVM execution.</li>
<li>&lt;80% of historical transactions have non-conflicting dependencies.</li>
<li>Historical sync: can calculate the best parallelization schedule offline; an early attempt is <a href="https://github.com/paradigmxyz/reth/tree/rkrasiuk/parallel">available</a>.</li>
<li>Live sync: combine serial and parallel execution based on static analysis, since Block STM has poor performance during heavy state contention periods; an early attempt is <a href="https://github.com/risechain/pevm">available</a>.</li>
</ul>
</div>
</div>
<div id="outline-container-org9cd06d3" class="outline-4">
<h4 id="org9cd06d3"><span class="section-number-4">2.1.3.</span> Optimized state commitment</h4>
<div class="outline-text-4" id="text-2-1-3">
<ul class="org-ul">
<li>Traditional EVM implementation <b><b>couples</b></b> the transaction execution and the state root computation: the state root is updated whenever a transaction updates a trie, since the state root computation has to be sequential from the updated node to the root, this is slow.</li>
<li>Reth <b><b>decouples</b></b> the process: raw state data is stored in KV databases, and each trie is <b><b>re-built</b></b> for each block from the databases in the end.
<ul class="org-ul">
<li>Pro: can use more efficient databases.</li>
<li>Con: need to re-calculate the entire trie, which costs &gt;75% of end-to-end block production time.</li>
</ul></li>
<li>Optimizations:
<ul class="org-ul">
<li>Now already re-calculate the storage trie for each updated contract in parallel.</li>
<li>Can also calculate the account trie when the storage tries are computed.</li>
<li>Pre-fetch cached trie nodes (cached by the state root computation) by tracking updated accounts and storage, e.g., a part of the trie may remain the same hash.</li>
</ul></li>
<li>Going beyond:
<ul class="org-ul">
<li>Only calculate the state root every \(T\) blocks.</li>
<li><b><b>Lag</b></b> the state root computation a few blocks behind to advance executions.</li>
<li>Use a cheaper encoder and hash function (Blake3).</li>
<li>Use wider branch nodes.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgfa94edc" class="outline-3">
<h3 id="orgfa94edc"><span class="section-number-3">2.2.</span> Horizontal scaling (2025)</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li>Spread the workload across multiple systems.</li>
</ul>
</div>
<div id="outline-container-org4619f9b" class="outline-4">
<h4 id="org4619f9b"><span class="section-number-4">2.2.1.</span> Multi-Rollup (?)</h4>
<div class="outline-text-4" id="text-2-2-1">
<ul class="org-ul">
<li>Reduce operational overhead of running multiple rollups.</li>
</ul>
</div>
</div>
<div id="outline-container-orgb569cc7" class="outline-4">
<h4 id="orgb569cc7"><span class="section-number-4">2.2.2.</span> Cloud-Native nodes.</h4>
<div class="outline-text-4" id="text-2-2-2">
<ul class="org-ul">
<li>Deploy the heavy node (e.g., sequencer) as a service stack that can autoscale with compute demand and use cloud storage for persistence.</li>
<li>Similar to serverless database projects, e.g., NeonDB.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org8f4e1f7" class="outline-3">
<h3 id="org8f4e1f7"><span class="section-number-3">2.3.</span> Open questions</h3>
<div class="outline-text-3" id="text-2-3">
<ul class="org-ul">
<li>Second order effects of above changes, e.g., on light clients.</li>
<li>What is the best, average and worst case scenarios for each optimization.</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-evm.html">evm</a> <a href="https://chenyo.me/tag-parallel-evm.html">parallel-evm</a> <a href="https://chenyo.me/tag-reth.html">reth</a> </div>]]></description>
  <category><![CDATA[evm]]></category>
  <category><![CDATA[parallel-evm]]></category>
  <category><![CDATA[reth]]></category>
  <link>https://chenyo.me/2024-07-24-parallel-evm:-reth.html</link>
  <guid>https://chenyo.me/2024-07-24-parallel-evm:-reth.html</guid>
  <pubDate>Wed, 24 Jul 2024 15:54:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[CMU 15-445 notes: Modern SQL]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org8ba4a82">1. Terminology</a>
<ul>
<li><a href="#org3f0d751">1.1. SQL and relational algebra</a></li>
<li><a href="#org5b28cd9">1.2. SQL commands</a></li>
</ul>
</li>
<li><a href="#orgf8c217f">2. SQL syntax</a>
<ul>
<li><a href="#orgee091df">2.1. Join</a></li>
<li><a href="#org452ec55">2.2. Aggregation function</a></li>
<li><a href="#orgdf14d0d">2.3. String operation</a></li>
<li><a href="#orgac555a7">2.4. Date and time</a></li>
<li><a href="#org75cb8c8">2.5. Output redirection</a></li>
<li><a href="#org4e6aed2">2.6. Output control</a></li>
<li><a href="#org94f486f">2.7. Nested queries</a></li>
<li><a href="#orgeba7448">2.8. Window functions</a></li>
<li><a href="#org1728602">2.9. Common Table Expressions (CTE)</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://15445.courses.cs.cmu.edu/fall2022/notes/02-modernsql.pdf">CMU 15-445 L2 notes</a>, along with some SQL command explained by <a href="https://claude.ai/chat/a2f07962-eb31-4f76-9a31-5e408722894b">Claude.ai</a>.
</p>
<div id="outline-container-org8ba4a82" class="outline-2">
<h2 id="org8ba4a82"><span class="section-number-2">1.</span> Terminology</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org3f0d751" class="outline-3">
<h3 id="org3f0d751"><span class="section-number-3">1.1.</span> SQL and relational algebra</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>Relational algebra is based on sets (unordered, no duplicates); SQL is based on bags (unordered, allows duplicates).</li>
<li>SQL is a declarative query language; users use SQL to specify the desired result, each DBMS determines the most efficient strategy to produce the answer.</li>
</ul>
</div>
</div>
<div id="outline-container-org5b28cd9" class="outline-3">
<h3 id="org5b28cd9"><span class="section-number-3">1.2.</span> SQL commands</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Data manipulation language (DML): <code>SELECT</code>, <code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code>.</li>
<li><p>
Data definition language (DDL): <code>CREATE</code>.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #51afef;">CREATE</span> TABLR student (
    sid <span style="color: #ECBE7B;">INT</span> <span style="color: #51afef;">PRIMARY</span> <span style="color: #51afef;">KEY</span>,
    <span style="color: #51afef;">name</span> <span style="color: #ECBE7B;">VARCHAR</span>(<span style="color: #da8548; font-weight: bold;">16</span>),
    login <span style="color: #ECBE7B;">VARCHAR</span>(<span style="color: #da8548; font-weight: bold;">32</span>) <span style="color: #51afef;">UNIQUE</span>,
    age <span style="color: #ECBE7B;">SMALLINT</span>,
    gpa <span style="color: #ECBE7B;">FLOAT</span>
);
</pre>
</div></li>
<li>Data control language (DCL): security, access control.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgf8c217f" class="outline-2">
<h2 id="orgf8c217f"><span class="section-number-2">2.</span> SQL syntax</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-orgee091df" class="outline-3">
<h3 id="orgee091df"><span class="section-number-3">2.1.</span> Join</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li><p>
Combine columns from one or more tables and produces a new table.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #5B6268;">-- </span><span style="color: #5B6268;">All students that get an A in 15-721</span>
<span style="color: #51afef;">SELECT</span> s.<span style="color: #51afef;">name</span>
    <span style="color: #51afef;">FROM</span> enrolled <span style="color: #51afef;">AS</span> e, student <span style="color: #51afef;">AS</span> s
<span style="color: #51afef;">WHERE</span> e.grade = <span style="color: #98be65;">'A'</span> <span style="color: #51afef;">AND</span> e.cid = <span style="color: #98be65;">'15-721'</span>
    <span style="color: #51afef;">AND</span> e.sid = s.sid
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-org452ec55" class="outline-3">
<h3 id="org452ec55"><span class="section-number-3">2.2.</span> Aggregation function</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li><code>AVG(COL)</code>, <code>MIN(COL)</code>, <code>MAX(COL)</code>, <code>COUNT(COL)</code>.</li>
<li><p>
Take as input a bag of tuples and produce a single scalar value.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #5B6268;">-- </span><span style="color: #5B6268;">Get number of students and their average GPA with a '@cs' login</span>
<span style="color: #51afef;">SELECT</span> <span style="color: #c678dd;">AVG</span>(gpa), <span style="color: #c678dd;">COUNT</span>(sid) <span style="color: #51afef;">FROM</span> student <span style="color: #51afef;">WHERE</span> login <span style="color: #51afef;">LIKE</span> <span style="color: #98be65;">'@cs'</span>;
<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">Get the unique students</span>
<span style="color: #51afef;">SELECT</span> <span style="color: #c678dd;">COUNT</span>(<span style="color: #51afef;">DISTINCT</span> login) <span style="color: #51afef;">FROM</span> student <span style="color: #51afef;">WHERE</span> login <span style="color: #51afef;">LIKE</span> <span style="color: #98be65;">'@cs'</span>;
</pre>
</div></li>
<li><p>
Non-aggregated values in <code>SELECT</code> output must appear in <code>GROUP BY</code>.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #5B6268;">-- </span><span style="color: #5B6268;">Get the average GPA in each course</span>
<span style="color: #51afef;">SELECT</span> <span style="color: #c678dd;">AVG</span>(s.gpa), e.cid
    <span style="color: #51afef;">FROM</span> enrolled <span style="color: #51afef;">AS</span> e, student <span style="color: #51afef;">AS</span> s
<span style="color: #51afef;">WHERE</span> e.sid = s.sid
<span style="color: #51afef;">GROUP</span> <span style="color: #51afef;">BY</span> e.cid;
</pre>
</div></li>
<li><p>
<code>HAVING</code>: filter output results based on aggregation computation.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #51afef;">SELECT</span> <span style="color: #c678dd;">AVG</span>(s.gpa), e.cid
    <span style="color: #51afef;">FROM</span> enrolled <span style="color: #51afef;">AS</span> e, student <span style="color: #51afef;">AS</span> s
<span style="color: #51afef;">WHERE</span> e.sid = s.sid
<span style="color: #51afef;">GROUP</span> <span style="color: #51afef;">BY</span> e.cid
<span style="color: #51afef;">HAVING</span> <span style="color: #c678dd;">AVG</span>(s.gpa) &gt; <span style="color: #da8548; font-weight: bold;">3.9</span>;
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orgdf14d0d" class="outline-3">
<h3 id="orgdf14d0d"><span class="section-number-3">2.3.</span> String operation</h3>
<div class="outline-text-3" id="text-2-3">
<ul class="org-ul">
<li>Strings are case sensitive and single-quotes only in the SQL standard.</li>
<li>Use <code>LIKE</code> for string pattern matching:
<ul class="org-ul">
<li><code>%</code> matches any sub-string,</li>
<li><code>_</code> matches any one character</li>
</ul></li>
<li>Standard string functions: <code>UPPER(S)</code>, <code>SUBSTRING(S, B, E)</code>.</li>
<li><code>||</code>: string concatenation.</li>
</ul>
</div>
</div>
<div id="outline-container-orgac555a7" class="outline-3">
<h3 id="orgac555a7"><span class="section-number-3">2.4.</span> Date and time</h3>
<div class="outline-text-3" id="text-2-4">
<ul class="org-ul">
<li>Attributes: <code>DATE</code>, <code>TIME</code>.</li>
<li>Different DBMS have different date/time operations.</li>
</ul>
</div>
</div>
<div id="outline-container-org75cb8c8" class="outline-3">
<h3 id="org75cb8c8"><span class="section-number-3">2.5.</span> Output redirection</h3>
<div class="outline-text-3" id="text-2-5">
<ul class="org-ul">
<li><p>
One can store the results into another table
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #5B6268;">-- </span><span style="color: #5B6268;">output to a non-existing table</span>
<span style="color: #51afef;">SELECT</span> <span style="color: #51afef;">DISTINCT</span> cis <span style="color: #51afef;">INTO</span> CourseIds <span style="color: #51afef;">FROM</span> enrolled;
<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">output to an existing table with the same number of columns and column type</span>
<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">but the names do not matter</span>
<span style="color: #51afef;">INSERT</span> <span style="color: #51afef;">INTO</span> CourseIds (<span style="color: #51afef;">SELECT</span> <span style="color: #51afef;">DISTINCT</span> cid <span style="color: #51afef;">FROM</span> enrolled);
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-org4e6aed2" class="outline-3">
<h3 id="org4e6aed2"><span class="section-number-3">2.6.</span> Output control</h3>
<div class="outline-text-3" id="text-2-6">
<ul class="org-ul">
<li>Use <code>ORDER</code>, <code>ASC</code> and <code>DESC</code> to sort the output tuples; otherwise the output could have different order every time.</li>
<li><p>
Use <code>LIMIT</code>, <code>OFFSET</code> to restrict the output number.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #51afef;">SELECT</span> sid <span style="color: #51afef;">FROM</span> enrolled <span style="color: #51afef;">WHERE</span> cid = <span style="color: #98be65;">'15-721'</span>
<span style="color: #51afef;">ORDER</span> <span style="color: #51afef;">BY</span> <span style="color: #c678dd;">UPPER</span>(grade) <span style="color: #51afef;">DESC</span>, sid + <span style="color: #da8548; font-weight: bold;">1</span> <span style="color: #51afef;">ASC</span>;
    <span style="color: #51afef;">LIMIT</span> <span style="color: #da8548; font-weight: bold;">10</span> OFFSET <span style="color: #da8548; font-weight: bold;">10</span>;  <span style="color: #5B6268;">-- </span><span style="color: #5B6268;">output 10 tuples, starting from the 11th tuple</span>
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-org94f486f" class="outline-3">
<h3 id="org94f486f"><span class="section-number-3">2.7.</span> Nested queries</h3>
<div class="outline-text-3" id="text-2-7">
<ul class="org-ul">
<li>Nested queries are often difficult to optimize.</li>
<li>The inner query can access attributes defined in the outer query.</li>
<li><p>
Inner queries can appear anywhere.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #5B6268;">-- </span><span style="color: #5B6268;">Output a column 'one' with 1s, the number of 1s</span>
<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">equals to the number of rows in 'student'</span>
<span style="color: #51afef;">SELECT</span> (<span style="color: #51afef;">SELECT</span> <span style="color: #da8548; font-weight: bold;">1</span>) <span style="color: #51afef;">AS</span> one <span style="color: #51afef;">FROM</span> student;

<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">Get the names of students that are enrolled in '15-445'</span>
<span style="color: #51afef;">SELECT</span> <span style="color: #51afef;">name</span> <span style="color: #51afef;">FROM</span> students
    <span style="color: #51afef;">WHERE</span> sid <span style="color: #51afef;">IN</span> (
        <span style="color: #51afef;">SELECT</span> sid <span style="color: #51afef;">FROM</span> enrolled
        <span style="color: #51afef;">WHERE</span> cid = <span style="color: #98be65;">'15-445'</span>
);

<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">Get student record with the highest id</span>
<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">that is enrolled in at least one course.</span>
<span style="color: #51afef;">SELECT</span> student.sid, <span style="color: #51afef;">name</span>
    <span style="color: #51afef;">FROM</span> student
    <span style="color: #5B6268;">-- </span><span style="color: #5B6268;">the intermediate output is aliases as max_e</span>
    <span style="color: #51afef;">JOIN</span> (<span style="color: #51afef;">SELECT</span> <span style="color: #c678dd;">MAX</span>(sid) <span style="color: #51afef;">AS</span> sid <span style="color: #51afef;">FROM</span> enrolled) <span style="color: #51afef;">AS</span> max_e
    <span style="color: #5B6268;">-- </span><span style="color: #5B6268;">only select student who has the max_e</span>
    <span style="color: #51afef;">ON</span> student.sid = max_e.sid;

<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">the above is same as below, but `join` syntax is more preferred</span>
<span style="color: #51afef;">SELECT</span> student.sid, <span style="color: #51afef;">name</span>
<span style="color: #51afef;">FROM</span> student <span style="color: #51afef;">AS</span> s, (<span style="color: #51afef;">SELECT</span> <span style="color: #c678dd;">MAX</span>(sid) <span style="color: #51afef;">AS</span> sid <span style="color: #51afef;">FROM</span> enrolled) <span style="color: #51afef;">AS</span> max_e
<span style="color: #51afef;">WHERE</span> s.sid = max_e.sid;
</pre>
</div></li>

<li>Nested query results expression:
<ul class="org-ul">
<li><code>ALL</code>: must satisfy expression for all <b><b>rows</b></b> in sub-query.</li>
<li><code>ANY</code>, <code>IN</code>: must satisfy expression for at least one row in sub-query.</li>
<li><p>
<code>EXISTS</code>: at least one row is returned.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #5B6268;">-- </span><span style="color: #5B6268;">Get all courses with no students enrolled in</span>
<span style="color: #51afef;">SELECT</span> * <span style="color: #51afef;">FROM</span> course
    <span style="color: #51afef;">WHERE</span> <span style="color: #51afef;">NOT</span> <span style="color: #51afef;">EXISTS</span>(
        <span style="color: #51afef;">SELECT</span> * <span style="color: #51afef;">FROM</span> enrolled
            <span style="color: #51afef;">WHERE</span> course.cid = enrolled.cid
)

<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">Get students whose gpa is larget than the highest score in '15-712'</span>
<span style="color: #5B6268;">-- </span><span style="color: #5B6268;">and the login has a level &gt; 3</span>
<span style="color: #51afef;">SELECT</span> student.sid, <span style="color: #51afef;">name</span>
    <span style="color: #51afef;">FROM</span> student <span style="color: #51afef;">AS</span> S
<span style="color: #51afef;">WHERE</span> s.gpa &gt; <span style="color: #51afef;">ALL</span> (
    <span style="color: #51afef;">SELECT</span> course.score <span style="color: #51afef;">FROM</span> course
        <span style="color: #51afef;">WHERE</span> course.cid = <span style="color: #98be65;">'15-712'</span>
)
<span style="color: #51afef;">AND</span> student.login <span style="color: #51afef;">IN</span> (
    <span style="color: #51afef;">SELECT</span> login <span style="color: #51afef;">FROM</span> enrolled
    <span style="color: #51afef;">WHERE</span> <span style="color: #51afef;">level</span> &gt; <span style="color: #da8548; font-weight: bold;">3</span>
);
</pre>
</div></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgeba7448" class="outline-3">
<h3 id="orgeba7448"><span class="section-number-3">2.8.</span> Window functions</h3>
<div class="outline-text-3" id="text-2-8">
<ul class="org-ul">
<li>Perform sliding calculation across a set of tuples.</li>
</ul>
</div>
</div>
<div id="outline-container-org1728602" class="outline-3">
<h3 id="org1728602"><span class="section-number-3">2.9.</span> Common Table Expressions (CTE)</h3>
<div class="outline-text-3" id="text-2-9">
<ul class="org-ul">
<li>An alternative to windows or nested queries when writing more complex queries.</li>
<li><p>
CTEs use <code>WITH</code> to bind the output of an inner query to a temporary table.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #51afef;">WITH</span> cteName (col1, col2) <span style="color: #51afef;">AS</span> (
    <span style="color: #51afef;">SELECT</span> <span style="color: #da8548; font-weight: bold;">1</span>, <span style="color: #da8548; font-weight: bold;">2</span>
)
<span style="color: #51afef;">SELECT</span> col1 + col2 <span style="color: #51afef;">FROM</span> cteName;
</pre>
</div></li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-database.html">database</a> <a href="https://chenyo.me/tag-cmu.html">cmu</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[database]]></category>
  <category><![CDATA[cmu]]></category>
  <link>https://chenyo.me/2024-07-23-db-notes:-modern-sql.html</link>
  <guid>https://chenyo.me/2024-07-23-db-notes:-modern-sql.html</guid>
  <pubDate>Tue, 23 Jul 2024 13:05:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[CMU 15-445 notes: Relational Model & Algebra]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org2933f8c">1. Terminology</a>
<ul>
<li><a href="#org3510e63">1.1. Database</a></li>
<li><a href="#org03bd07a">1.2. Database design consideration</a></li>
<li><a href="#org1128de4">1.3. Database management system (DBMS)</a></li>
<li><a href="#org1b16526">1.4. Data model</a></li>
<li><a href="#org44051ee">1.5. Schema</a></li>
<li><a href="#orgba1de6b">1.6. Entities and Tables</a></li>
<li><a href="#orgee44502">1.7. Attributes and Fields</a></li>
<li><a href="#org6b5249d">1.8. Logical layer</a></li>
<li><a href="#orga96906e">1.9. Physical layer</a></li>
<li><a href="#org4583cb2">1.10. Data manipulation languages (DMLs)</a></li>
<li><a href="#org5f03fbd">1.11. SQL (Structured Query Language) and relational model</a></li>
</ul>
</li>
<li><a href="#orga05f5ff">2. Relational model</a>
<ul>
<li><a href="#org47300d7">2.1. A relation</a></li>
<li><a href="#org8c855da">2.2. A domain</a></li>
<li><a href="#org9b5f329">2.3. A tuple</a></li>
<li><a href="#orgf39cd2a">2.4. Keys</a></li>
</ul>
</li>
<li><a href="#org6b7b1b9">3. Relational Algebra</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://www.youtube.com/watch?v=uikbtpVZS2s&amp;list=PLSE8ODhjZXjaKScG3l0nuOiDTTqpfnWFf&amp;index=2">CMU 15-445 L1 video</a> and <a href="https://15445.courses.cs.cmu.edu/fall2022/notes/01-introduction.pdf">CMU 15-445 L1 notes</a>, along with some terminology explained by <a href="https://claude.ai/chat/14f3c4ec-0ca8-495e-ac70-dd13f9eab5ea">Claude.ai</a>.
</p>
<div id="outline-container-org2933f8c" class="outline-2">
<h2 id="org2933f8c"><span class="section-number-2">1.</span> Terminology</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org3510e63" class="outline-3">
<h3 id="org3510e63"><span class="section-number-3">1.1.</span> Database</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>An organized collection of inter-related data that models some aspect of the real-world.</li>
</ul>
</div>
</div>
<div id="outline-container-org03bd07a" class="outline-3">
<h3 id="org03bd07a"><span class="section-number-3">1.2.</span> Database design consideration</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Data integrity: protect invalid writing.</li>
<li>Implementation: query complexity, concurrent query.</li>
<li>Durability: replication, fault tolerance.</li>
</ul>
</div>
</div>
<div id="outline-container-org1128de4" class="outline-3">
<h3 id="org1128de4"><span class="section-number-3">1.3.</span> Database management system (DBMS)</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>A software that manages a database.</li>
<li>Allow the definition, creation, query, update and administration of databases.</li>
</ul>
</div>
</div>
<div id="outline-container-org1b16526" class="outline-3">
<h3 id="org1b16526"><span class="section-number-3">1.4.</span> Data model</h3>
<div class="outline-text-3" id="text-1-4">
<ul class="org-ul">
<li>A conceptual, high-level representation of how data is structured</li>
<li>Defines entities, attributes, relationships between entities and constraints.</li>
</ul>
</div>
</div>
<div id="outline-container-org44051ee" class="outline-3">
<h3 id="org44051ee"><span class="section-number-3">1.5.</span> Schema</h3>
<div class="outline-text-3" id="text-1-5">
<ul class="org-ul">
<li>A concrete implementation of a data model.</li>
<li>Defines tables, fields, data types, keys and rules.</li>
<li>Typically represented by a specific database language.</li>
</ul>
</div>
</div>
<div id="outline-container-orgba1de6b" class="outline-3">
<h3 id="orgba1de6b"><span class="section-number-3">1.6.</span> Entities and Tables</h3>
<div class="outline-text-3" id="text-1-6">
<ul class="org-ul">
<li>Entities: conceptual representations of objects in the logical data model.</li>
<li>Tables: physical storage structures in the physical data model.</li>
</ul>
</div>
</div>
<div id="outline-container-orgee44502" class="outline-3">
<h3 id="orgee44502"><span class="section-number-3">1.7.</span> Attributes and Fields</h3>
<div class="outline-text-3" id="text-1-7">
<ul class="org-ul">
<li>Attributes: properties of an entity.</li>
<li>Fields: columns in a database table.</li>
</ul>
</div>
</div>
<div id="outline-container-org6b5249d" class="outline-3">
<h3 id="org6b5249d"><span class="section-number-3">1.8.</span> Logical layer</h3>
<div class="outline-text-3" id="text-1-8">
<ul class="org-ul">
<li>The entities and attributes the database has.</li>
</ul>
</div>
</div>
<div id="outline-container-orga96906e" class="outline-3">
<h3 id="orga96906e"><span class="section-number-3">1.9.</span> Physical layer</h3>
<div class="outline-text-3" id="text-1-9">
<ul class="org-ul">
<li>How are entities and attributes stored in the database.</li>
</ul>
</div>
</div>
<div id="outline-container-org4583cb2" class="outline-3">
<h3 id="org4583cb2"><span class="section-number-3">1.10.</span> Data manipulation languages (DMLs)</h3>
<div class="outline-text-3" id="text-1-10">
<ul class="org-ul">
<li>Methods to store and retrieve information from a database.</li>
<li>Procedural: the query specifies the (high-level) strategy the DBMS should use to get the results, e.g., with relational algebra.</li>
<li>Declarative: the query specifies only what data is desired but not how to get it, e.g., with relational calculus (a formal language).</li>
</ul>
</div>
</div>
<div id="outline-container-org5f03fbd" class="outline-3">
<h3 id="org5f03fbd"><span class="section-number-3">1.11.</span> SQL (Structured Query Language) and relational model</h3>
<div class="outline-text-3" id="text-1-11">
<ul class="org-ul">
<li>SQL <b><b>implements</b></b> the relational model in DBMS and provides a standard way to create, manipulate and query relational databases.</li>
<li>Different SQL implementation may vary and do not strictly adhere to the relational model, e.g., allow duplicate rows.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orga05f5ff" class="outline-2">
<h2 id="orga05f5ff"><span class="section-number-2">2.</span> Relational model</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>A <b><b>data model</b></b> that defines a database <b><b>abstraction</b></b> to avoid maintenance overhead when changing the physical layer.</li>
<li>Data is stored as relations/tables.</li>
<li>Physical layer implementation and execution strategy depends on DBMS implementation.</li>
</ul>


<figure id="org98fe676">
<img src="https://www.guru99.com/images/1/091318_0803_RelationalD1.png" alt="091318_0803_RelationalD1.png" align="center" width="500px">

<figcaption><span class="figure-number">Figure 1: </span>Relational model concepts (<a href="https://www.guru99.com/images/1/091318_0803_RelationalD1.png">Source</a>)</figcaption>
</figure>
</div>
<div id="outline-container-org47300d7" class="outline-3">
<h3 id="org47300d7"><span class="section-number-3">2.1.</span> A relation</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>An unordered set that contains the relationship of attributes that represent entities.</li>
<li>Relationships are unordered in the relation.</li>
</ul>
</div>
</div>
<div id="outline-container-org8c855da" class="outline-3">
<h3 id="org8c855da"><span class="section-number-3">2.2.</span> A domain</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li>A named set of allowable values for a specific attribute.</li>
</ul>
</div>
</div>
<div id="outline-container-org9b5f329" class="outline-3">
<h3 id="org9b5f329"><span class="section-number-3">2.3.</span> A tuple</h3>
<div class="outline-text-3" id="text-2-3">
<ul class="org-ul">
<li>A set of attribute values in the relation.</li>
<li>Values can also be lists or nested data structures.</li>
<li><code>Null</code>: a special value in any attribute which means the attribute in a tuple is undefined.</li>
<li>\(n-ary\): a relation with \(n\) attributes.</li>
</ul>
</div>
</div>
<div id="outline-container-orgf39cd2a" class="outline-3">
<h3 id="orgf39cd2a"><span class="section-number-3">2.4.</span> Keys</h3>
<div class="outline-text-3" id="text-2-4">
<ul class="org-ul">
<li>Primary key: uniquely identifies a single tuple.</li>
<li>Foreign key: specifies that an attribute (e.g., <code>CustomerID</code>) in one relation (e.g., <code>OrderTable</code>) has to map to a tuple (e.g., the tuple with the same <code>CustomerID</code>) in another relation (e.g., <code>CustomerTable</code>).</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org6b7b1b9" class="outline-2">
<h2 id="org6b7b1b9"><span class="section-number-2">3.</span> Relational Algebra</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>A set of fundamental operations to retrieve and manipulate tuples in a relation.</li>
<li>Each operator takes in one or more relations as inputs, and outputs a new relation; operators can be chained.</li>
<li>Is a <b><b>procedure language</b></b>, meaning the execution always follow the query, even there exists more efficient way to get the same result; A better way is to be more declarative, e.g., SQL&rsquo;s <code>where</code> syntax.</li>
<li><a href="https://i.sstatic.net/AHjRg.png">Common relational algebra</a>.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-database.html">database</a> <a href="https://chenyo.me/tag-cmu.html">cmu</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[database]]></category>
  <category><![CDATA[cmu]]></category>
  <link>https://chenyo.me/2024-07-17-db-notes:-relational-model.html</link>
  <guid>https://chenyo.me/2024-07-17-db-notes:-relational-model.html</guid>
  <pubDate>Wed, 17 Jul 2024 17:05:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Parallel EVM: BEP-130]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orga5be66a">1. Blockchain fundamentals</a>
<ul>
<li><a href="#org8275138">1.1. System contract</a></li>
<li><a href="#org5ae8442">1.2. Transaction execution phases</a></li>
</ul>
</li>
<li><a href="#org1f3227a">2. Design principle</a></li>
<li><a href="#orgc834b48">3. Workflow</a>
<ul>
<li><a href="#org6ae01a1">3.1. Dispatch factors</a></li>
<li><a href="#org8468d3c">3.2. Slot execution stages</a></li>
<li><a href="#orgf0e5853">3.3. Conflict detection</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for <a href="https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP130.md">BEP-130</a>.
BEP-130 is a proposal that introduces a parallel transaction execution mechanism on the BNB Smart Chain (BSC).
</p>
<div id="outline-container-orga5be66a" class="outline-2">
<h2 id="orga5be66a"><span class="section-number-2">1.</span> Blockchain fundamentals</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org8275138" class="outline-3">
<h3 id="org8275138"><span class="section-number-3">1.1.</span> System contract</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>Built-in contracts to perform system level operations, e,g., gas fee reward, cross chain communication.</li>
<li>Cannot be executed concurrently since they depend on the execution results of other transactions, e.g., a number of transaction made by an account at some timestamp.</li>
</ul>
</div>
</div>
<div id="outline-container-org5ae8442" class="outline-3">
<h3 id="org5ae8442"><span class="section-number-3">1.2.</span> Transaction execution phases</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Block mining phase: received from the P2P transaction pool, could contain invalid transactions.</li>
<li>Block sync phase: the block is confirmed.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org1f3227a" class="outline-2">
<h2 id="org1f3227a"><span class="section-number-2">2.</span> Design principle</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Should always produce the same result as the current sequential execution.</li>
<li>Should be decoupled into existing or new modules with no circular dependency.</li>
<li>Should be configurable based on node hardware resources.</li>
<li>Keep it simple and smart.</li>
</ul>
</div>
</div>
<div id="outline-container-orgc834b48" class="outline-2">
<h2 id="orgc834b48"><span class="section-number-2">3.</span> Workflow</h2>
<div class="outline-text-2" id="text-3">
</div>
<div id="outline-container-org6ae01a1" class="outline-3">
<h3 id="org6ae01a1"><span class="section-number-3">3.1.</span> Dispatch factors</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>Is the slot idle or occupied?</li>
<li>Is there a same address contract running or pending in this slot?</li>
<li>Has the slot&rsquo;s pending transactions size reached the max transactions queue size limitation?</li>
<li>Is there a big transaction index gap between the slot&rsquo;s head transaction and the dispatched transaction?</li>
<li>Is the transaction contract likely to have high gas cost or a conflict rate?</li>
</ul>
</div>
</div>
<div id="outline-container-org8468d3c" class="outline-3">
<h3 id="org8468d3c"><span class="section-number-3">3.2.</span> Slot execution stages</h3>
<div class="outline-text-3" id="text-3-2">
<ol class="org-ol">
<li>Execute the transaction \(Tx_i\)based on a specific worldstate, e.g., the state when the execution starts.</li>
<li>Wait for the finalization of the previous transaction \(Tx_{i-1}\).</li>
<li>Detect if there is any conflict between the state read by \(Tx_i\) and the state change after the execution of \(Tx_i\) starts.</li>
<li>If a conflict is detected, re-execute \(Tx_{i}\) again based on the latest finalized worldstate.</li>
<li>Finalize the state changed by \(Tx_i\) to the latest worldstate.</li>
<li>The state changes are kept within each slot, and are merged to the main StateDB once the execution is done.</li>
<li>The first transaction in a block can be immediately finalized.</li>
<li>If \(Tx_i\) and \(Tx_{i-1}\) are in the same slot, \(Tx_i\) can immediately start conflict detection.</li>
<li>Re-executed transaction can be immediately finalized as it reads the latest worldstate.</li>
</ol>
</div>
</div>
<div id="outline-container-orgf0e5853" class="outline-3">
<h3 id="orgf0e5853"><span class="section-number-3">3.3.</span> Conflict detection</h3>
<div class="outline-text-3" id="text-3-3">
<ul class="org-ul">
<li>Detection items: storage key/value pair; account balance; contract content and status.</li>
<li>Overlap reads without write, or hardcode writes without read are not conflicts.</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-evm.html">evm</a> <a href="https://chenyo.me/tag-parallel-evm.html">parallel-evm</a> <a href="https://chenyo.me/tag-bnb.html">bnb</a> </div>]]></description>
  <category><![CDATA[evm]]></category>
  <category><![CDATA[parallel-evm]]></category>
  <category><![CDATA[bnb]]></category>
  <link>https://chenyo.me/2024-07-14-parallel-evm:-bep-130.html</link>
  <guid>https://chenyo.me/2024-07-14-parallel-evm:-bep-130.html</guid>
  <pubDate>Sun, 14 Jul 2024 12:38:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Parallel EVM: BNB chain]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org7dfc0b6">1. Blockchain fundamentals</a>
<ul>
<li><a href="#orgcebc034">1.1. Why is parallel EVM not easy</a></li>
<li><a href="#org447f361">1.2. A Parallel EVM ideas</a></li>
<li><a href="#org7c94b11">1.3. Block STM algorithm</a></li>
</ul>
</li>
<li><a href="#org87f718c">2. BNB Parallel EVM 1.0: Infrastructure</a></li>
<li><a href="#org691d9cd">3. BNB Parallel EVM 2.0: Performance enhancement</a></li>
<li><a href="#org75184a9">4. BNB Parallel EVM 3.0: Production</a>
<ul>
<li><a href="#orgef84c4d">4.1. Hint-based dispatcher</a></li>
<li><a href="#orgf1689bc">4.2. Seamless BNB chain ecosystem integration</a></li>
</ul>
</li>
<li><a href="#orgc57d3f7">5. Comparison with other solutions</a></li>
<li><a href="#org9a82136">6. Other optimizations</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note for <a href="https://www.bnbchain.org/zh-CN/blog/road-to-high-performance-parallel-evm-for-bnb-chain">BNB chain-blog</a>.
</p>
<div id="outline-container-org7dfc0b6" class="outline-2">
<h2 id="org7dfc0b6"><span class="section-number-2">1.</span> Blockchain fundamentals</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-orgcebc034" class="outline-3">
<h3 id="orgcebc034"><span class="section-number-3">1.1.</span> Why is parallel EVM not easy</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>Lack of visibility of potential transaction conflict.</li>
<li>Blockchains experience transaction bursts, e.g., &gt;70M transactions per day.</li>
</ul>
</div>
</div>
<div id="outline-container-org447f361" class="outline-3">
<h3 id="org447f361"><span class="section-number-3">1.2.</span> A Parallel EVM ideas</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Run multiple EVM instances concurrently on different threads.</li>
<li>Execute transactions independently on each thread and later merge a finial state update.</li>
<li><a href="https://lh7-us.googleusercontent.com/Dh1GAMYlMkiRI0xWQ0ByYOxq_GNtA9h1PP1OF7FP9b8O3VRxVtlh1eq991OlNa4rNX_ZXH8tVPRBeN58_0dBF1jPUVRuuJMl4JqmBchhCTZp_vF-W003l77KajIjIMCHfapjsBH--0EpMi0FT2iNPlw">Parallel EVM scheme</a></li>
</ul>
</div>
</div>
<div id="outline-container-org7c94b11" class="outline-3">
<h3 id="org7c94b11"><span class="section-number-3">1.3.</span> Block STM algorithm</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>Optimistic parallelism: assigns transactions to various threads.</li>
<li>Software transaction memory (STM): detect conflicts when transactions try to modify the same shared state simultaneously.</li>
<li>Conflict resolution: when conflicts are detected, the offending transactions are discarded without affecting the blockchain state and are re-executed.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org87f718c" class="outline-2">
<h2 id="org87f718c"><span class="section-number-2">2.</span> BNB Parallel EVM 1.0: Infrastructure</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>Proposal: <a href="https://github.com/bnb-chain/BEPs/pull/130?ref=bnbchain.ghost.io">BEP-130 (2022)</a></li>
<li>Dispatcher: distributes transactions across threads to optimize throughput.</li>
<li>Parallel execution engine: execute transactions independently on each thread.</li>
<li>Local stateDB: each thread maintains a local stateDB to record state access.</li>
<li>Conflict detection: detect conflicts and re-execute conflicting transactions.</li>
<li>State commit: the finalized results are committed to the global state DB.</li>
</ul>
</div>
</div>
<div id="outline-container-org691d9cd" class="outline-2">
<h2 id="org691d9cd"><span class="section-number-2">3.</span> BNB Parallel EVM 2.0: Performance enhancement</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>Dispatcher: combine both static and dynamic dispatch strategies.</li>
<li>Execution engine: streaming pipeline to enable smooth transaction processing.</li>
<li>Conflict detection: ensure data integrity while minimizing unnecessary re-execution.</li>
<li>Memory: shared memory pools and light copying techniques to reduce memory footprint.</li>
<li>The overall performance ranges from 20% to 50%.</li>
</ul>
</div>
</div>
<div id="outline-container-org75184a9" class="outline-2">
<h2 id="org75184a9"><span class="section-number-2">4.</span> BNB Parallel EVM 3.0: Production</h2>
<div class="outline-text-2" id="text-4">
</div>
<div id="outline-container-orgef84c4d" class="outline-3">
<h3 id="orgef84c4d"><span class="section-number-3">4.1.</span> Hint-based dispatcher</h3>
<div class="outline-text-3" id="text-4-1">
<ul class="org-ul">
<li>leverages external hint providers to analyze transactions and generate predictions about potential state access conflicts.</li>
<li>Simple hints include read/write state sets; advanced hints incorporate weak/strong ordering for optimal parallelism.</li>
<li>Conflicting transactions are assigned to the same slot.</li>
<li>Transactions with no conflicts are distributed across different slots.</li>
<li>Conflict detector remains as a backup for handling unforeseen conflicts.</li>
</ul>
</div>
</div>
<div id="outline-container-orgf1689bc" class="outline-3">
<h3 id="orgf1689bc"><span class="section-number-3">4.2.</span> Seamless BNB chain ecosystem integration</h3>
<div class="outline-text-3" id="text-4-2">
<ul class="org-ul">
<li>Modularization and reconstructing.</li>
<li>Thorough testing and validation.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgc57d3f7" class="outline-2">
<h2 id="orgc57d3f7"><span class="section-number-2">5.</span> Comparison with other solutions</h2>
<div class="outline-text-2" id="text-5">
<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Solutions</th>
<th scope="col" class="org-left">TX dependency check</th>
<th scope="col" class="org-left">Conflict resolution</th>
<th scope="col" class="org-left">StateDB optimization</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">BlockSTM</td>
<td class="org-left">tracks at execution</td>
<td class="org-left">re-execution</td>
<td class="org-left">N/A</td>
</tr>

<tr>
<td class="org-left">Polygon</td>
<td class="org-left">minimal metadata solution</td>
<td class="org-left">reduced re-execution</td>
<td class="org-left">N/A</td>
</tr>

<tr>
<td class="org-left">Monad</td>
<td class="org-left">static analysis</td>
<td class="org-left">reduced re-execution</td>
<td class="org-left">Monad DB</td>
</tr>

<tr>
<td class="org-left">Sei</td>
<td class="org-left">tracks at execution</td>
<td class="org-left">re-execution</td>
<td class="org-left">SeiDB</td>
</tr>

<tr>
<td class="org-left">Neon EVM and Solana Sealevel</td>
<td class="org-left">contract provided</td>
<td class="org-left">reduced re-execution</td>
<td class="org-left">depends on Solana</td>
</tr>

<tr>
<td class="org-left">BNBChain</td>
<td class="org-left">hint info</td>
<td class="org-left">reduced or eliminated re-execution</td>
<td class="org-left">Thread local DB</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org9a82136" class="outline-2">
<h2 id="org9a82136"><span class="section-number-2">6.</span> Other optimizations</h2>
<div class="outline-text-2" id="text-6">
<ul class="org-ul">
<li>Opcode-level optimization: fine-tuning individual EVM instructions for maximum efficiency.</li>
<li>Compilation optimization: JIT/AOT compilation paradigms; instruction-level parallelism (SIMD).</li>
<li>Database sharding: distribute data across multiple databases.</li>
<li>Concurrent node execution.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-evm.html">evm</a> <a href="https://chenyo.me/tag-parallel-evm.html">parallel-evm</a> <a href="https://chenyo.me/tag-bnb.html">bnb</a> </div>]]></description>
  <category><![CDATA[evm]]></category>
  <category><![CDATA[parallel-evm]]></category>
  <category><![CDATA[bnb]]></category>
  <link>https://chenyo.me/2024-07-07-parallel-evm:-bnb-chain.html</link>
  <guid>https://chenyo.me/2024-07-07-parallel-evm:-bnb-chain.html</guid>
  <pubDate>Sun, 07 Jul 2024 22:19:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Parallel EVM: MegaETH]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org4b1fe4d">1. Blockchain fundamentals</a>
<ul>
<li><a href="#org926d90b">1.1. Conduit chain</a></li>
<li><a href="#org15c2ce8">1.2. Gas per second</a></li>
<li><a href="#orgc7326b8">1.3. Target gas per block</a></li>
<li><a href="#orgfa3c2a1">1.4. Current blockchain scalability</a></li>
<li><a href="#org68e492b">1.5. Blockchain node hardware requirements</a></li>
<li><a href="#orgccae819">1.6. L1 and L2 nodes</a></li>
<li><a href="#org5d33452">1.7. Verifying a block</a></li>
<li><a href="#orgc481514">1.8. Maximum extractable value (MEV)</a></li>
<li><a href="#orgbaafd50">1.9. Proposer-builder separation (PBS)</a></li>
<li><a href="#org9b5193c">1.10. Live and historical sync</a></li>
<li><a href="#org67d9fdb">1.11. Portal Network</a></li>
<li><a href="#orgd4e6acb">1.12. Verkle tree</a></li>
<li><a href="#org08a9fed">1.13. Node storage</a>
<ul>
<li><a href="#orgb9f5abc">1.13.1. History expiry</a></li>
<li><a href="#org8e9af51">1.13.2. State expiry</a></li>
<li><a href="#org05fd31f">1.13.3. Statelessness</a></li>
</ul>
</li>
<li><a href="#org424cb80">1.14. Software transactional memory (STM)</a></li>
<li><a href="#org3ba8081">1.15. Block-STM</a></li>
</ul>
</li>
<li><a href="#org9966a0d">2. What is MagaETH</a>
<ul>
<li><a href="#org50e5549">2.1. Node specialization</a></li>
<li><a href="#orgd5958b5">2.2. Design philosophy</a></li>
</ul>
</li>
<li><a href="#org45c6e78">3. MegaETH challenges</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note for <a href="https://megaeth.systems/research">MegaETH-blog</a> as well as some terminology explained online, e.g.,  <a href="https://ethereum.org/en/roadmap/">ethereum.org</a>.
</p>

<p>
In summary, this blog proposes many challenges when designing a high-performance EVM chain, but does not include any design details of MegaETH itself.
</p>
<div id="outline-container-org4b1fe4d" class="outline-2">
<h2 id="org4b1fe4d"><span class="section-number-2">1.</span> Blockchain fundamentals</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org926d90b" class="outline-3">
<h3 id="org926d90b"><span class="section-number-3">1.1.</span> <a href="https://docs.conduit.xyz/">Conduit chain</a></h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>Allows one to deploy a rollup through its Rollups-as-a-service platform within in minutes.</li>
</ul>
</div>
</div>
<div id="outline-container-org15c2ce8" class="outline-3">
<h3 id="org15c2ce8"><span class="section-number-3">1.2.</span> Gas per second</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Reflects the amount of computation the blockchain can handle per second.</li>
<li>Different EVM operation costs different gas, e.g., <code>ADD</code> costs 3 gas.</li>
<li>Block gas limit: ensures that any node can reliably keep up with the rest of the network.</li>
</ul>
</div>
</div>
<div id="outline-container-orgc7326b8" class="outline-3">
<h3 id="orgc7326b8"><span class="section-number-3">1.3.</span> Target gas per block</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>Dynamically regulate the amount of computation a block can include.</li>
<li><code>Gas per second = Target Gas per block / Block time</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-orgfa3c2a1" class="outline-3">
<h3 id="orgfa3c2a1"><span class="section-number-3">1.4.</span> Current blockchain scalability</h3>
<div class="outline-text-3" id="text-1-4">

<figure id="org9d9b069">
<img src="https://hackmd.io/_uploads/rkHVB0iHR.png" alt="rkHVB0iHR.png" align="center" width="500px">

<figcaption><span class="figure-number">Figure 1: </span>2024 blockchain scalability comparison</figcaption>
</figure>

<ul class="org-ul">
<li>Throughput: 100MGas/s (\(\approx\) 3700 ERC-20 transfer) cannot compares to Web2 database with &gt;1M transactions per second.</li>
<li>Capacity: Complex applications cannot be on-chain, e.g., compute large Fibonacci (e.g., \(10^8\)) number would take 55 seconds on opBNB, while in C just 30 milliseconds in a single core.</li>
<li>Delay: Applications that require fast feedback loop, e.g., high-frequency trading are not feasible with long block times, e.g., 1s.</li>
</ul>
</div>
</div>
<div id="outline-container-org68e492b" class="outline-3">
<h3 id="org68e492b"><span class="section-number-3">1.5.</span> Blockchain node hardware requirements</h3>
<div class="outline-text-3" id="text-1-5">
<ul class="org-ul">
<li>Lower hardware requirements for full nodes increase decentralization.</li>
<li>Higher requirements increase performance and security.</li>
</ul>
</div>
</div>
<div id="outline-container-orgccae819" class="outline-3">
<h3 id="orgccae819"><span class="section-number-3">1.6.</span> L1 and L2 nodes</h3>
<div class="outline-text-3" id="text-1-6">
<ul class="org-ul">
<li>L1 nodes are homogeneous; each node performs identical tasks, i.e., transaction consensus and execution without specialization.</li>
<li>L2 nodes are heterogeneous; different nodes perform specific tasks, e.g., sequencer node determines the transaction order, prover nodes rely on accelerators to enhance proof generation.</li>
</ul>
</div>
</div>
<div id="outline-container-org5d33452" class="outline-3">
<h3 id="org5d33452"><span class="section-number-3">1.7.</span> Verifying a block</h3>
<div class="outline-text-3" id="text-1-7">
<ul class="org-ul">
<li>Re-execute the transactions in the block.</li>
<li>Applying the changes to Ethereum state trie.</li>
<li>Calculate the new root hash and compare it with the root hash provided by the block.</li>
</ul>
</div>
</div>
<div id="outline-container-orgc481514" class="outline-3">
<h3 id="orgc481514"><span class="section-number-3">1.8.</span> Maximum extractable value (MEV)</h3>
<div class="outline-text-3" id="text-1-8">
<ul class="org-ul">
<li>Validators maximize their profitability by favorably ordering transactions.</li>
</ul>
</div>
</div>
<div id="outline-container-orgbaafd50" class="outline-3">
<h3 id="orgbaafd50"><span class="section-number-3">1.9.</span> Proposer-builder separation (PBS)</h3>
<div class="outline-text-3" id="text-1-9">
<ul class="org-ul">
<li>Block builders are responsible for creating blocks and offering them to the block proposer in each slot.</li>
<li>Block proposers cannot see the contents, but simply choose the most profitable one and pay a fee to the block builder before broadcasting the block.</li>
<li>PBS makes it harder for block builders to censor transactions, and to outperform individuals at MEV extraction.</li>
</ul>
</div>
</div>
<div id="outline-container-org9b5193c" class="outline-3">
<h3 id="org9b5193c"><span class="section-number-3">1.10.</span> Live and historical sync</h3>
<div class="outline-text-3" id="text-1-10">
<ul class="org-ul">
<li>Live (online): continuously update a node with the latest data.</li>
<li>Historical (offline): synchronize a node by downloading the processing data up to a certain point.</li>
<li>Historical sync has much higher TPS than live sync, e.g., 10x, since historical sync can perform batch processing and does not have network latency.</li>
</ul>
</div>
</div>
<div id="outline-container-org67d9fdb" class="outline-3">
<h3 id="org67d9fdb"><span class="section-number-3">1.11.</span> <a href="https://ethereum.org/en/developers/docs/networking-layer/portal-network/">Portal Network</a></h3>
<div class="outline-text-3" id="text-1-11">
<ul class="org-ul">
<li>An in-development p2p network for serving historical data where each node stores a small piece of Ethereum&rsquo;s history.</li>
<li>Light nodes do not need to trust on full nodes.</li>
<li>The entire history exists distributed across the network.</li>
</ul>
</div>
</div>
<div id="outline-container-orgd4e6acb" class="outline-3">
<h3 id="orgd4e6acb"><span class="section-number-3">1.12.</span> <a href="https://ethereum.org/en/roadmap/verkle-trees/">Verkle tree</a></h3>
<div class="outline-text-3" id="text-1-12">
<ul class="org-ul">
<li>Stateless clients rely on a witness that arrives with the block for PoI rather on maintaining own local trie.</li>
<li><b><b>Witness</b></b>: the minimal set of data that prove the values of the state that are being changed by the transactions in a block.</li>
</ul>

<ul class="org-ul">
<li>Merkle tree is too large to be broadcast between peers; the witness is a path connecting the data from leaved to the root, and to verify the data the hash of all sibling nodes are also required (to compute the parent hash).</li>
<li>Verkle trees reduce the witness size by shortening the distance between leaves and eliminating the need to provide sibling nodes; Using a polynomial commitment scheme (see <a href="https://chenyo-17.github.io/org-static-blog/2024-07-28-ethereum-merkle-patricia-trie.html">Ethereum MPT post</a> for explanation) allows the witness to have a fixed size.</li>
</ul>
</div>
</div>
<div id="outline-container-org08a9fed" class="outline-3">
<h3 id="org08a9fed"><span class="section-number-3">1.13.</span> Node storage</h3>
<div class="outline-text-3" id="text-1-13">
<ul class="org-ul">
<li>High disk space is the main barrier to a full node access, due to the need to store large chunks of Ethereum state data to process new transactions.</li>
<li>Using cheap hard drivers to store old data cannot keep up with new blocks.</li>
<li>Clients should find new ways to verify transactions without relying on looking up local databases.</li>
</ul>
</div>
<div id="outline-container-orgb9f5abc" class="outline-4">
<h4 id="orgb9f5abc"><span class="section-number-4">1.13.1.</span> History expiry</h4>
<div class="outline-text-4" id="text-1-13-1">
<ul class="org-ul">
<li>Nodes discard state data older than X blocks with weak subjectivity checkpoints, i.e., a genesis block close to the present.</li>
<li>Nodes can request historical data from peers with Portal Network, e.g., altruistic nodes that are willing to maintain and serve historical achieves, e.g., DAO.</li>
<li>Does not fundamentally change how Ethereum node handles data.</li>
<li>Controversial due to it could introduce new censorship risks if centralized organizations are providing historical data.</li>
<li>EIP-4444 is under active discussion regarding community management.</li>
</ul>
</div>
</div>
<div id="outline-container-org8e9af51" class="outline-4">
<h4 id="org8e9af51"><span class="section-number-4">1.13.2.</span> State expiry</h4>
<div class="outline-text-4" id="text-1-13-2">
<ul class="org-ul">
<li>Remove state from individual nodes if it has not been accessed recently.</li>
<li>The inactive accounts is not deleted, but stored separately from the active state and can be resurrected.</li>
<li>A leading approach requires to add timestamps to the account address.</li>
<li>The responsibility of storing old data may also be moved to centralized providers.</li>
</ul>
</div>
</div>
<div id="outline-container-org05fd31f" class="outline-4">
<h4 id="org05fd31f"><span class="section-number-4">1.13.3.</span> Statelessness</h4>
<div class="outline-text-4" id="text-1-13-3">
<ul class="org-ul">
<li>weak statelessness: only block producers need access to full state data.</li>
<li>Weak statelessness require Verkle trees and proposer-builder separation.</li>
<li>strong statelessness: no nodes need access to the full state data.</li>
<li>In strong statelessness, witnesses are generated by users to declare accounts related to the transaction; not a part of Ethereum&rsquo;s roadmap.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org424cb80" class="outline-3">
<h3 id="org424cb80"><span class="section-number-3">1.14.</span> Software transactional memory (STM)</h3>
<div class="outline-text-3" id="text-1-14">
<ul class="org-ul">
<li>A concurrency control mechanism to control access to shares memory in software.</li>
<li>A transaction refers to a piece of code executing a series of reads and writes to the shared memory.</li>
<li>Transactions are isolated; changes made by one transaction are not visible to others until the transaction commits.</li>
<li>When a conflict is detected, e.g., two transactions try to modify the same memory, one transaction is rolled back.</li>
</ul>
</div>
</div>
<div id="outline-container-org3ba8081" class="outline-3">
<h3 id="org3ba8081"><span class="section-number-3">1.15.</span> Block-STM</h3>
<div class="outline-text-3" id="text-1-15">
<ul class="org-ul">
<li>A parallel execution engine to schedule smart contract transactions based on STM.</li>
<li>Transactions are grouped in blocks, every execution of the block must yield the deterministic and consistent outcome.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org9966a0d" class="outline-2">
<h2 id="org9966a0d"><span class="section-number-2">2.</span> What is MagaETH</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>An EVM-compatible L2 blockchain with Web2-level real-time processing and publishing, i.e., millisecond-level response times under heavy load.</li>
<li>Main idea: delegate security and censorship resistance to base layers, e.g., Ethereum to make room for L2 optimization.</li>
</ul>
</div>
<div id="outline-container-org50e5549" class="outline-3">
<h3 id="org50e5549"><span class="section-number-3">2.1.</span> Node specialization</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>sequencer: only one active sequencer at any time to <b><b>eliminate the consensus overhead</b></b>.</li>
<li>full node: receive state diff from the sequencer via a p2p network and apply the diffs to update local states; don&rsquo;t re-execute transactions, only validates the block indirectly using proofs provided by the provers.</li>
<li>provers: validate the block asynchronously using the stateless validation scheme.</li>
<li><a href="https://vitalik.eth.limo/general/2021/12/06/endgame.html">Endgame, Vitalik 2021</a>: Node specialization ensures trustless and high decentralized block validation (more provers), even though block production becomes more centralized (one sequencer).</li>
</ul>
</div>
</div>
<div id="outline-container-orgd5958b5" class="outline-3">
<h3 id="orgd5958b5"><span class="section-number-3">2.2.</span> Design philosophy</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li>Reth (Rust implementation of the Ethereum protocol) is bottlenecked by the MPT update in a live sync setup, even with a powerful sequencer.</li>
<li><a href="https://www.usenix.org/conference/atc19/presentation/keynote">Measure, then build</a>: first get insights from real problems, then design techniques to address all problems simultaneously.</li>
<li>Prefer clean-slate, as addressing any bottleneck in isolation rarely results in significant end-to-end performance improvement.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org45c6e78" class="outline-2">
<h2 id="org45c6e78"><span class="section-number-2">3.</span> MegaETH challenges</h2>
<div class="outline-text-2" id="text-3">

<figure id="orgd5363cf">
<img src="https://hackmd.io/_uploads/BJW2EG4L0.png" alt="BJW2EG4L0.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 2: </span>A transaction life-cycle.</figcaption>
</figure>

<ul class="org-ul">
<li>State synchronization requires high data compression given limited network bandwidth.</li>
<li>Updating the hash root requires intensive disk I/O operation, which cannot be well speedup with optimized smart-contract compilers.</li>
<li>Cannot easily raise block gas limit without properly repricing opcodes that do not benefit from optimized compilation.</li>
<li>Parallelism is low for long dependency chains.</li>
<li>The actual user experience highly depend on the infrastructure, e.g., RPC nodes, indexers.</li>
<li>Support transaction priorities, e.g., critical transactions should be processed without queuing delays.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-evm.html">evm</a> <a href="https://chenyo.me/tag-parallel-evm.html">parallel-evm</a> <a href="https://chenyo.me/tag-megaeth.html">megaeth</a> </div>]]></description>
  <category><![CDATA[evm]]></category>
  <category><![CDATA[parallel-evm]]></category>
  <category><![CDATA[megaeth]]></category>
  <link>https://chenyo.me/2024-07-04-parallel-evm:-megaeth.html</link>
  <guid>https://chenyo.me/2024-07-04-parallel-evm:-megaeth.html</guid>
  <pubDate>Thu, 04 Jul 2024 15:34:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[My German course]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org698f277">1. Was ist passiert</a></li>
<li><a href="#orgce7cae0">2. Ich kann kein gutes Englisch schreiben</a></li>
<li><a href="#org5d54848">3. Ich kann nicht mich vorstellen</a></li>
</ul>
</div>
</nav>
<div id="outline-container-org698f277" class="outline-2">
<h2 id="org698f277"><span class="section-number-2">1.</span> Was ist passiert</h2>
<div class="outline-text-2" id="text-1">
<p>
Ich habe seit diesem Montag einen intensiven Deutschkurs gemacht.
Die Kurs fangt von 8:30 Uhr bis 11:45 Uhr jeden Tag an.
Weil von mein Wohnung bis zu die Schule ich fast einen Stunden brauche, muss ich vor 7 aufstehen und zur Bushaltstelle runnen.
Nach dem Kurs fahre ich mit dem Bus zur Buro und arbeite ich bis zum Abendessen.
Danach komme ich nach Haus zuruck und mache ein paar Haushalt.
Ich gehe circa 11 Uhr ins Bett.
</p>
</div>
</div>
<div id="outline-container-orgce7cae0" class="outline-2">
<h2 id="orgce7cae0"><span class="section-number-2">2.</span> Ich kann kein gutes Englisch schreiben</h2>
<div class="outline-text-2" id="text-2">
<p>
Wenn ich hier diesen Satzen schreibe, merke ich, dass ich komplexe Satze auf Englisch nicht mehr schreiben kann.
</p>

<p>
This is interesting, I am still in the starting phase, I cannot speak fluently at all and I have grammar mistakes everywhere.
However, now when I try to type something in english, the german translation pops up in my mind first.
If I don&rsquo;t know the german, I have a problem writing it down in english.
As a result, my written english falls back to almost the same level as german.
</p>
</div>
</div>
<div id="outline-container-org5d54848" class="outline-2">
<h2 id="org5d54848"><span class="section-number-2">3.</span> Ich kann nicht mich vorstellen</h2>
<div class="outline-text-2" id="text-3">
<p>
All my classmates come from diverse backgrounds.
At least 5 are Ukriainian, and at least 2 from some countries that I have never heard before.
English is no longer a universal language, but with my broken german I can barely chat.
</p>

<p>
Even with english, I have struggled a lot introducing myself.
In the past decade, I never had this issue since everyone around me shared the similar experience.
I can easily position myself; which education I had, which university I went, what work I am doing, what issue I have, etc.
But this coordinate system works no more in this class.
I am only confusing others if I mention I am a PhD student.
So you are a student, they ask, why would they pay a student?
</p>

<p>
Once I asked classmate what she does on weekend.
She paused, and said: because you are working, so the weekend is different for you, but I don&rsquo;t work, so there is no difference for me.
And before this I have never thought of such a bias in my question.
</p>

<p>
More and more often recently, I realize how limited my perspective is.
I did not know what the life with a social worker is like.
I did not know that Afghan can often speak Turkish.
I did not know what my lecturer thinks when he works as a security guard at night.
I have been too much caught up in my own world, such that I am unable to ask a meaningful question of people I don&rsquo;t understand.
I want to know more about the difference of this world, but I don&rsquo;t know how.
</p>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-personal.html">personal</a> <a href="https://chenyo.me/tag-german.html">german</a> </div>]]></description>
  <category><![CDATA[personal]]></category>
  <category><![CDATA[german]]></category>
  <link>https://chenyo.me/2024-07-04-my-german-course.html</link>
  <guid>https://chenyo.me/2024-07-04-my-german-course.html</guid>
  <pubDate>Thu, 04 Jul 2024 13:36:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Ethereum Virtual Machine]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org88a12ae">1. Terminology</a>
<ul>
<li><a href="#orgc7e63f7">1.1. Motivation</a></li>
<li><a href="#org6fc085a">1.2. Blockchain paradigm</a></li>
<li><a href="#org30b8e58">1.3. Ethereum Transaction execution</a></li>
<li><a href="#org0a2b55e">1.4. World state \(\sigma\)</a>
<ul>
<li><a href="#orgbc2f667">1.4.1. The account state \(\sigma[a]\)</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note of EVM, resources are from:
</p>
<ul class="org-ul">
<li><a href="https://ethereum.org/en/developers/docs/evm/">ethereum.org</a></li>
<li><a href="https://chatgpt.com/g/g-TJq7kBEsX-evm-gpt">EVM GPT</a></li>
<li><a href="https://ethereum.github.io/yellowpaper/paper.pdf">Ethereum yellowpaper: Paris version (26.06.2024)</a></li>
</ul>
<div id="outline-container-org88a12ae" class="outline-2">
<h2 id="org88a12ae"><span class="section-number-2">1.</span> Terminology</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>EVM: a decentralized virtual environment that executes code consistently and securely across all Ethereum nodes.</li>
<li>Gas: used to measure the computational effort required to execute smart contracts.</li>
<li>Ether(ETH): the native cryptocurrency in Ethereum; used to incentivize computation.</li>
<li>Wei: the smallest subdenomination of Ether; 1 Ether = \(10^{18}\) Wei.</li>
<li>State: A modified Merkle Patricia Trie to keep all accounts linked by hashes and reducible to a single root hash stored on the blockchain.</li>
<li>State transition function: <code>Y(S, T)=S'</code>: produces a <b><b>deterministic</b></b> new valid state (<code>S'</code>) given an old valid state (<code>S</code>) new set of valid transactions (<code>T</code>)</li>
<li>Transactions: signed instructions from accounts, includes
<ul class="org-ul">
<li>a contraction creation to create a new contract account containing compiled contract bytecode, or</li>
<li>a message call to a contract to execute the bytecode.</li>
</ul></li>
<li>Proof of work: a spam deterrence mechanism; demonstrate the potential for a basic data channel to carry a strong economic signal without relying on trust.</li>
<li>Fork: a disagreement between nodes as to which root-to-leaf path down the block tree is the best blockchain.</li>
<li>Chain Id (\(\beta\)): distinguish between diverged blockchains (EIP-155).</li>
</ul>


<figure id="orgca5f14f">
<img src="https://ethereum.org/_next/image/?url=%2Fcontent%2Fdevelopers%2Fdocs%2Fevm%2Fevm.png&amp;w=1920&amp;q=75" alt="?url=%2Fcontent%2Fdevelopers%2Fdocs%2Fevm%2Fevm.png&amp;w=1920&amp;q=75" align="center" width="500px">

<figcaption><span class="figure-number">Figure 1: </span>The EVM structure</figcaption>
</figure>
</div>
<div id="outline-container-orgc7e63f7" class="outline-3">
<h3 id="orgc7e63f7"><span class="section-number-3">1.1.</span> Motivation</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>To facilitate transactions between individuals who would otherwise have no means to trust one another.</li>
<li>To enforce a rich and unambiguous agreement autonomously (crypto-lay system).</li>
</ul>
</div>
</div>
<div id="outline-container-org6fc085a" class="outline-3">
<h3 id="org6fc085a"><span class="section-number-3">1.2.</span> Blockchain paradigm</h3>
<div class="outline-text-3" id="text-1-2">
<div class="latex" id="org0b4628b">
\begin{aligned}
\sigma_{t+1} & \equiv \Pi\left(\boldsymbol{\sigma}_t, B\right) \\
B & \equiv\left(\ldots,\left(T_0, T_1, \ldots\right), \ldots\right) \\
\Pi(\boldsymbol{\sigma}, B) & \equiv \Upsilon\left(\Upsilon\left(\boldsymbol{\sigma}, T_0\right), T_1\right) \ldots
\end{aligned}

</div>
<ul class="org-ul">
<li>\(\sigma\): a valid state between two transactions.</li>
<li>\(B\): a block including a series of transactions.</li>
<li>\(\Upsilon\): the Ethereum state transition function.</li>
<li>\(\Pi\): the block-level state transition function.</li>
</ul>
</div>
</div>
<div id="outline-container-org30b8e58" class="outline-3">
<h3 id="org30b8e58"><span class="section-number-3">1.3.</span> Ethereum Transaction execution</h3>
<div class="outline-text-3" id="text-1-3">
<ol class="org-ol">
<li>An user (externally owned accounts, EOA) signs a transaction, including the sender, receiver (the contract address), Ether value, Gas limit and Gas price.</li>
<li>The transaction is broadcast to the Ethereum network.</li>
<li>Once a validator receives the transaction, it first performs sanity check, e.g., signature validation, balance check.</li>
<li>Upon passing the validation, a transaction is included in a block and executed.
<ol class="org-ol">
<li>Initialization: PC set to the start of the contract code; Gas limit; empty stack, memory; contract state trie loaded to the storage.</li>
<li>Execution: locally executes each bytecode and modifies stack (<code>PUSH</code>), memory (<code>MSTORE</code>) and storage (<code>SSTORE</code>); modifies the global state tree (<code>CALL</code>).</li>
<li>Abortion: if the gas is used up, all state changes during the execution are reverted.</li>
</ol></li>
<li>After the execution is finished, the validator assembles the block and proposes the new block.</li>
<li>If a consensus is reached, the block is appended to the blockchain, and other nodes verify the block and update their global states accordingly.</li>
</ol>
</div>
</div>
<div id="outline-container-org0a2b55e" class="outline-3">
<h3 id="org0a2b55e"><span class="section-number-3">1.4.</span> World state \(\sigma\)</h3>
<div class="outline-text-3" id="text-1-4">
<ul class="org-ul">
<li>A mapping between 160-bit addresses and account states, maintained in a modified Merkle Patricia tree (MPT), serialized as RLP, stored in a off-chain database backend.</li>
<li>MPT benefits: the root node depends on all internal data; allows any previous state with known root hash to be recalled as the tree is immutable.</li>
<li><a href="https://media.licdn.com/dms/image/D4D12AQG2itcSOHtiKw/article-cover_image-shrink_720_1280/0/1690981109933?e=1725494400&amp;v=beta&amp;t=4e2FSROhKCs2qeGtpyb5STePXe80agLfg3G9nuD4oKc">Merkle Patricia Trie representation of state data across blocks</a></li>
</ul>
</div>
<div id="outline-container-orgbc2f667" class="outline-4">
<h4 id="orgbc2f667"><span class="section-number-4">1.4.1.</span> The account state \(\sigma[a]\)</h4>
<div class="outline-text-4" id="text-1-4-1">
<ul class="org-ul">
<li><code>nonce</code>: the number of transactions the address has sent, or the number of contracts the address has made.</li>
<li><code>balance</code>: the number of Wei owned by the address.</li>
<li><code>storageRoot</code>: a 256-bit hash of the root node of a MPT which encodes the account storage, i.e., the contract storage.</li>
<li><code>codeHash</code>: the hash of the EVM code, i.e., the contract bytecode, which is executed if the address receives a message call.</li>
</ul>
</div>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-evm.html">evm</a> </div>]]></description>
  <category><![CDATA[evm]]></category>
  <link>https://chenyo.me/2024-06-30-ethereum-virtual-machine.html</link>
  <guid>https://chenyo.me/2024-06-30-ethereum-virtual-machine.html</guid>
  <pubDate>Sun, 30 Jun 2024 11:29:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Viewed: Interlaken]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org72239a4">1. Where did we go</a></li>
<li><a href="#org46b8bfc">2. Why did we go</a></li>
<li><a href="#org63ac241">3. What did we do</a></li>
</ul>
</div>
</nav>
<div id="outline-container-org72239a4" class="outline-2">
<h2 id="org72239a4"><span class="section-number-2">1.</span> Where did we go</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>We rent a car and drove to Interlaken.</li>
<li>We visited <a href="https://aareschlucht.ch/">Aareschlucht</a> and <a href="https://www.brienz.ch/">Brienz</a>, and did some short strolls around.</li>
</ul>


<figure id="org292d107">
<img src="./static/car.jpg" alt="car.jpg" align="center" width="600px">

<figcaption><span class="figure-number">Figure 1: </span>The view outside the car</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org46b8bfc" class="outline-2">
<h2 id="org46b8bfc"><span class="section-number-2">2.</span> Why did we go</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>According to the unpredictable <a href="https://www.meteoschweiz.admin.ch/#tab=forecast-map">Meteoswiss</a> forecast, this Saturday would have been the only weekend-day with some good weather in limited locations to go hiking since 2? or 3? weeks ago.</li>
<li>But this was not the case anymore when we arrived the <a href="https://www.interlaken.ch/en/experiences/mountains-panoramas/mountain-excursions/brienzer-rothorn">Rothorn Kulm</a> restaurant via the <a href="https://www.interlaken.ch/en/experiences/poi/brienz-rothorn-railway">steam train</a>.</li>
</ul>


<figure id="orgea72c50">
<img src="./static/restaurant.jpg" alt="restaurant.jpg" align="center" width="400px">

<figcaption><span class="figure-number">Figure 2: </span>The weather at the Rothorn Kulm</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org63ac241" class="outline-2">
<h2 id="org63ac241"><span class="section-number-2">3.</span> What did we do</h2>
<div class="outline-text-2" id="text-3">
<ol class="org-ol">
<li>We first went a tour in Aareschlucht, where we experienced both strong cold wind and gentle warm wind.</li>
<li>We then did a half-hour small hiking to go back to our starting point.</li>
<li>Then we drove to Brienz, and had a relaxing lunch along the lake, where I ate a piece of watermelon.</li>
<li>We took the 1-hour steam train to the Rothorn Kulm, when we arrived it started to be foggy, windy and rainy.</li>
<li>We refilled our energy with hot drinks and snacks in the restaurant, and took a short stroll around the restaurant.</li>
<li>We went back to the restaurant to escape the cold (yes it is end of June) and waited for the steam train to go down.</li>
<li>During the train down the sun came out a bit, and the view was clear and nice again!</li>
</ol>


<figure id="org1b359a6">
<img src="./static/water.jpg" alt="water.jpg" align="center" width="600px">

<figcaption><span class="figure-number">Figure 3: </span>The water in Aareschlucht</figcaption>
</figure>


<figure id="org7ba0002">
<img src="./static/view.jpg" alt="view.jpg" align="center" width="600px">

<figcaption><span class="figure-number">Figure 4: </span>The view on the train</figcaption>
</figure>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-personal.html">personal</a> <a href="https://chenyo.me/tag-trip.html">trip</a> <a href="https://chenyo.me/tag-interlaken.html">interlaken</a> </div>]]></description>
  <category><![CDATA[personal]]></category>
  <category><![CDATA[trip]]></category>
  <category><![CDATA[interlaken]]></category>
  <link>https://chenyo.me/2024-06-29-viewed:-interlaken.html</link>
  <guid>https://chenyo.me/2024-06-29-viewed:-interlaken.html</guid>
  <pubDate>Sat, 29 Jun 2024 23:52:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Parallel EVM: Sei-v2]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgd580020">1. Blockchain fundamentals</a>
<ul>
<li><a href="#org9a1bc99">1.1. Mainnet and Testnet</a></li>
<li><a href="#orgc9b339e">1.2. Mainnet Alpha and Beta</a></li>
<li><a href="#org9110ee1">1.3. Layer 1 and Layer 2</a></li>
<li><a href="#org79e5c59">1.4. Rollups</a></li>
<li><a href="#org8bde153">1.5. State channels</a></li>
<li><a href="#orgb40a11e">1.6. Sidechains</a></li>
<li><a href="#orge98c242">1.7. Ethereum and EVM</a></li>
<li><a href="#orgdb58b0a">1.8. IAVL tree</a></li>
<li><a href="#orgf1a73f6">1.9. CosmWasm contract</a></li>
<li><a href="#org49c25da">1.10. Cosmos Ecosystem</a></li>
<li><a href="#orgc830363">1.11. Blockchain layers</a></li>
<li><a href="#orga9473ea">1.12. Optimistic parallelization</a></li>
<li><a href="#org39a925e">1.13. Integrated and Modular blockchain</a></li>
<li><a href="#org567c6e7">1.14. EVM Execution and storage layer</a></li>
<li><a href="#org22b2962">1.15. Block time and finalize time</a></li>
<li><a href="#org2ed880f">1.16. Blockchain audit</a></li>
</ul>
</li>
<li><a href="#org2e7fdd4">2. What is Sei</a></li>
<li><a href="#orgaab69e4">3. What is Sei v2</a>
<ul>
<li><a href="#org22028d3">3.1. Backwards compatibility</a></li>
<li><a href="#org61c8205">3.2. Optimistic parallelization</a></li>
<li><a href="#orgdf127ef">3.3. SeiDB</a></li>
<li><a href="#org3eccb8a">3.4. Interoperability</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for <a href="https://blog.sei.io/sei-v2-the-first-parallelized-evm/">Sei-v2-blog</a> as well as some terminology explained by <a href="https://chatgpt.com/g/g-TJq7kBEsX-evm-gpt">EVM GPT</a>.
</p>
<div id="outline-container-orgd580020" class="outline-2">
<h2 id="orgd580020"><span class="section-number-2">1.</span> Blockchain fundamentals</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org9a1bc99" class="outline-3">
<h3 id="org9a1bc99"><span class="section-number-3">1.1.</span> Mainnet and Testnet</h3>
<div class="outline-text-3" id="text-1-1">
<ul class="org-ul">
<li>Mainnet: real transactions occur and have real-world value; any operation is final and irreversible.</li>
<li>Testnet: a sandbox environment with test cryptocurrencies without real-world value.</li>
</ul>
</div>
</div>
<div id="outline-container-orgc9b339e" class="outline-3">
<h3 id="orgc9b339e"><span class="section-number-3">1.2.</span> Mainnet Alpha and Beta</h3>
<div class="outline-text-3" id="text-1-2">
<ul class="org-ul">
<li>Alpha: test core functionalities and gather initial feedback in live environment.</li>
<li>Beta: more stable and feature-complete, but still need more testing.</li>
</ul>
</div>
</div>
<div id="outline-container-org9110ee1" class="outline-3">
<h3 id="org9110ee1"><span class="section-number-3">1.3.</span> Layer 1 and Layer 2</h3>
<div class="outline-text-3" id="text-1-3">
<ul class="org-ul">
<li>L1: the main network where all transactions are processed and the primary chain is maintained.</li>
<li>L2: secondary frameworks on top of L1 chain, aimed to enhance scalability without compromising the security of the L1.</li>
</ul>
</div>
</div>
<div id="outline-container-org79e5c59" class="outline-3">
<h3 id="org79e5c59"><span class="section-number-3">1.4.</span> Rollups</h3>
<div class="outline-text-3" id="text-1-4">
<ul class="org-ul">
<li>Processes transactions off-chain and periodically submits a summary (rollup) to L1.</li>
<li>Optimistic rollups: assume transactions are valid be default and use a challenge period to allow disputes
<ul class="org-ul">
<li>Examples: Optimism, Arbitrum.</li>
</ul></li>
<li>ZK-rollups: use zero-knowledge proofs to validate transactions.
<ul class="org-ul">
<li>Examples: zkSync, StarkNet.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org8bde153" class="outline-3">
<h3 id="org8bde153"><span class="section-number-3">1.5.</span> State channels</h3>
<div class="outline-text-3" id="text-1-5">
<ul class="org-ul">
<li>allow participants to conduct numerous off-chain transactions, with only the final state recorded on the L1.</li>
<li>Examples: Bitcoin lightning network.</li>
</ul>
</div>
</div>
<div id="outline-container-orgb40a11e" class="outline-3">
<h3 id="orgb40a11e"><span class="section-number-3">1.6.</span> Sidechains</h3>
<div class="outline-text-3" id="text-1-6">
<ul class="org-ul">
<li>Independent blockchains running parallel to the main chain, with own consensus and security.</li>
<li>Examples: Polygon.</li>
</ul>
</div>
</div>
<div id="outline-container-orge98c242" class="outline-3">
<h3 id="orge98c242"><span class="section-number-3">1.7.</span> Ethereum and EVM</h3>
<div class="outline-text-3" id="text-1-7">
<ul class="org-ul">
<li>Ethereum: a blockchain ecosystem, includes the blockchain, consensus mechanism, smart contracts, native cryptocurrency.</li>
<li>EVM: the runtime environment to execute smart contracts in Ethereum.</li>
</ul>
</div>
</div>
<div id="outline-container-orgdb58b0a" class="outline-3">
<h3 id="orgdb58b0a"><span class="section-number-3">1.8.</span> IAVL tree</h3>
<div class="outline-text-3" id="text-1-8">
<ul class="org-ul">
<li>AVL tree: self-balancing binary tree where the difference in heights between left and right subtrees of anynode is at most one.</li>
<li>IAVL tree: immutable AVL tree; node cannot be changed once it is added.</li>
</ul>
</div>
</div>
<div id="outline-container-orgf1a73f6" class="outline-3">
<h3 id="orgf1a73f6"><span class="section-number-3">1.9.</span> CosmWasm contract</h3>
<div class="outline-text-3" id="text-1-9">
<ul class="org-ul">
<li>Allows developers to write fast and portable smart contracts in WebAssembly.</li>
<li>Designed to be interoperable within in the Cosmos ecosystem, a network of independent blockchains connected via the Inter-blockchain communication (IBC) protocol.</li>
</ul>
</div>
</div>
<div id="outline-container-org49c25da" class="outline-3">
<h3 id="org49c25da"><span class="section-number-3">1.10.</span> Cosmos Ecosystem</h3>
<div class="outline-text-3" id="text-1-10">
<ul class="org-ul">
<li>A network of independent, interoperable blockchains designed to create an Internet of blockchain.</li>
<li>Decouples the consensus (BFT consensus engine) and networking (IBC protocol) layers from the application layers</li>
<li>Cosmos SDK: a modular framework for building application-specific blockchains efficiently.</li>
<li>Cosmos Hub: the first blockchain in the Cosmos network, serves as a central hub to connect multiple blockchains via IBC.</li>
</ul>
</div>
</div>
<div id="outline-container-orgc830363" class="outline-3">
<h3 id="orgc830363"><span class="section-number-3">1.11.</span> Blockchain layers</h3>
<div class="outline-text-3" id="text-1-11">
<ul class="org-ul">
<li>Infrastructure layer: the physical devices that support the network; and the underlying communication protocols for data transfer between nodes.</li>
<li>Data layer: the distributed ledger and the storage methods.</li>
<li>Consensus layer: the protocols, validators and miners; determines the transaction orders.</li>
<li>Execution layer: smart contracts and virtual machines; determines the transaction update.</li>
<li>Application layer: dApps to provide service and user interfaces.</li>
<li>Governance layer: the community decision-making process and proposals.</li>
<li>Security layer: cryptographic primitives and security protocols to avoid attacks.</li>
</ul>
</div>
</div>
<div id="outline-container-orga9473ea" class="outline-3">
<h3 id="orga9473ea"><span class="section-number-3">1.12.</span> Optimistic parallelization</h3>
<div class="outline-text-3" id="text-1-12">
<ul class="org-ul">
<li>Multiple transactions are processed in parallel under the assumption that they will conflict with each other; necessary corrections are made afterwards if conflicts are detected.</li>
<li>Increase throughput if conflicts are well handled.</li>
</ul>
</div>
</div>
<div id="outline-container-org39a925e" class="outline-3">
<h3 id="org39a925e"><span class="section-number-3">1.13.</span> Integrated and Modular blockchain</h3>
<div class="outline-text-3" id="text-1-13">
<ul class="org-ul">
<li>Integrated: all components, e.g., execution layer, consensus mechanism, networking are tightly coupled; faster internal communication but lower flexibility and scalability.</li>
<li>Modular: allow independent upgrades for different components; enhance scalability.</li>
</ul>
</div>
</div>
<div id="outline-container-org567c6e7" class="outline-3">
<h3 id="org567c6e7"><span class="section-number-3">1.14.</span> EVM Execution and storage layer</h3>
<div class="outline-text-3" id="text-1-14">
<ul class="org-ul">
<li>Execution: responsible for running smart contracts and processing transactions.</li>
<li>Storage: store all blockchain data, e.g., accounts, smart contract states, transaction history.</li>
</ul>
</div>
</div>
<div id="outline-container-org22b2962" class="outline-3">
<h3 id="org22b2962"><span class="section-number-3">1.15.</span> Block time and finalize time</h3>
<div class="outline-text-3" id="text-1-15">
<ul class="org-ul">
<li>Block: the average time for a new block to be added.</li>
<li>Finalize: the period after which a block is considered irreversible.</li>
<li>Faster block times often imply cheaper transaction fees due to increased transaction throughput and less block competition.</li>
</ul>
</div>
</div>
<div id="outline-container-org2ed880f" class="outline-3">
<h3 id="org2ed880f"><span class="section-number-3">1.16.</span> Blockchain audit</h3>
<div class="outline-text-3" id="text-1-16">
<ul class="org-ul">
<li>A review of a blockchain to ensures its security and functionality.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org2e7fdd4" class="outline-2">
<h2 id="org2e7fdd4"><span class="section-number-2">2.</span> What is Sei</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>On mainnet beta since August 2023.</li>
<li>Consistently finalizes blocks at 390ms; the fastest chain in existence.</li>
<li>Consistently sees activity of &gt;45 TPS (transaction per seconds); the second highest number of successful transactions per second.</li>
<li>Allows for Cosmwasm smart contracts written in Rust; more execution environments like EVM is the biggest request.</li>
</ul>
</div>
</div>
<div id="outline-container-orgaab69e4" class="outline-2">
<h2 id="orgaab69e4"><span class="section-number-2">3.</span> What is Sei v2</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>The first fully parallelized EVM.</li>
<li>Backwards compatibility of EVM smart contracts.</li>
<li>Optimistic parallelization; support parallelization without requiring any dependencies.</li>
<li>Improves the storage layer to prevent state bloat, read/write, and state sync for new nodes.</li>
<li>Seamless composability between different execution environments.</li>
<li>Offers 28,300 batched transactions per second of throughput; 390ms block times and 390ms finality; far cheaper per-transaction costs.</li>
<li>Once audits are complete, the upgrade is released in a public testnet in Q1 2024, and deployed to mainnet in H1 2024.</li>
</ul>
</div>
<div id="outline-container-org22028d3" class="outline-3">
<h3 id="org22028d3"><span class="section-number-3">3.1.</span> Backwards compatibility</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>Ethereum contracts can be seamlessly deployed on Sei v2 with no code changes.</li>
<li>User can send a Eth transaction to the Ethereum contract on Sei v2 via the same interface, e.g., Metamask, Hardhat.</li>
<li>Sei v2 imports Geth (a Go EVM implementation) to process the Eth transaction, and convert the result to Sei storage.</li>
</ul>
</div>
</div>
<div id="outline-container-org61c8205" class="outline-3">
<h3 id="org61c8205"><span class="section-number-3">3.2.</span> Optimistic parallelization</h3>
<div class="outline-text-3" id="text-3-2">
<ul class="org-ul">
<li>Sei requires smart contract developers to optionally define the state that smart contracts are using, Sei v2 removes this need.</li>
<li>Sei v2 chain optimistically runs all transactions in parallel, when reaching conflicts, i.e., transactions touching the same state, the chain tracks the storage parts each transaction is touching.</li>
<li>Transactions touching different parts will be rerun in parallel; transactions touching the same state will be rerun sequentially.</li>
<li>Recursively continue until no more conflicts.</li>
<li>Since the transactions are ordered in a block, this process is deterministic.</li>
</ul>
</div>
</div>
<div id="outline-container-orgdf127ef" class="outline-3">
<h3 id="orgdf127ef"><span class="section-number-3">3.3.</span> SeiDB</h3>
<div class="outline-text-3" id="text-3-3">
<ul class="org-ul">
<li>Sei uses a vanilla database layer composed of an IAVL tree, which is less efficient in terms of storage and latency.</li>
<li>Sei v2 breaks the single IAVL tree into 2 components:
<ul class="org-ul">
<li>state store: provide low latency direct access to raw key-value pairs to remove the overhead of redundant metadata and disk usage; uses a write-ahead log to help event recovery.</li>
<li>state commitment: use an in-memory IAVL tree to help validators reach consensus faster.</li>
</ul></li>
<li>After benchmarking, Sei v2 replaces GoLevelDB with PebbleDB for better read/write in multi-threaded access.</li>
</ul>
</div>
</div>
<div id="outline-container-org3eccb8a" class="outline-3">
<h3 id="org3eccb8a"><span class="section-number-3">3.4.</span> Interoperability</h3>
<div class="outline-text-3" id="text-3-4">
<ul class="org-ul">
<li>Sei v2 processes different transactions, e.g., Cosmwasm, EVM in a uniformed way, and then forwards them to different storage sections.</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-evm.html">evm</a> <a href="https://chenyo.me/tag-parallel-evm.html">parallel-evm</a> <a href="https://chenyo.me/tag-sei.html">sei</a> </div>]]></description>
  <category><![CDATA[evm]]></category>
  <category><![CDATA[parallel-evm]]></category>
  <category><![CDATA[sei]]></category>
  <link>https://chenyo.me/2024-06-28-parallel-evm:-sei-v2.html</link>
  <guid>https://chenyo.me/2024-06-28-parallel-evm:-sei-v2.html</guid>
  <pubDate>Fri, 28 Jun 2024 21:25:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Watched: Argo (2012)]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org7dffac4">1. Why did I watch it</a></li>
<li><a href="#orgbae242b">2. What is it about</a></li>
<li><a href="#org961c743">3. Did I like it</a></li>
</ul>
</div>
</nav>

<figure id="orgea546c8">
<img src="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*IFB2V5vjsVKtHcxBdCfQSQ.jpeg" alt="1*IFB2V5vjsVKtHcxBdCfQSQ.jpeg" align="center" width="300px">

<figcaption><span class="figure-number">Figure 1: </span>Argo poster</figcaption>
</figure>
<div id="outline-container-org7dffac4" class="outline-2">
<h2 id="org7dffac4"><span class="section-number-2">1.</span> Why did I watch it</h2>
<div class="outline-text-2" id="text-1">
<p>
This week, I found myself craving a movie with a &ldquo;Homeland&rdquo; theme.
Then the name of Argo came to me.
I saw its name a decade ago (I am too old!) on some movie magazine cover.
</p>
</div>
</div>
<div id="outline-container-orgbae242b" class="outline-2">
<h2 id="orgbae242b"><span class="section-number-2">2.</span> What is it about</h2>
<div class="outline-text-2" id="text-2">
<p>
It has little thing to do with &ldquo;Homeland&rdquo;.
Instead, it blends action, comedy and drama based on a true story, although non of any dramatic conflicts really happened in history afak.
It is about how a selfless agent, backed by an entire intelligence system which behaved incredibly efficient, and an alliance which also behaved incredibly generous, escaped a group of compatriots, who also behaved incredibly brave, from a dangerous place.
My boyfriend said it is quite &ldquo;Hitchcock&rdquo;.
Every tension resolves safely in the end: the phone will be picked up at the last second, the plane will take off at the last second, even the plane tickets will magically show up at the last second (Swissair yeah!).
</p>
</div>
</div>
<div id="outline-container-org961c743" class="outline-2">
<h2 id="org961c743"><span class="section-number-2">3.</span> Did I like it</h2>
<div class="outline-text-2" id="text-3">
<p>
I guess?
The filming is good, as well as the narration and the performance.
There were some moments where I was not fully convinced, but I accept them if that was the history.
What really amazed me was when I found the actor of Tony was also the director, and also wrote &ldquo;Good Will Hunting (1997)&rdquo;, what a genius!
But I guessed I preferred &ldquo;Civil war (2024)&rdquo; (my last movie) to this one.
The reason?
I felt &ldquo;Argo&rdquo; could have delved deeper into the absurdities of war rather than solely focusing on a heroic narrative.
</p>


<figure id="org90c7db3">
<img src="https://m.media-amazon.com/images/M/MV5BOTI0MzcxMTYtZDVkMy00NjY1LTgyMTYtZmUxN2M3NmQ2NWJhXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_.jpg" alt="MV5BOTI0MzcxMTYtZDVkMy00NjY1LTgyMTYtZmUxN2M3NmQ2NWJhXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_.jpg" align="center" width="300px">

<figcaption><span class="figure-number">Figure 2: </span>Good Will Hunting poster</figcaption>
</figure>



<figure id="org37f0c64">
<img src="https://posterspy.com/wp-content/uploads/2024/04/Civil-War-Kirsten.jpg" alt="Civil-War-Kirsten.jpg" align="center" width="300px">

<figcaption><span class="figure-number">Figure 3: </span>Civil War poster</figcaption>
</figure>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-personal.html">personal</a> <a href="https://chenyo.me/tag-moive.html">moive</a> </div>]]></description>
  <category><![CDATA[personal]]></category>
  <category><![CDATA[moive]]></category>
  <link>https://chenyo.me/2024-06-26-watched:-argo.html</link>
  <guid>https://chenyo.me/2024-06-26-watched:-argo.html</guid>
  <pubDate>Wed, 26 Jun 2024 21:37:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Go patterns]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org7d2d2e3">1. Concurrency vs Parallelism</a></li>
<li><a href="#orgf15d141">2. Use goroutines for states</a>
<ul>
<li><a href="#orgd69758f">2.1. Matching a regex</a></li>
<li><a href="#orge6f0f22">2.2. When the state variable cannot be avoided</a></li>
</ul>
</li>
<li><a href="#org7440baa">3. Pattern 1: publish/subscribe server</a>
<ul>
<li><a href="#org61fe3ce">3.1. Options for slow goroutines</a></li>
</ul>
</li>
<li><a href="#org3adafe3">4. Pattern 2: work scheduler</a></li>
<li><a href="#orge8d82f7">5. Pattern 3: replicated service client</a></li>
<li><a href="#orgdeb5e2d">6. Pattern 4: Protocol multiplexer</a></li>
</ul>
</div>
</nav>
<p>
This a personal note for the <a href="https://www.youtube.com/watch?v=IdCbMO0Ey9I">Russ Cox guest lecture</a>.
</p>
<div id="outline-container-org7d2d2e3" class="outline-2">
<h2 id="org7d2d2e3"><span class="section-number-2">1.</span> Concurrency vs Parallelism</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>Concurrency: write a program to handle lot of things at once
<ul class="org-ul">
<li>not necessarily faster</li>
</ul></li>
<li>Parallelism: the program itself can do a lot of computations at once</li>
</ul>
</div>
</div>
<div id="outline-container-orgf15d141" class="outline-2">
<h2 id="orgf15d141"><span class="section-number-2">2.</span> Use goroutines for states</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-orgd69758f" class="outline-3">
<h3 id="orgd69758f"><span class="section-number-3">2.1.</span> Matching a regex</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>return if a given string matches a regex: start with <code>"</code>, contains arbitrary escape sequence and ends with <code>"</code></li>
<li><p>
unclear logic: store states in the data
</p>
<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #dcaeea;">state</span> := <span style="color: #da8548; font-weight: bold;">0</span>
<span class="linenr"> 2: </span><span style="color: #51afef;">for</span> {
<span class="linenr"> 3: </span>    <span style="color: #dcaeea;">c</span> := <span style="color: #c678dd;">read</span>()
<span class="linenr"> 4: </span>    <span style="color: #51afef;">switch</span> state {
<span class="linenr"> 5: </span>    <span style="color: #51afef;">case</span> <span style="color: #da8548; font-weight: bold;">0</span>:
<span class="linenr"> 6: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">first char must be "</span>
<span class="linenr"> 7: </span>        <span style="color: #51afef;">if</span> c != <span style="color: #98be65;">'"'</span> {
<span class="linenr"> 8: </span>            <span style="color: #51afef;">return</span> <span style="color: #a9a1e1;">false</span>
<span class="linenr"> 9: </span>        }
<span class="linenr">10: </span>        state = <span style="color: #da8548; font-weight: bold;">1</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">match the next char</span>
<span class="linenr">11: </span>    <span style="color: #51afef;">case</span> <span style="color: #da8548; font-weight: bold;">1</span>:
<span class="linenr">12: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">ending with " matches</span>
<span class="linenr">13: </span>        <span style="color: #51afef;">if</span> c == <span style="color: #98be65;">'"'</span> {
<span class="linenr">14: </span>            <span style="color: #51afef;">return</span> <span style="color: #a9a1e1;">true</span>
<span class="linenr">15: </span>        }
<span class="linenr">16: </span>        <span style="color: #51afef;">if</span> c == <span style="color: #98be65;">'\\'</span> {
<span class="linenr">17: </span>            state = <span style="color: #da8548; font-weight: bold;">2</span>
<span class="linenr">18: </span>        } <span style="color: #51afef;">else</span> {
<span class="linenr">19: </span>            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">transition to state 1 to match next char</span>
<span class="linenr">20: </span>            state = <span style="color: #da8548; font-weight: bold;">1</span>
<span class="linenr">21: </span>        }
<span class="linenr">22: </span>    <span style="color: #51afef;">case</span> <span style="color: #da8548; font-weight: bold;">2</span>:
<span class="linenr">23: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">read the char, discard it and</span>
<span class="linenr">24: </span>        state = <span style="color: #da8548; font-weight: bold;">1</span>
<span class="linenr">25: </span>    }
<span class="linenr">26: </span>}
</pre>
</div></li>
<li><p>
clear logic: store states in the code
</p>
<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">no variable to store state</span>
<span class="linenr"> 2: </span><span style="color: #51afef;">if</span> <span style="color: #c678dd;">read</span>() != <span style="color: #98be65;">'"'</span> {
<span class="linenr"> 3: </span>    <span style="color: #51afef;">return</span> <span style="color: #a9a1e1;">false</span>
<span class="linenr"> 4: </span>}
<span class="linenr"> 5: </span><span style="color: #51afef;">var</span> <span style="color: #dcaeea;">c</span> <span style="color: #ECBE7B;">rune</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">c is a Unicode, alias to int32</span>
<span class="linenr"> 6: </span><span style="color: #51afef;">for</span> c != <span style="color: #98be65;">'"'</span> {
<span class="linenr"> 7: </span>    c = <span style="color: #c678dd;">read</span>()
<span class="linenr"> 8: </span>    <span style="color: #51afef;">if</span> c == <span style="color: #98be65;">'\\'</span> {
<span class="linenr"> 9: </span>        <span style="color: #c678dd;">read</span>()  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">skip the next char</span>
<span class="linenr">10: </span>    }
<span class="linenr">11: </span>}
<span class="linenr">12: </span><span style="color: #51afef;">return</span> <span style="color: #a9a1e1;">true</span>
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orge6f0f22" class="outline-3">
<h3 id="orge6f0f22"><span class="section-number-3">2.2.</span> When the state variable cannot be avoided</h3>
<div class="outline-text-3" id="text-2-2">
<ul class="org-ul">
<li><p>
the function needs to return the state
</p>
<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">quoter</span> <span style="color: #51afef;">struct</span> {
<span class="linenr"> 2: </span>    state <span style="color: #ECBE7B;">int</span>
<span class="linenr"> 3: </span>}
<span class="linenr"> 4: </span>
<span class="linenr"> 5: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">q</span> *<span style="color: #ECBE7B;">quoter</span>) <span style="color: #c678dd;">Init</span>() {
<span class="linenr"> 6: </span>    r.state = <span style="color: #da8548; font-weight: bold;">0</span>
<span class="linenr"> 7: </span>}
<span class="linenr"> 8: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">proess each char based on current state</span>
<span class="linenr"> 9: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">q</span> *<span style="color: #ECBE7B;">quoter</span>) <span style="color: #c678dd;">Write</span>(<span style="color: #dcaeea;">c</span> <span style="color: #ECBE7B;">rune</span>) <span style="color: #ECBE7B;">Status</span> {
<span class="linenr">10: </span>    <span style="color: #51afef;">switch</span> q.state {
<span class="linenr">11: </span>    <span style="color: #51afef;">case</span> <span style="color: #da8548; font-weight: bold;">0</span>:
<span class="linenr">12: </span>        <span style="color: #51afef;">if</span> c != <span style="color: #98be65;">'"'</span> {
<span class="linenr">13: </span>            <span style="color: #51afef;">return</span> BadInput
<span class="linenr">14: </span>        }
<span class="linenr">15: </span>        q.state = <span style="color: #da8548; font-weight: bold;">1</span>
<span class="linenr">16: </span>    <span style="color: #51afef;">case</span> <span style="color: #da8548; font-weight: bold;">1</span>:
<span class="linenr">17: </span>        <span style="color: #51afef;">if</span> c == <span style="color: #98be65;">'"'</span> {
<span class="linenr">18: </span>            <span style="color: #51afef;">return</span> Success
<span class="linenr">19: </span>        }
<span class="linenr">20: </span>        <span style="color: #51afef;">if</span> c == <span style="color: #98be65;">'\\'</span> {
<span class="linenr">21: </span>            q.state = <span style="color: #da8548; font-weight: bold;">2</span>
<span class="linenr">22: </span>        } <span style="color: #51afef;">else</span> {
<span class="linenr">23: </span>            q.state = <span style="color: #da8548; font-weight: bold;">1</span>
<span class="linenr">24: </span>        }
<span class="linenr">25: </span>    <span style="color: #51afef;">case</span> <span style="color: #da8548; font-weight: bold;">2</span>:
<span class="linenr">26: </span>        q.state = <span style="color: #da8548; font-weight: bold;">1</span>
<span class="linenr">27: </span>    }
<span class="linenr">28: </span>    <span style="color: #51afef;">return</span> NeedMoreInput
<span class="linenr">29: </span>}
</pre>
</div></li>
<li><p>
use additional goroutines to hold states
</p>
<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">quoter</span> <span style="color: #51afef;">struct</span> {
<span class="linenr"> 2: </span>    char <span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">rune</span>
<span class="linenr"> 3: </span>    status <span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Status</span>
<span class="linenr"> 4: </span>}
<span class="linenr"> 5: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">q</span> *<span style="color: #ECBE7B;">quoter</span>) <span style="color: #c678dd;">Init</span>() {
<span class="linenr"> 6: </span>    q.char = <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">rune</span>)
<span class="linenr"> 7: </span>    q.status = <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Status</span>)
<span class="linenr"> 8: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">need to make sure why and when the goroutine will exit</span>
<span class="linenr"> 9: </span>    <span style="color: #51afef;">go</span> q.<span style="color: #c678dd;">parse</span>()
<span class="linenr">10: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">blocks until it receives an initial status from parse()</span>
<span class="linenr">11: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to ensure that parse() is ready, i.e., q.status = NeedMoreInput</span>
<span class="linenr">12: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">before Write() is called</span>
<span class="linenr">13: </span>    &lt;-q.status
<span class="linenr">14: </span>}
<span class="linenr">15: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">Write sends the next char to q.char, which will be receivecd by parse()</span>
<span class="linenr">16: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">the status is a public state accessible by the user</span>
<span class="linenr">17: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">q</span> *<span style="color: #ECBE7B;">quoter</span>) <span style="color: #c678dd;">Write</span>(<span style="color: #dcaeea;">r</span> <span style="color: #ECBE7B;">rune</span>) <span style="color: #ECBE7B;">Status</span> {
<span class="linenr">18: </span>    q.char &lt;- c
<span class="linenr">19: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">wait for the result</span>
<span class="linenr">20: </span>    <span style="color: #51afef;">return</span> &lt;-q.status
<span class="linenr">21: </span>}
<span class="linenr">22: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">q</span> *<span style="color: #ECBE7B;">quoteReader</span>) <span style="color: #c678dd;">parse</span>() {
<span class="linenr">23: </span>    <span style="color: #51afef;">if</span> q.<span style="color: #c678dd;">read</span>() != <span style="color: #98be65;">'"'</span> {
<span class="linenr">24: </span>        q.status &lt;- SyntaxError
<span class="linenr">25: </span>        <span style="color: #51afef;">return</span>
<span class="linenr">26: </span>    }
<span class="linenr">27: </span>    <span style="color: #51afef;">var</span> <span style="color: #dcaeea;">c</span> <span style="color: #ECBE7B;">rune</span>
<span class="linenr">28: </span>    <span style="color: #51afef;">for</span> c!= <span style="color: #98be65;">'"'</span> {
<span class="linenr">29: </span>        c = q.<span style="color: #c678dd;">read</span>()
<span class="linenr">30: </span>        <span style="color: #51afef;">if</span> c == <span style="color: #98be65;">'\\'</span> {
<span class="linenr">31: </span>            q.<span style="color: #c678dd;">read</span>()
<span class="linenr">32: </span>        }
<span class="linenr">33: </span>    }
<span class="linenr">34: </span>    q.status &lt;- Done
<span class="linenr">35: </span>}
<span class="linenr">36: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">a helper function used in parse() to return the next char in q.char</span>
<span class="linenr">37: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">q</span> *<span style="color: #ECBE7B;">quoter</span>) <span style="color: #c678dd;">read</span>() <span style="color: #ECBE7B;">int</span> {
<span class="linenr">38: </span>    q.status &lt;- NeedMoreInput
<span class="linenr">39: </span>    <span style="color: #51afef;">return</span> &lt;- q.char
<span class="linenr">40: </span>}
<span class="linenr">41: </span><span style="color: #51afef;">func</span> <span style="color: #c678dd;">main</span>() {
<span class="linenr">42: </span>    <span style="color: #dcaeea;">q</span> := &amp;<span style="color: #ECBE7B;">quoter</span>{}
<span class="linenr">43: </span>    q.<span style="color: #c678dd;">Init</span>()
<span class="linenr">44: </span>
<span class="linenr">45: </span>    <span style="color: #dcaeea;">input</span> := <span style="color: #98be65;">`"Hello, \"World\""`</span>
<span class="linenr">46: </span>    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">_</span>, <span style="color: #dcaeea;">c</span> := <span style="color: #51afef;">range</span> input {
<span class="linenr">47: </span>        <span style="color: #dcaeea;">status</span> := q.<span style="color: #c678dd;">Write</span>(c)
<span class="linenr">48: </span>    }
<span class="linenr">49: </span>}
</pre>
</div></li>
<li>check goroutine blockage
<ul class="org-ul">
<li><code>Ctrl-\</code> sends <code>SIGQUIT</code></li>
<li>use the HTTP server&rsquo;s <code>/debug/pprof/goroutine</code> if importing <code>net/http</code></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org7440baa" class="outline-2">
<h2 id="org7440baa"><span class="section-number-2">3.</span> Pattern 1: publish/subscribe server</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>the information goes one way: server -&gt; client</li>
<li>close a channel to signal no new values will be sent</li>
<li><p>
prefer <code>defer</code> when unlocking the mutex
</p>
<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">Server</span> <span style="color: #51afef;">struct</span> {
<span class="linenr"> 2: </span>    mu  <span style="color: #ECBE7B;">sync.Mutex</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">protect sub</span>
<span class="linenr"> 3: </span>    sub <span style="color: #51afef;">map</span>[<span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>]<span style="color: #ECBE7B;">bool</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">whether a channel should be closed</span>
<span class="linenr"> 4: </span>}
<span class="linenr"> 5: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">Init</span>() {
<span class="linenr"> 6: </span>    s.sub = <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">map</span>[<span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>]<span style="color: #ECBE7B;">bool</span>)
<span class="linenr"> 7: </span>}
<span class="linenr"> 8: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">publish an event to all subscribed channel</span>
<span class="linenr"> 9: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">Publish</span>(<span style="color: #dcaeea;">e</span> <span style="color: #ECBE7B;">Event</span>) {
<span class="linenr">10: </span>    s.mu.<span style="color: #c678dd;">Lock</span>()  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">each method could be called by many clients</span>
<span class="linenr">11: </span>    <span style="color: #51afef;">defer</span> s.mu.<span style="color: #c678dd;">Unlock</span>()
<span class="linenr">12: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">need mutex here since it needs to read s.sub state</span>
<span class="linenr">13: </span>    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">c</span> := <span style="color: #51afef;">range</span> s.sub {
<span class="linenr">14: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if a goroutine consumes the channel events too slow</span>
<span class="linenr">15: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">then a new event publish has to wait</span>
<span class="linenr">16: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">before it can send to the channel</span>
<span class="linenr">17: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">can add channel buffer to mitigate this</span>
<span class="linenr">18: </span>        c &lt;- e
<span class="linenr">19: </span>    }
<span class="linenr">20: </span>}
<span class="linenr">21: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">a channel starts to subscribe</span>
<span class="linenr">22: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">Subscribe</span>(<span style="color: #dcaeea;">c</span> <span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>) {
<span class="linenr">23: </span>    s.mu.<span style="color: #c678dd;">Lock</span>()
<span class="linenr">24: </span>    <span style="color: #51afef;">defer</span> s.mu.<span style="color: #c678dd;">Unlock</span>()
<span class="linenr">25: </span>    <span style="color: #51afef;">if</span> s.sub[c] {
<span class="linenr">26: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the mutex wil also be unlocked with defer</span>
<span class="linenr">27: </span>        <span style="color: #c678dd;">panic</span>(<span style="color: #98be65;">"pubsub: already subscribed"</span>)     }
<span class="linenr">28: </span>    s.sub[c] = <span style="color: #a9a1e1;">true</span>
<span class="linenr">29: </span>}
<span class="linenr">30: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">a channel cancels the subscription</span>
<span class="linenr">31: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">Cancel</span>(<span style="color: #dcaeea;">c</span> <span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>) {
<span class="linenr">32: </span>    s.mu.<span style="color: #c678dd;">Lock</span>()
<span class="linenr">33: </span>    <span style="color: #51afef;">defer</span> s.mu.<span style="color: #c678dd;">Unlock</span>()
<span class="linenr">34: </span>    <span style="color: #51afef;">if</span> <span style="color: #51afef; font-weight: bold;">!</span>s.sub[c] {
<span class="linenr">35: </span>        <span style="color: #c678dd;">panic</span>(<span style="color: #98be65;">"pubsub: not subscribed"</span>)
<span class="linenr">36: </span>    }
<span class="linenr">37: </span>    <span style="color: #c678dd;">close</span>(c)
<span class="linenr">38: </span>    <span style="color: #c678dd;">delete</span>(s.sub, c)
<span class="linenr">39: </span>}
</pre>
</div></li>
</ul>
</div>
<div id="outline-container-org61fe3ce" class="outline-3">
<h3 id="org61fe3ce"><span class="section-number-3">3.1.</span> Options for slow goroutines</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>slow down event generation</li>
<li>drop events if it cannot be sent, e.g., <code>os/signal</code>, <code>runtime/pprof</code></li>
<li><p>
queue events, e.g., add a <code>helper</code> between the server and each client, which also separates the concerns
</p>
<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">func</span> <span style="color: #c678dd;">helper</span>(<span style="color: #dcaeea;">in</span> &lt;-<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Event</span>, <span style="color: #dcaeea;">out</span> <span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>) {
<span class="linenr"> 2: </span>    <span style="color: #51afef;">var</span> <span style="color: #dcaeea;">q</span> []<span style="color: #ECBE7B;">Event</span>
<span class="linenr"> 3: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if the in is closed, flash out the pending events in q</span>
<span class="linenr"> 4: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">and close out</span>
<span class="linenr"> 5: </span>    <span style="color: #51afef;">for</span> in != <span style="color: #a9a1e1;">nil</span> || <span style="color: #c678dd;">len</span>(q) &gt; <span style="color: #da8548; font-weight: bold;">0</span> {
<span class="linenr"> 6: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">decide whether and what to send</span>
<span class="linenr"> 7: </span>        <span style="color: #51afef;">var</span> <span style="color: #dcaeea;">sendOut</span> <span style="color: #51afef;">chan</span>&lt;- <span style="color: #dcaeea;">Event</span>
<span class="linenr"> 8: </span>        <span style="color: #51afef;">var</span> <span style="color: #dcaeea;">next</span> <span style="color: #ECBE7B;">Event</span>
<span class="linenr"> 9: </span>        <span style="color: #51afef;">if</span> <span style="color: #c678dd;">len</span>(q) &gt; <span style="color: #da8548; font-weight: bold;">0</span> {
<span class="linenr">10: </span>            sendOut = out
<span class="linenr">11: </span>            next = q[<span style="color: #da8548; font-weight: bold;">0</span>]
<span class="linenr">12: </span>        }
<span class="linenr">13: </span>        <span style="color: #51afef;">select</span> {
<span class="linenr">14: </span>        <span style="color: #51afef;">case</span> <span style="color: #dcaeea;">e</span>, <span style="color: #dcaeea;">ok</span> := &lt;-in: <span style="color: #5B6268;">// </span><span style="color: #5B6268;">never reaches here after in = nil</span>
<span class="linenr">15: </span>            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">ok tells whether in is closed</span>
<span class="linenr">16: </span>            <span style="color: #51afef;">if</span> <span style="color: #51afef; font-weight: bold;">!</span>ok {
<span class="linenr">17: </span>                in = <span style="color: #a9a1e1;">nil</span>
<span class="linenr">18: </span>                <span style="color: #51afef;">break</span>
<span class="linenr">19: </span>            }
<span class="linenr">20: </span>            q = <span style="color: #c678dd;">append</span>(q, e)
<span class="linenr">21: </span>        <span style="color: #51afef;">case</span> sendOut &lt;- next: <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if len(q) == 0, sendOut = nil</span>
<span class="linenr">22: </span>            q = q[<span style="color: #da8548; font-weight: bold;">1</span>:]
<span class="linenr">23: </span>        }
<span class="linenr">24: </span>    }
<span class="linenr">25: </span>    <span style="color: #c678dd;">close</span>(out)
<span class="linenr">26: </span>}
</pre>
</div></li>
<li><p>
convert mutexes into goroutines, not suitable for Raft where state transition is complex
</p>
<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">Server</span> <span style="color: #51afef;">struct</span> {
<span class="linenr"> 2: </span>    publish   <span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Event</span>
<span class="linenr"> 3: </span>    subscribe <span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">subReq</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a channel to queue unhandled subscription</span>
<span class="linenr"> 4: </span>    cancel    <span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">subReq</span>
<span class="linenr"> 5: </span>}
<span class="linenr"> 6: </span><span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">subReq</span> <span style="color: #51afef;">struct</span> {
<span class="linenr"> 7: </span>    c  <span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>
<span class="linenr"> 8: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a signal of whether an operation succeeds</span>
<span class="linenr"> 9: </span>    ok <span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">bool</span>
<span class="linenr">10: </span>}
<span class="linenr">11: </span>
<span class="linenr">12: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">Init</span>() {
<span class="linenr">13: </span>    s.publish = <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Event</span>)
<span class="linenr">14: </span>    s.subscribe = <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">subReq</span>)
<span class="linenr">15: </span>    s.cancel = <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">subReq</span>)
<span class="linenr">16: </span>    <span style="color: #51afef;">go</span> s.<span style="color: #c678dd;">loop</span>()
<span class="linenr">17: </span>}
<span class="linenr">18: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">Publish</span>(<span style="color: #dcaeea;">e</span> <span style="color: #ECBE7B;">Event</span>) {
<span class="linenr">19: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">no mutex is required here</span>
<span class="linenr">20: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">as it does not read state</span>
<span class="linenr">21: </span>    s.publish &lt;- e
<span class="linenr">22: </span>}
<span class="linenr">23: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">Subscribe</span>(<span style="color: #dcaeea;">c</span> <span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>) {
<span class="linenr">24: </span>    <span style="color: #dcaeea;">r</span> := <span style="color: #ECBE7B;">subReq</span>{<span style="color: #a9a1e1;">c</span>: c, <span style="color: #a9a1e1;">ok</span>: <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">bool</span>)}
<span class="linenr">25: </span>    s.subscribe &lt;- r
<span class="linenr">26: </span>    <span style="color: #51afef;">if</span> <span style="color: #51afef; font-weight: bold;">!</span>&lt;-r.ok {  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">wait for loop() handle result</span>
<span class="linenr">27: </span>        <span style="color: #c678dd;">panic</span>(<span style="color: #98be65;">"pubsub: already subscribed"</span>)
<span class="linenr">28: </span>    }
<span class="linenr">29: </span>}
<span class="linenr">30: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">Cancel</span>(<span style="color: #dcaeea;">c</span> <span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>) {
<span class="linenr">31: </span>    <span style="color: #dcaeea;">r</span> := <span style="color: #ECBE7B;">subReq</span>{<span style="color: #a9a1e1;">c</span>: c, <span style="color: #a9a1e1;">ok</span>: <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">bool</span>)}
<span class="linenr">32: </span>    s.cancel &lt;- r
<span class="linenr">33: </span>    <span style="color: #51afef;">if</span> <span style="color: #51afef; font-weight: bold;">!</span>&lt;-r.ok {
<span class="linenr">34: </span>        <span style="color: #c678dd;">panic</span>(<span style="color: #98be65;">"pubusb: not subscribed"</span>)
<span class="linenr">35: </span>    }
<span class="linenr">36: </span>}
<span class="linenr">37: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">s</span> *<span style="color: #ECBE7B;">Server</span>) <span style="color: #c678dd;">loop</span>() {
<span class="linenr">38: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">now sub is a local variable, no lock is needed</span>
<span class="linenr">39: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">sub maps from a subscribed channel to a helper channel</span>
<span class="linenr">40: </span>    <span style="color: #dcaeea;">sub</span> := <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">map</span>[<span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>]<span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Event</span>)
<span class="linenr">41: </span>    <span style="color: #51afef;">for</span> {
<span class="linenr">42: </span>        <span style="color: #51afef;">select</span> {
<span class="linenr">43: </span>        <span style="color: #51afef;">case</span> <span style="color: #dcaeea;">e</span> := &lt;-s.publish:
<span class="linenr">44: </span>            <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">_</span>, <span style="color: #dcaeea;">h</span> := <span style="color: #51afef;">range</span> sub {
<span class="linenr">45: </span>                <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the event is published to a helper channel</span>
<span class="linenr">46: </span>                h &lt;- e
<span class="linenr">47: </span>            }
<span class="linenr">48: </span>        <span style="color: #51afef;">case</span> <span style="color: #dcaeea;">r</span> := &lt;-s.subscribe:
<span class="linenr">49: </span>            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the helper channel exists</span>
<span class="linenr">50: </span>            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">meaning the subscriber has been handled before</span>
<span class="linenr">51: </span>            <span style="color: #51afef;">if</span> sub[r.c] != <span style="color: #a9a1e1;">nil</span> {
<span class="linenr">52: </span>                r.ok &lt;- <span style="color: #a9a1e1;">false</span>
<span class="linenr">53: </span>                <span style="color: #51afef;">break</span>
<span class="linenr">54: </span>            }
<span class="linenr">55: </span>            h = <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Event</span>)
<span class="linenr">56: </span>            <span style="color: #51afef;">go</span> <span style="color: #c678dd;">helper</span>(h, r.c)
<span class="linenr">57: </span>            sub[r.c] = h
<span class="linenr">58: </span>            r.ok &lt;- <span style="color: #a9a1e1;">true</span>
<span class="linenr">59: </span>        <span style="color: #51afef;">case</span> <span style="color: #dcaeea;">c</span> := &lt;-s.cancel:
<span class="linenr">60: </span>            <span style="color: #51afef;">if</span> <span style="color: #51afef; font-weight: bold;">!</span>sub[r.c] == <span style="color: #a9a1e1;">nil</span>{
<span class="linenr">61: </span>                r.ok &lt;- <span style="color: #a9a1e1;">false</span>
<span class="linenr">62: </span>                <span style="color: #51afef;">break</span>
<span class="linenr">63: </span>            }
<span class="linenr">64: </span>            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">close the helper channel</span>
<span class="linenr">65: </span>            <span style="color: #c678dd;">close</span>(sub[r.c])
<span class="linenr">66: </span>            <span style="color: #c678dd;">delete</span>(sub, r.c)
<span class="linenr">67: </span>            r.ok &lt;- <span style="color: #a9a1e1;">true</span>
<span class="linenr">68: </span>        }
<span class="linenr">69: </span>    }
<span class="linenr">70: </span>}
</pre>
</div></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org3adafe3" class="outline-2">
<h2 id="org3adafe3"><span class="section-number-2">4.</span> Pattern 2: work scheduler</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li><p>
\(M\) tasks assigned to \(N\) servers/workers, \( M >> N\).
</p>

<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">func</span> <span style="color: #c678dd;">Schedule</span>(<span style="color: #dcaeea;">servers</span> []<span style="color: #ECBE7B;">string</span>, <span style="color: #dcaeea;">numTask</span> <span style="color: #ECBE7B;">int</span>,
<span class="linenr"> 2: </span>    <span style="color: #dcaeea;">call</span> <span style="color: #51afef;">func</span>(<span style="color: #dcaeea;">srv</span> <span style="color: #ECBE7B;">string</span>, <span style="color: #dcaeea;">task</span> <span style="color: #ECBE7B;">int</span>)) {
<span class="linenr"> 3: </span>
<span class="linenr"> 4: </span>    <span style="color: #dcaeea;">idle</span> := <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">string</span>, <span style="color: #c678dd;">len</span>(servers))
<span class="linenr"> 5: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">initialize a channel of idle servers</span>
<span class="linenr"> 6: </span>    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">_</span>, <span style="color: #dcaeea;">srv</span> := <span style="color: #51afef;">range</span> servers {
<span class="linenr"> 7: </span>        idle &lt;- srv
<span class="linenr"> 8: </span>    }
<span class="linenr"> 9: </span>
<span class="linenr">10: </span>    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">task</span> := <span style="color: #da8548; font-weight: bold;">0</span>, task &lt; numTask; task++ {
<span class="linenr">11: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if using task in the for loop rather than a local task,</span>
<span class="linenr">12: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">there is a race: the loop goes on before the goroutinue starts,</span>
<span class="linenr">13: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">so that some tasks are skipped.</span>
<span class="linenr">14: </span>        <span style="color: #dcaeea;">task</span> := task
<span class="linenr">15: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if moving srv := &lt;- idle inside goroutine</span>
<span class="linenr">16: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a lot of goroutines are created simoutaneously and hung</span>
<span class="linenr">17: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">due to non-idle server</span>
<span class="linenr">18: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">leaving it outside so that a goroutine is only created when</span>
<span class="linenr">19: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">there is an idle server (but it slows down the main loop)</span>
<span class="linenr">20: </span>        <span style="color: #dcaeea;">srv</span> := &lt;-idle
<span class="linenr">21: </span>        <span style="color: #51afef;">go</span> <span style="color: #51afef;">func</span>() {
<span class="linenr">22: </span>            <span style="color: #c678dd;">call</span>(srv, task) <span style="color: #5B6268;">// </span><span style="color: #5B6268;">server does the task</span>
<span class="linenr">23: </span>            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">serve finishes the task and becomes idle again</span>
<span class="linenr">24: </span>            idle &lt;- srv
<span class="linenr">25: </span>        }()
<span class="linenr">26: </span>    }
<span class="linenr">27: </span>
<span class="linenr">28: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">determine when all tasks are done / all servers are idle</span>
<span class="linenr">29: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">this is used to prevent early exit when all tasks have been assigned</span>
<span class="linenr">30: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">but the last servers have not finished</span>
<span class="linenr">31: </span>    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">i</span> :=<span style="color: #da8548; font-weight: bold;">0</span>; i &lt; <span style="color: #c678dd;">len</span>(servers); i++ {
<span class="linenr">32: </span>        &lt;-idle
<span class="linenr">33: </span>    }
<span class="linenr">34: </span>}
</pre>
</div></li>

<li><p>
Optimization for the above code: while the task loop creates goroutines \(M\) times, actually there are only at most \(N\) active goroutines at any time.
</p>
<ul class="org-ul">
<li>Better to spin off a goroutine for each server.</li>
<li>The number of servers can be dynamic.</li>
</ul>

<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">func</span> <span style="color: #c678dd;">Schedule</span>(<span style="color: #dcaeea;">servers</span> <span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">string</span>, <span style="color: #dcaeea;">numTask</span> <span style="color: #ECBE7B;">int</span>,
<span class="linenr"> 2: </span>    <span style="color: #dcaeea;">call</span> <span style="color: #51afef;">func</span>(<span style="color: #dcaeea;">srv</span> <span style="color: #ECBE7B;">string</span>, <span style="color: #dcaeea;">task</span> <span style="color: #ECBE7B;">int</span>)) {
<span class="linenr"> 3: </span>
<span class="linenr"> 4: </span>    <span style="color: #dcaeea;">work</span> := <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">int</span>)  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a queue of all works yet to be done</span>
<span class="linenr"> 5: </span>    <span style="color: #dcaeea;">done</span> := <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">bool</span>) <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a queue of all done tasks</span>
<span class="linenr"> 6: </span>    <span style="color: #dcaeea;">exit</span> := <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">bool</span>) <span style="color: #5B6268;">// </span><span style="color: #5B6268;">signal when should not pull new servers</span>
<span class="linenr"> 7: </span>
<span class="linenr"> 8: </span>    <span style="color: #dcaeea;">runTasks</span> := <span style="color: #51afef;">func</span>(<span style="color: #dcaeea;">srv</span> <span style="color: #ECBE7B;">string</span>) {
<span class="linenr"> 9: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">keep polling until work is closed</span>
<span class="linenr">10: </span>        <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">task</span> := <span style="color: #51afef;">range</span> work {
<span class="linenr">11: </span>            <span style="color: #51afef;">if</span> <span style="color: #c678dd;">call</span>(srv, task) {
<span class="linenr">12: </span>                done &lt;- <span style="color: #a9a1e1;">true</span>
<span class="linenr">13: </span>            } <span style="color: #51afef;">else</span> {
<span class="linenr">14: </span>                <span style="color: #5B6268;">// </span><span style="color: #5B6268;">repush the task if it failed</span>
<span class="linenr">15: </span>                work &lt;- task
<span class="linenr">16: </span>            }
<span class="linenr">17: </span>        }
<span class="linenr">18: </span>    }
<span class="linenr">19: </span>
<span class="linenr">20: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">use a goroutine to avoid hanging when</span>
<span class="linenr">21: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">no server is available</span>
<span class="linenr">22: </span>    <span style="color: #51afef;">go</span> <span style="color: #51afef;">func</span>() {
<span class="linenr">23: </span>        <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">_</span>, <span style="color: #dcaeea;">srv</span> := <span style="color: #51afef;">range</span> servers {
<span class="linenr">24: </span>            <span style="color: #51afef;">for</span> {
<span class="linenr">25: </span>                <span style="color: #51afef;">select</span> {
<span class="linenr">26: </span>                <span style="color: #51afef;">case</span> <span style="color: #dcaeea;">src</span> := &lt;-servers:
<span class="linenr">27: </span>                    <span style="color: #51afef;">go</span> <span style="color: #c678dd;">runTasks</span>(srv)
<span class="linenr">28: </span>                <span style="color: #51afef;">case</span> &lt;-exit:
<span class="linenr">29: </span>                    <span style="color: #51afef;">return</span>
<span class="linenr">30: </span>                }
<span class="linenr">31: </span>            }
<span class="linenr">32: </span>        }
<span class="linenr">33: </span>    }()
<span class="linenr">34: </span>
<span class="linenr">35: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">The following code has a deadlock!</span>
<span class="linenr">36: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">In the runTasks, the server pushes to done channel when a task is done.</span>
<span class="linenr">37: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">However, the done channel is only pulled when the main routine has</span>
<span class="linenr">38: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">pushed all tasks and close the work channel.</span>
<span class="linenr">39: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">Therefore any server hangs when trying push the second done work.</span>
<span class="linenr">40: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">for taks := 0; task &lt; numTask; task++ {</span>
<span class="linenr">41: </span>    <span style="color: #5B6268;">//  </span><span style="color: #5B6268;">work &lt;- task</span>
<span class="linenr">42: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">}</span>
<span class="linenr">43: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">// signal no more task so that servers know</span>
<span class="linenr">44: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">// when to termiante</span>
<span class="linenr">45: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">close(work)</span>
<span class="linenr">46: </span>
<span class="linenr">47: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">// wait until all tasks are done</span>
<span class="linenr">48: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">for i := 0; i &lt; numTask; i++ {</span>
<span class="linenr">49: </span>    <span style="color: #5B6268;">//  </span><span style="color: #5B6268;">&lt;-done</span>
<span class="linenr">50: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">}</span>
<span class="linenr">51: </span>
<span class="linenr">52: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">fix 1: one can switch between work and donw channel</span>
<span class="linenr">53: </span>    <span style="color: #dcaeea;">i</span> := <span style="color: #da8548; font-weight: bold;">0</span>
<span class="linenr">54: </span><span style="color: #a9a1e1;">WorkLoop</span>:
<span class="linenr">55: </span>    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">task</span> := <span style="color: #da8548; font-weight: bold;">0</span>; task &lt; numTask; task++ {
<span class="linenr">56: </span>        <span style="color: #51afef;">for</span> {
<span class="linenr">57: </span>            <span style="color: #51afef;">select</span> {
<span class="linenr">58: </span>            <span style="color: #51afef;">case</span> work &lt;- task:
<span class="linenr">59: </span>                <span style="color: #51afef;">continue</span> <span style="color: #a9a1e1;">WorkLoop</span>
<span class="linenr">60: </span>            <span style="color: #51afef;">case</span> &lt;-done:
<span class="linenr">61: </span>                i++
<span class="linenr">62: </span>            }
<span class="linenr">63: </span>        }
<span class="linenr">64: </span>    }
<span class="linenr">65: </span>
<span class="linenr">66: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">wait for the last assigned tasks to be done</span>
<span class="linenr">67: </span>    <span style="color: #51afef;">for</span> ; i &lt; numTask; i++ {
<span class="linenr">68: </span>        &lt;-done
<span class="linenr">69: </span>    }
<span class="linenr">70: </span>
<span class="linenr">71: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">only close work channel in the end,</span>
<span class="linenr">72: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">in case some tasks failed and need to be redo</span>
<span class="linenr">73: </span>    <span style="color: #c678dd;">close</span>(work)
<span class="linenr">74: </span>    exit &lt;- <span style="color: #a9a1e1;">true</span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">stop pulling new servers</span>
<span class="linenr">75: </span>
<span class="linenr">76: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">fix 2: move the work assignment to a separate go routine</span>
<span class="linenr">77: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">go func() {</span>
<span class="linenr">78: </span>    <span style="color: #5B6268;">//  </span><span style="color: #5B6268;">for task := ; task &lt; numTask; task++ {</span>
<span class="linenr">79: </span>    <span style="color: #5B6268;">//      </span><span style="color: #5B6268;">work &lt;- task</span>
<span class="linenr">80: </span>    <span style="color: #5B6268;">//  </span><span style="color: #5B6268;">}</span>
<span class="linenr">81: </span>    <span style="color: #5B6268;">//  </span><span style="color: #5B6268;">close(work)</span>
<span class="linenr">82: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">}()</span>
<span class="linenr">83: </span>
<span class="linenr">84: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">fix 3: increase buffer for the work channel</span>
<span class="linenr">85: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">work := make(chan int, numTask)</span>
<span class="linenr">86: </span>}
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orge8d82f7" class="outline-2">
<h2 id="orge8d82f7"><span class="section-number-2">5.</span> Pattern 3: replicated service client</h2>
<div class="outline-text-2" id="text-5">
<ul class="org-ul">
<li><p>
A client replicates its requests to multiple servers, waits for the first reply and changes its preferred server.
</p>

<div class="org-src-container">
<pre class="src src-go"><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">c</span> *<span style="color: #ECBE7B;">Client</span>) <span style="color: #c678dd;">Call</span>(<span style="color: #dcaeea;">args</span> <span style="color: #ECBE7B;">Args</span>) <span style="color: #ECBE7B;">Reply</span> {
    <span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">result</span> <span style="color: #51afef;">struct</span> {
        serverID <span style="color: #ECBE7B;">int</span>
        reply <span style="color: #ECBE7B;">Reply</span>
    }

    <span style="color: #51afef;">const</span> <span style="color: #a9a1e1;">timeout</span> = <span style="color: #da8548; font-weight: bold;">1</span> * time.Second
    <span style="color: #dcaeea;">t</span> := time.<span style="color: #c678dd;">NewTimer</span>(timeout)
    <span style="color: #51afef;">defer</span> t.<span style="color: #c678dd;">Stop</span>()

    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">a channel for all servers to send reply</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">so that even if the client has received a reply</span>
    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">other later replies don't hang</span>
    <span style="color: #dcaeea;">done</span> := <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">result</span>, <span style="color: #c678dd;">len</span>(c.servers))

    c.mu.<span style="color: #c678dd;">Lock</span>()
    <span style="color: #dcaeea;">prefer</span> := c.prefer
    c.mu.<span style="color: #c678dd;">Unlock</span>()

    <span style="color: #51afef;">var</span> <span style="color: #dcaeea;">r</span> <span style="color: #ECBE7B;">result</span>
    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">off</span> := <span style="color: #da8548; font-weight: bold;">0</span>; off &lt; <span style="color: #c678dd;">len</span>(c.servers); off++ {
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">start from the preferred server</span>
        <span style="color: #dcaeea;">id</span> := (prefer + off) % <span style="color: #c678dd;">len</span>(c.servers)
        <span style="color: #51afef;">go</span> <span style="color: #51afef;">func</span>() {
            done &lt;- <span style="color: #ECBE7B;">result</span>{id, c.<span style="color: #c678dd;">callOne</span>(c.servers[id], arfs)}
        }()

        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">now wait for either a done signal or a timeout</span>
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if it is done, don't send to other servers</span>
        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">otherwise, reset the timer and sends to the next server</span>
        <span style="color: #51afef;">select</span> {
        <span style="color: #51afef;">case</span> r = &lt;-done:
            <span style="color: #51afef;">goto</span> <span style="color: #a9a1e1;">Done</span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">use a goto if it makes code clear</span>
        <span style="color: #51afef;">case</span> &lt;-t.C:
            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">timeout</span>
            t.<span style="color: #c678dd;">Reset</span>(timeout)
        }
    }

    r = &lt;-done  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">wait for the first reply even if it is a RPC timeout</span>

<span style="color: #a9a1e1;">Done</span>:
    c.mu.<span style="color: #c678dd;">Lock</span>()
    c.prefer = r.serverID <span style="color: #5B6268;">// </span><span style="color: #5B6268;">update preference</span>
    c.mu.<span style="color: #c678dd;">Unlock</span>()
    <span style="color: #51afef;">return</span> r.reply
}

</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orgdeb5e2d" class="outline-2">
<h2 id="orgdeb5e2d"><span class="section-number-2">6.</span> Pattern 4: Protocol multiplexer</h2>
<div class="outline-text-2" id="text-6">
<ul class="org-ul">
<li><p>
A multiplexer sits in front of a service and forward messages between multiple clients and the service, e.g., an RPC.
</p>

<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">ProtocolMux</span> <span style="color: #51afef;">interface</span> {
<span class="linenr"> 2: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">A mux is binded to a specific service</span>
<span class="linenr"> 3: </span>    <span style="color: #c678dd;">Init</span>(<span style="color: #ECBE7B;">Service</span>)
<span class="linenr"> 4: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">A client uses this method to send message to the service</span>
<span class="linenr"> 5: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">and wait for the service reply</span>
<span class="linenr"> 6: </span>    <span style="color: #c678dd;">Call</span>(<span style="color: #ECBE7B;">Msg</span>) <span style="color: #ECBE7B;">Msg</span>
<span class="linenr"> 7: </span>}
<span class="linenr"> 8: </span>
<span class="linenr"> 9: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">Methods that a service exposes to let a mux use</span>
<span class="linenr">10: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">Underlining messgae processing are in the implementation</span>
<span class="linenr">11: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">of the actual service struct</span>
<span class="linenr">12: </span><span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">Service</span> <span style="color: #51afef;">interface</span> {
<span class="linenr">13: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">A tag is a muxing identifier in the request or reply message,</span>
<span class="linenr">14: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">e.g., which client channel to send the reply</span>
<span class="linenr">15: </span>    <span style="color: #c678dd;">ReadTag</span>(<span style="color: #ECBE7B;">Msg</span>) <span style="color: #ECBE7B;">int64</span>
<span class="linenr">16: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">Send a request message to the service</span>
<span class="linenr">17: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">multiple sends cannot be called concurrently</span>
<span class="linenr">18: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">probably due to only a single channel between</span>
<span class="linenr">19: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">mux and the service (serialization)</span>
<span class="linenr">20: </span>    <span style="color: #c678dd;">Send</span>(<span style="color: #ECBE7B;">Msg</span>)
<span class="linenr">21: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">Waits and return the reply message,</span>
<span class="linenr">22: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">multiple recvs cannot be called concurrently</span>
<span class="linenr">23: </span>    <span style="color: #c678dd;">Recv</span>() <span style="color: #ECBE7B;">Msg</span>
<span class="linenr">24: </span>}
</pre>
</div></li>

<li><p>
The mux maintains a channel to queue unsent requests and a channel to queue unsent replies.
</p>

<div class="org-src-container">
<pre class="src src-go"><span class="linenr"> 1: </span><span style="color: #51afef;">type</span> <span style="color: #ECBE7B;">Mux</span> <span style="color: #51afef;">struct</span> {
<span class="linenr"> 2: </span>    srv <span style="color: #ECBE7B;">Service</span>
<span class="linenr"> 3: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">stores unsent requests</span>
<span class="linenr"> 4: </span>    send <span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Msg</span>
<span class="linenr"> 5: </span>    mu <span style="color: #ECBE7B;">sync.Mutex</span>
<span class="linenr"> 6: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">maps channel tag to channel</span>
<span class="linenr"> 7: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">whose replies have not been sent out</span>
<span class="linenr"> 8: </span>    pending <span style="color: #51afef;">map</span>[<span style="color: #ECBE7B;">int64</span>]<span style="color: #51afef;">chan</span>&lt;- <span style="color: #ECBE7B;">Msg</span>
<span class="linenr"> 9: </span>}
<span class="linenr">10: </span>
<span class="linenr">11: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">m</span> *<span style="color: #ECBE7B;">Mux</span>) <span style="color: #c678dd;">Init</span>(<span style="color: #dcaeea;">srv</span> <span style="color: #ECBE7B;">Service</span>) {
<span class="linenr">12: </span>    m.srv = srv
<span class="linenr">13: </span>    m.pending = <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">map</span>[<span style="color: #ECBE7B;">int64</span>]<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Msg</span>)
<span class="linenr">14: </span>    <span style="color: #51afef;">go</span> m.<span style="color: #c678dd;">sendLoop</span>()
<span class="linenr">15: </span>    <span style="color: #51afef;">go</span> m.<span style="color: #c678dd;">recvLoop</span>()
<span class="linenr">16: </span>}
<span class="linenr">17: </span>
<span class="linenr">18: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">sending out queued requests</span>
<span class="linenr">19: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">m</span> *<span style="color: #ECBE7B;">Mux</span>) <span style="color: #ECBE7B;">sendLoop</span> {
<span class="linenr">20: </span>    <span style="color: #51afef;">for</span> <span style="color: #dcaeea;">args</span> := <span style="color: #51afef;">range</span> m.send {
<span class="linenr">21: </span>        m.srv.<span style="color: #c678dd;">Send</span>(args)
<span class="linenr">22: </span>    }
<span class="linenr">23: </span>}
<span class="linenr">24: </span>
<span class="linenr">25: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">m</span> *<span style="color: #ECBE7B;">Mux</span>) <span style="color: #c678dd;">recvLoop</span>() {
<span class="linenr">26: </span>    <span style="color: #51afef;">for</span> {
<span class="linenr">27: </span>        <span style="color: #dcaeea;">reply</span> := m.srv.<span style="color: #c678dd;">Recv</span>()
<span class="linenr">28: </span>        <span style="color: #dcaeea;">tag</span> := m.srv.<span style="color: #c678dd;">ReadTag</span>(reply)
<span class="linenr">29: </span>        m.mu.<span style="color: #c678dd;">Lock</span>()
<span class="linenr">30: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">get the reply channel</span>
<span class="linenr">31: </span>        <span style="color: #dcaeea;">done</span> := m.pending[tag]
<span class="linenr">32: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">clear the channel since the message loop</span>
<span class="linenr">33: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">is complete</span>
<span class="linenr">34: </span>        <span style="color: #c678dd;">delete</span>(m.pending, tag)
<span class="linenr">35: </span>        m.mu.<span style="color: #c678dd;">Unlock</span>()
<span class="linenr">36: </span>
<span class="linenr">37: </span>        <span style="color: #51afef;">if</span> done == <span style="color: #a9a1e1;">nil</span> {
<span class="linenr">38: </span>            <span style="color: #c678dd;">panic</span>(<span style="color: #98be65;">"unexpected reply"</span>)
<span class="linenr">39: </span>        }
<span class="linenr">40: </span>        done &lt;- reply
<span class="linenr">41: </span>    }
<span class="linenr">42: </span>
<span class="linenr">43: </span>}
<span class="linenr">44: </span>
<span class="linenr">45: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">Clients call this method concurrently</span>
<span class="linenr">46: </span><span style="color: #51afef;">func</span> (<span style="color: #dcaeea;">m</span> *<span style="color: #ECBE7B;">Mux</span>) <span style="color: #c678dd;">Call</span>(<span style="color: #dcaeea;">args</span> <span style="color: #ECBE7B;">Msg</span>) (<span style="color: #dcaeea;">reply</span> <span style="color: #ECBE7B;">Msg</span>) {
<span class="linenr">47: </span>    <span style="color: #dcaeea;">tag</span> := m.srv.<span style="color: #c678dd;">ReadTag</span>(args)
<span class="linenr">48: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to record which message should reply</span>
<span class="linenr">49: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">to which client</span>
<span class="linenr">50: </span>    <span style="color: #dcaeea;">done</span> := <span style="color: #c678dd;">make</span>(<span style="color: #51afef;">chan</span> <span style="color: #ECBE7B;">Msg</span>, <span style="color: #da8548; font-weight: bold;">1</span>)
<span class="linenr">51: </span>    m.mu.<span style="color: #c678dd;">Lock</span>()
<span class="linenr">52: </span>    <span style="color: #51afef;">if</span> m.pending[tag] != <span style="color: #a9a1e1;">nil</span> {
<span class="linenr">53: </span>        m.mu.<span style="color: #c678dd;">Unlock</span>()
<span class="linenr">54: </span>        <span style="color: #c678dd;">panic</span>(<span style="color: #98be65;">"duplicate request"</span>)
<span class="linenr">55: </span>    }
<span class="linenr">56: </span>    m.pending[tag] = done
<span class="linenr">57: </span>    m.mu.<span style="color: #c678dd;">Unlock</span>()
<span class="linenr">58: </span>    m.send &lt;- args
<span class="linenr">59: </span>    <span style="color: #51afef;">return</span> &lt;-done <span style="color: #5B6268;">// </span><span style="color: #5B6268;">hang until a reply is received</span>
<span class="linenr">60: </span>}
</pre>
</div></li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-go.html">go</a> <a href="https://chenyo.me/tag-design-pattern.html">design-pattern</a> <a href="https://chenyo.me/tag-study.html">study</a> </div>]]></description>
  <category><![CDATA[go]]></category>
  <category><![CDATA[design-pattern]]></category>
  <category><![CDATA[study]]></category>
  <link>https://chenyo.me/2024-06-25-go-patterns.html</link>
  <guid>https://chenyo.me/2024-06-25-go-patterns.html</guid>
  <pubDate>Tue, 25 Jun 2024 21:25:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[A stupid debugging experience]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgb161311">1. What happened</a></li>
<li><a href="#org1b3845c">2. What did I do</a></li>
<li><a href="#orga298fdf">3. Another issue of running RPC in docker</a></li>
</ul>
</div>
</nav>
<div id="outline-container-orgb161311" class="outline-2">
<h2 id="orgb161311"><span class="section-number-2">1.</span> What happened</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>Servers SA and SB have the same docker installation, and the same running container CA and CB.</li>
<li><p>
A Go file G can be built on CA, but on CB it reports this error:
</p>
<p class="verse">
runtime: failed to create new OS thread (have 2 already; errno=11)<br>
runtime: may need to increase max user processes (ulimit -u)<br>
fatal error: newosproc<br>
</p></li>
</ul>
</div>
</div>
<div id="outline-container-org1b3845c" class="outline-2">
<h2 id="org1b3845c"><span class="section-number-2">2.</span> What did I do</h2>
<div class="outline-text-2" id="text-2">
<ol class="org-ol">
<li>I compared any related configurations between SA and SB. and between CA and CB, e.g., <code class="src src-bash"><span style="color: #c678dd;">ulimit</span> -a</code>, <code class="src src-bash">/etc/security/limits.conf</code>. They all look the same.</li>
<li>I created a new container CN on SA with the same docker image, CN can compile G.</li>
<li>I looked into the (complex) <code>docker run</code> script for CA/CB and figured out it was due to a resource constraint <code>--pids-limit 100</code>.
<ul class="org-ul">
<li>Increasing this limit to 200 seems resolve the issue, but I had no idea why the Go compiler needed so many resources (perhaps due to package I imported).</li>
</ul></li>
<li><b><b>Until this point</b></b>, I realized, since the container did not support the compilation, why not just only transfer the compiled binary!
<ul class="org-ul">
<li>How silly that I didn&rsquo;t even try this in the beginning!</li>
</ul></li>
<li>Since the program imports the <code>net</code> package, and there is a <a href="https://www.reddit.com/r/golang/comments/pi97sp/what_is_the_consequence_of_using_cgo_enabled0/">known issue</a> of Alpine image running a Go binary file, I followed the post and disabled <code>CGO</code> on SA, then <code>docker cp</code> the binary to CA, and it worked.</li>
</ol>
</div>
</div>
<div id="outline-container-orga298fdf" class="outline-2">
<h2 id="orga298fdf"><span class="section-number-2">3.</span> Another issue of running RPC in docker</h2>
<div class="outline-text-2" id="text-3">
<ul class="org-ul">
<li>The other day, I also spent hours debugging a <code>route unreachable</code> error when I want to send a request from CA to SA.</li>
<li>The CA is using the <code>bridge</code> network, so it should talk to SA via SA&rsquo;s interface <code>docker0</code> within the subnet <code>172.17.0.0/16</code>.</li>
<li><p>
However, in my case, the docker by default rejects packages from any container as shown in SA&rsquo;s <code>tcpdump</code> result:
</p>
<p class="verse">
172.17.0.1-&gt;172.17.0.3 ICMP host unreachable- admin prohibited, length 68<br>
</p></li>

<li><p>
By checking SA&rsquo;s iptables, I found this rule:
</p>
<div class="org-src-container">
<pre class="src src-bash">  -A INPUT -j REJECT --reject-with icmp-host-prohibited
</pre>
</div>
<ul class="org-ul">
<li>Strangely, the <code>ping</code> still works with this rule.</li>
</ul></li>

<li><p>
In the end, I need to append a new rule to make the RPC work.
</p>
<div class="org-src-container">
<pre class="src src-bash">  iptables -I INPUT <span style="color: #da8548; font-weight: bold;">1</span> -i docker0 -p tcp --dport &lt;port&gt; -s 172.17.0.0/16 -j ACCEPT
</pre>
</div></li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-docker.html">docker</a> <a href="https://chenyo.me/tag-go.html">go</a> <a href="https://chenyo.me/tag-linux.html">linux</a> <a href="https://chenyo.me/tag-alpine.html">alpine</a> </div>]]></description>
  <category><![CDATA[docker]]></category>
  <category><![CDATA[go]]></category>
  <category><![CDATA[linux]]></category>
  <category><![CDATA[alpine]]></category>
  <link>https://chenyo.me/2024-06-24-a-stupid-debugging-experience.html</link>
  <guid>https://chenyo.me/2024-06-24-a-stupid-debugging-experience.html</guid>
  <pubDate>Mon, 24 Jun 2024 15:06:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Linux use tips]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org4295e4f">1. i3</a>
<ul>
<li><a href="#org6d4480c">1.1. Move specific workspaces between different monitors (ref)</a></li>
</ul>
</li>
<li><a href="#org67db899">2. Org</a>
<ul>
<li><a href="#orgf55dd61">2.1. Format code blocks</a></li>
</ul>
</li>
<li><a href="#org8b3676f">3. Emacs</a>
<ul>
<li><a href="#org884271c">3.1. Prefix argument</a></li>
<li><a href="#org269c400">3.2. Help functions</a></li>
</ul>
</li>
<li><a href="#org47ea020">4. Vim</a>
<ul>
<li><a href="#org738a838">4.1. Delete a word backwards</a></li>
</ul>
</li>
<li><a href="#org2735990">5. Firefox</a>
<ul>
<li><a href="#org1a17489">5.1. Cache bypass refresh</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<div id="outline-container-org4295e4f" class="outline-2">
<h2 id="org4295e4f"><span class="section-number-2">1.</span> i3</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org6d4480c" class="outline-3">
<h3 id="org6d4480c"><span class="section-number-3">1.1.</span> Move specific workspaces between different monitors <a href="https://i3wm.org/docs/user-contributed/swapping-workspaces.html">(ref)</a></h3>
<div class="outline-text-3" id="text-1-1">
<ol class="org-ol">
<li>Adjust the monitor relative positions.</li>
<li>Use <code class="src src-bash">i3-msg -- move workspace to output right</code> to move the <b><b>current</b></b> workspace to the monitor on the right</li>
</ol>
</div>
</div>
</div>
<div id="outline-container-org67db899" class="outline-2">
<h2 id="org67db899"><span class="section-number-2">2.</span> Org</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-orgf55dd61" class="outline-3">
<h3 id="orgf55dd61"><span class="section-number-3">2.1.</span> Format code blocks</h3>
<div class="outline-text-3" id="text-2-1">
<ul class="org-ul">
<li>Use the shortcut <code>&lt; s &lt;TAB&gt;</code> to create a code block.</li>
<li>Use <code>C-c '</code> to enter the code environment to use the language major mode.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org8b3676f" class="outline-2">
<h2 id="org8b3676f"><span class="section-number-2">3.</span> Emacs</h2>
<div class="outline-text-2" id="text-3">
</div>
<div id="outline-container-org884271c" class="outline-3">
<h3 id="org884271c"><span class="section-number-3">3.1.</span> Prefix argument</h3>
<div class="outline-text-3" id="text-3-1">
<ul class="org-ul">
<li>When the function includes <code>(interactive "P")</code>, it means one can add a prefix argument <code>C-u 1</code> (or any integer) to trigger some effect.</li>
</ul>
</div>
</div>
<div id="outline-container-org269c400" class="outline-3">
<h3 id="org269c400"><span class="section-number-3">3.2.</span> Help functions</h3>
<div class="outline-text-3" id="text-3-2">
<ul class="org-ul">
<li><code>Ctrl-h K</code> get the function name given a shortcut</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org47ea020" class="outline-2">
<h2 id="org47ea020"><span class="section-number-2">4.</span> Vim</h2>
<div class="outline-text-2" id="text-4">
</div>
<div id="outline-container-org738a838" class="outline-3">
<h3 id="org738a838"><span class="section-number-3">4.1.</span> Delete a word backwards</h3>
<div class="outline-text-3" id="text-4-1">
<ul class="org-ul">
<li><code>diw</code> or <code>daw</code></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org2735990" class="outline-2">
<h2 id="org2735990"><span class="section-number-2">5.</span> Firefox</h2>
<div class="outline-text-2" id="text-5">
</div>
<div id="outline-container-org1a17489" class="outline-3">
<h3 id="org1a17489"><span class="section-number-3">5.1.</span> Cache bypass refresh</h3>
<div class="outline-text-3" id="text-5-1">
<ul class="org-ul">
<li><code>Ctrl+Shift+R</code></li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-tool.html">tool</a> <a href="https://chenyo.me/tag-linux.html">linux</a> <a href="https://chenyo.me/tag-i3.html">i3</a> <a href="https://chenyo.me/tag-arch.html">arch</a> </div>]]></description>
  <category><![CDATA[tool]]></category>
  <category><![CDATA[linux]]></category>
  <category><![CDATA[i3]]></category>
  <category><![CDATA[arch]]></category>
  <link>https://chenyo.me/2024-06-24-linux-use-tips.html</link>
  <guid>https://chenyo.me/2024-06-24-linux-use-tips.html</guid>
  <pubDate>Mon, 24 Jun 2024 09:17:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Weblab notes: React route]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgf216bd7">1. Router</a></li>
<li><a href="#org3050897">2. Link</a></li>
<li><a href="#org1a49774">3. Workshop 3</a>
<ul>
<li><a href="#org7e7d415">3.1. Structure</a></li>
<li><a href="#orgfc4e447">3.2. States</a></li>
<li><a href="#org81ec6fe">3.3. Props</a></li>
<li><a href="#orgb072e6c">3.4. Why passing down the update function in props 1, 4, 6?</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://docs.google.com/presentation/d/1hrTjcB8GU4hWPHzS5lI17WALogP4biZ1UAtyxXfafkI/edit#slide=id.p">web.lab lectures</a>.
</p>
<div id="outline-container-orgf216bd7" class="outline-2">
<h2 id="orgf216bd7"><span class="section-number-2">1.</span> Router</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>use the Reach <a href="https://reach.tech/router/">Reach Router</a> library</li>
<li><p>
URL -&gt; Router -&gt; render different components
</p>
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span>&lt;App&gt;
<span class="linenr">2: </span>  <span style="color: #5B6268;">// </span><span style="color: #5B6268;">conditional rendering based on curren url</span>
<span class="linenr">3: </span>  &lt;Router&gt;
<span class="linenr">4: </span>    &lt;Home path=<span style="color: #98be65;">"/"</span> /&gt; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">root path</span>
<span class="linenr">5: </span>    &lt;Dashboard path=<span style="color: #98be65;">"dashboard"</span> /&gt; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">relative to the current URL</span>
<span class="linenr">6: </span>    &lt;Team path=<span style="color: #98be65;">"/team"</span> /&gt; <span style="color: #5B6268;">// </span><span style="color: #5B6268;">absolute path: root path + "/team"</span>
<span class="linenr">7: </span>    &lt;NotFound <span style="color: #51afef;">default</span> /&gt;
<span class="linenr">8: </span>  &lt;/Router&gt;
<span class="linenr">9: </span>&lt;/App&gt;;
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-org3050897" class="outline-2">
<h2 id="org3050897"><span class="section-number-2">2.</span> Link</h2>
<div class="outline-text-2" id="text-2">
<ul class="org-ul">
<li>relative: <code class="src src-js">&lt;Link to=<span style="color: #98be65;">"newpage"</span>&gt;Click me&lt;/Link&gt;</code></li>
<li>absolute: <code class="src src-js">&lt;Link to=<span style="color: #98be65;">"/newpage"</span>&gt;Click me&lt;/Link&gt;</code></li>
</ul>
</div>
</div>
<div id="outline-container-org1a49774" class="outline-2">
<h2 id="org1a49774"><span class="section-number-2">3.</span> Workshop 3</h2>
<div class="outline-text-2" id="text-3">
</div>
<div id="outline-container-org7e7d415" class="outline-3">
<h3 id="org7e7d415"><span class="section-number-3">3.1.</span> Structure</h3>
<div class="outline-text-3" id="text-3-1">

<figure id="org11dec7f">
<img src="./static/workshop-3-structure.png" alt="workshop-3-structure.png" align="center" width="600px">

<figcaption><span class="figure-number">Figure 1: </span>The Catbook structure in workshop 3</figcaption>
</figure>
</div>
</div>
<div id="outline-container-orgfc4e447" class="outline-3">
<h3 id="orgfc4e447"><span class="section-number-3">3.2.</span> States</h3>
<div class="outline-text-3" id="text-3-2">
<table>


<colgroup>
<col  class="org-center">
</colgroup>

<colgroup>
<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-center">name</th>
<th scope="col" class="org-left">states</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-center">Feed</td>
<td class="org-left"><code>stories</code>: a list of stories</td>
</tr>

<tr>
<td class="org-center">Card</td>
<td class="org-left"><code>comments</code>: a list of comments for a story id</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org81ec6fe" class="outline-3">
<h3 id="org81ec6fe"><span class="section-number-3">3.3.</span> Props</h3>
<div class="outline-text-3" id="text-3-3">
<table>


<colgroup>
<col  class="org-center">
</colgroup>

<colgroup>
<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-center">index</th>
<th scope="col" class="org-left">props</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-center">1</td>
<td class="org-left">a function to update <code>stories</code></td>
</tr>

<tr>
<td class="org-center">2</td>
<td class="org-left">all attributes in a story</td>
</tr>

<tr>
<td class="org-center">3</td>
<td class="org-left">the attributes used to display a story</td>
</tr>

<tr>
<td class="org-center">4</td>
<td class="org-left">a story id; a list of comments under the story; a function to update <code>comments</code></td>
</tr>

<tr>
<td class="org-center">5</td>
<td class="org-left">all attributes in a comment</td>
</tr>

<tr>
<td class="org-center">6</td>
<td class="org-left">a comment id; the function to update <code>comments</code></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-orgb072e6c" class="outline-3">
<h3 id="orgb072e6c"><span class="section-number-3">3.4.</span> Why passing down the update function in props 1, 4, 6?</h3>
<div class="outline-text-3" id="text-3-4">
<ul class="org-ul">
<li>To share the parent states, i.e., <code>stories</code> and <code>comments</code> to child component. Since the post action happens in the child component, we need a way to automatically update the states to see new contents immediately.</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-web.html">web</a> <a href="https://chenyo.me/tag-react.html">react</a> <a href="https://chenyo.me/tag-mit.html">mit</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[web]]></category>
  <category><![CDATA[react]]></category>
  <category><![CDATA[mit]]></category>
  <link>https://chenyo.me/2024-06-23-weblab-notes:-react-route.html</link>
  <guid>https://chenyo.me/2024-06-23-weblab-notes:-react-route.html</guid>
  <pubDate>Sun, 23 Jun 2024 18:38:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Weblab notes: React hooks]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org847bf81">1. What is a React hook</a>
<ul>
<li><a href="#orga170863">1.1. <code>useState</code> is not enough</a></li>
<li><a href="#orgf8b0571">1.2. <code>useEffect</code> runs after specific variable change</a></li>
</ul>
</li>
<li><a href="#org1fec729">2. React hook patterns</a>
<ul>
<li><a href="#org14c62ca">2.1. Fetch and send data</a></li>
<li><a href="#org662280e">2.2. Conditional rendering</a></li>
<li><a href="#org173ac44">2.3. Render an array of Data</a></li>
</ul>
</li>
<li><a href="#orgf88bca8">3. Example: Stopwatch</a></li>
<li><a href="#org92d9d2c">4. DOM and component mounting</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://docs.google.com/presentation/d/1n5RlpgBtXQ1OHvutx9TRLotWizyg2BPKv_780DD4-90/edit#slide=id.gb2bbafee77_1_66">web.lab lectures</a>.
</p>
<div id="outline-container-org847bf81" class="outline-2">
<h2 id="org847bf81"><span class="section-number-2">1.</span> What is a React hook</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>Special functions to access parts of the component lifestyle.</li>
<li>e.g., <code>useState</code></li>
</ul>
</div>
<div id="outline-container-orga170863" class="outline-3">
<h3 id="orga170863"><span class="section-number-3">1.1.</span> <code>useState</code> is not enough</h3>
<div class="outline-text-3" id="text-1-1">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #51afef;">const</span> [<span style="color: #dcaeea;">persons</span>, <span style="color: #dcaeea;">setPersons</span>] = useState([]);
<span class="linenr">2: </span>
<span class="linenr">3: </span>testingStuff = () =&gt; {
<span class="linenr">4: </span>    <span style="color: #5B6268;">/* </span><span style="color: #5B6268;">assume persons is empty before</span><span style="color: #5B6268;"> */</span>
<span class="linenr">5: </span>    setPersons([...persons, <span style="color: #98be65;">"me"</span>]);
<span class="linenr">6: </span>}
<span class="linenr">7: </span>console.log(persons);
</pre>
</div>

<ul class="org-ul">
<li>The output of <code class="src src-js">console.log</code> is <code>[]</code> instead of <code>["me"]</code> because setting a state is <b><b>async</b></b>!</li>
<li>To do something immediately after a state is changed, use <code>useEffect</code> hook!</li>
</ul>
</div>
</div>
<div id="outline-container-orgf8b0571" class="outline-3">
<h3 id="orgf8b0571"><span class="section-number-3">1.2.</span> <code>useEffect</code> runs after specific variable change</h3>
<div class="outline-text-3" id="text-1-2">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span>useEffect(() =&gt; {
<span class="linenr">2: </span>    console.log(persons);
<span class="linenr">3: </span>}, [persons]);
</pre>
</div>

<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span>useEffect(() =&gt; {
<span class="linenr">2: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">do something, e.g., interact with an external service</span><span style="color: #5B6268;"> */</span>
<span class="linenr">3: </span>
<span class="linenr">4: </span><span style="color: #51afef;">return</span> () =&gt; {
<span class="linenr">5: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">cleanup function on dismount, e.g., disconnect from external service</span><span style="color: #5B6268;"> */</span>
<span class="linenr">6: </span>}
<span class="linenr">7: </span>}, [<span style="color: #5B6268;">/*</span><span style="color: #5B6268;">dependencies</span><span style="color: #5B6268;"> */</span>])
</pre>
</div>

<ul class="org-ul">
<li><code class="src src-js">useEffect(myFunction, [var1, var2])</code> calls <code>myFunction</code> everytime when <code>var1</code> or <code>var2</code> changes</li>
<li><code class="src src-js">useEffect(myFunction, []])</code> calls only once when the component is rendered for the first time (on mount)</li>
<li><code class="src src-js">useEffect(myFunction)</code> calls at every render</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org1fec729" class="outline-2">
<h2 id="org1fec729"><span class="section-number-2">2.</span> React hook patterns</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-org14c62ca" class="outline-3">
<h3 id="org14c62ca"><span class="section-number-3">2.1.</span> Fetch and send data</h3>
<div class="outline-text-3" id="text-2-1">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">fetch data on mount</span><span style="color: #5B6268;"> */</span>
<span class="linenr">2: </span>useEffect(() =&gt; {
<span class="linenr">3: </span>    get(<span style="color: #98be65;">"/api/packages"</span>).then((packageList) =&gt; {
<span class="linenr">4: </span>        setPackages(packageList);
<span class="linenr">5: </span>    });
<span class="linenr">6: </span>}, []);
</pre>
</div>

<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">send data then toggle admin state</span><span style="color: #5B6268;"> */</span>
<span class="linenr">2: </span><span style="color: #51afef;">const</span> <span style="color: #dcaeea;">handleToggleAdmin</span> = () =&gt; {
<span class="linenr">3: </span>    <span style="color: #5B6268;">// </span><span style="color: #5B6268;">.then(), do something once the promise is fulfilled</span>
<span class="linenr">4: </span>    post(<span style="color: #98be65;">"/api/user/admin"</span>, { admin: !admin }).then(() =&gt; {
<span class="linenr">5: </span>        setAdmin(!admin);
<span class="linenr">6: </span>    });
<span class="linenr">7: </span>};
<span class="linenr">8: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">&lt;Button onClick={handleToggleAdmin}</span><span style="color: #5B6268;"> */</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org662280e" class="outline-3">
<h3 id="org662280e"><span class="section-number-3">2.2.</span> Conditional rendering</h3>
<div class="outline-text-3" id="text-2-2">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">JSX is a way of writing HTML in js</span>
<span class="linenr">2: </span><span style="color: #51afef;">let</span> <span style="color: #dcaeea;">content</span> = loading ? &lt;p&gt;Loading...&lt;/p&gt; : &lt;p&gt;Loaded&lt;/p&gt;;
<span class="linenr">3: </span><span style="color: #51afef;">return</span> (
<span class="linenr">4: </span>    &lt;div&gt;
<span class="linenr">5: </span>        &lt;h1&gt;Title&lt;/h1&gt;
<span class="linenr">6: </span>        {content}
<span class="linenr">7: </span>    &lt;/div&gt;
<span class="linenr">8: </span>);
</pre>
</div>
</div>
</div>
<div id="outline-container-org173ac44" class="outline-3">
<h3 id="org173ac44"><span class="section-number-3">2.3.</span> Render an array of Data</h3>
<div class="outline-text-3" id="text-2-3">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #51afef;">const</span> <span style="color: #dcaeea;">data</span> = [
<span class="linenr">2: </span>    { id: <span style="color: #da8548; font-weight: bold;">0</span>, text: <span style="color: #98be65;">"Text 1"</span> },
<span class="linenr">3: </span>    { id: <span style="color: #da8548; font-weight: bold;">1</span>, text: <span style="color: #98be65;">"Text 2"</span> },
<span class="linenr">4: </span>];
<span class="linenr">5: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">render a component for each data item</span>
<span class="linenr">6: </span><span style="color: #51afef;">return</span> data.map((item) =&gt; (
<span class="linenr">7: </span>    &lt;ItemComponent key={item.id}&gt;{item.text}&lt;/ItemComponent&gt;
<span class="linenr">8: </span>));
</pre>
</div>
<ul class="org-ul">
<li><code>key</code> is a special prop in React; it is used identify which item has changed efficiently</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgf88bca8" class="outline-2">
<h2 id="orgf88bca8"><span class="section-number-2">3.</span> Example: Stopwatch</h2>
<div class="outline-text-2" id="text-3">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr"> 1: </span><span style="color: #51afef;">const</span> <span style="color: #dcaeea;">Stopwatch</span> = () =&gt; {
<span class="linenr"> 2: </span>    <span style="color: #51afef;">const</span> [<span style="color: #dcaeea;">time</span>, <span style="color: #dcaeea;">setTimer</span>] = useState(<span style="color: #da8548; font-weight: bold;">0</span>);
<span class="linenr"> 3: </span>
<span class="linenr"> 4: </span>    useEffect(() =&gt; {
<span class="linenr"> 5: </span>        <span style="color: #51afef;">const</span> <span style="color: #dcaeea;">timer</span> = setInterval(() =&gt; {
<span class="linenr"> 6: </span>            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">setTimer accepts either a new state value,</span>
<span class="linenr"> 7: </span>            <span style="color: #5B6268;">// </span><span style="color: #5B6268;">or a function that takes the previous state (oldTime) as an argument and returns the new state</span>
<span class="linenr"> 8: </span>            setTime((oldTime) =&gt; oldTime + <span style="color: #da8548; font-weight: bold;">1</span>);}, <span style="color: #da8548; font-weight: bold;">1000</span>);
<span class="linenr"> 9: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if not properly cleanup after unmounting</span>
<span class="linenr">10: </span>        <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the timer will continue to run even the state no longer exists</span>
<span class="linenr">11: </span>        <span style="color: #51afef;">return</span> () =&gt; clearInterval(timer);
<span class="linenr">12: </span>    }, []);
<span class="linenr">13: </span>    <span style="color: #51afef;">return</span> &lt;&gt;TIme: {time}&lt;/&gt;;
<span class="linenr">14: </span>};
</pre>
</div>
</div>
</div>
<div id="outline-container-org92d9d2c" class="outline-2">
<h2 id="org92d9d2c"><span class="section-number-2">4.</span> DOM and component mounting</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>DOM (Document Object Model): a programming interface for web documents; represents the structure of a document, e.g., HTML, as a tree of objects, where each object corresponds to a part of the document; it dynamically updates the document contents
<ul class="org-ul">
<li>React is a framework that manipulates DOM</li>
</ul></li>
<li>A React component is unmounted when:
<ul class="org-ul">
<li>conditional rendering</li>
<li>routing; navigating from one route to another</li>
<li>its parent component is unmounted</li>
</ul></li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-web.html">web</a> <a href="https://chenyo.me/tag-react.html">react</a> <a href="https://chenyo.me/tag-mit.html">mit</a> </div>]]></description>
  <category><![CDATA[study]]></category>
  <category><![CDATA[web]]></category>
  <category><![CDATA[react]]></category>
  <category><![CDATA[mit]]></category>
  <link>https://chenyo.me/2024-06-23-weblab-notes:-react-hooks.html</link>
  <guid>https://chenyo.me/2024-06-23-weblab-notes:-react-hooks.html</guid>
  <pubDate>Sun, 23 Jun 2024 18:21:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Hello world]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org5d25491">1. Hallo!</a></li>
</ul>
</div>
</nav>
<div id="outline-container-org5d25491" class="outline-2">
<h2 id="org5d25491"><span class="section-number-2">1.</span> Hallo!</h2>
<div class="outline-text-2" id="text-1">
<p>
This is the first blog with org-static-blog!
</p>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-personal.html">personal</a> </div>]]></description>
  <category><![CDATA[personal]]></category>
  <link>https://chenyo.me/2024-06-23-hello-world.html</link>
  <guid>https://chenyo.me/2024-06-23-hello-world.html</guid>
  <pubDate>Sun, 23 Jun 2024 18:04:00 +0200</pubDate>
</item>
</channel>
</rss>
