<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>mightsleep</title>
    <subtitle>Bit tricks, renderers, and other things that are faster than they look.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://panacan.xyz/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://panacan.xyz"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-10-25T00:00:00+00:00</updated>
    <id>https://panacan.xyz/atom.xml</id>
    <entry xml:lang="en">
        <title>Two dimensions, one disk</title>
        <published>2026-10-25T00:00:00+00:00</published>
        <updated>2026-10-25T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://panacan.xyz/blog/curves-primer/"/>
        <id>https://panacan.xyz/blog/curves-primer/</id>
        
        <content type="html" xml:base="https://panacan.xyz/blog/curves-primer/">&lt;p&gt;This series started as a side question. I had just written an
&lt;a href=&quot;https://panacan.xyz/blog/offset/&quot;&gt;allocator for GPU memory&lt;/a&gt;, which packs buffers into
one long line, and wondered why the line had to be one-dimensional. Two
dimensions led to Morton order, Morton picked up a few ideas from image
recognition, and soon I was solving Morton with bit tricks instead of
packing anything. The packing can wait.&lt;/p&gt;
&lt;p&gt;Take a table with two columns you filter on: a position on a map, or a
time and a sensor id. The question is always the same: give me everything
inside this rectangle. Memory, a file and an index all have one
dimension, so before anything can be stored, someone has to decide in
which order the cells of a two-dimensional grid go into a line. This post
is about that decision. It opens a short series; the posts after it
compute the orders fast and measure what they cost.&lt;/p&gt;
&lt;h2 id=&quot;rows&quot;&gt;Rows&lt;/h2&gt;
&lt;p&gt;The obvious order is the one every array uses, row after row. On an
8 × 8 grid, cell (x, y) gets number y · 8 + x.&lt;/p&gt;
&lt;figure class=&quot;grids&quot;&gt;
&lt;svg class=&quot;cgrid faint&quot; viewBox=&quot;0 0 260 260&quot; role=&quot;img&quot; aria-label=&quot;An 8 by 8 grid numbered row by row, 0 to 63, with a 4 by 4 square from cell 18 to cell 45 marked&quot; style=&quot;--cell:32&quot;&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;2&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;2&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;2&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;2&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;2&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;2&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;2&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;2&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;34&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;34&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;34&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;34&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;34&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;34&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;34&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;34&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;66&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;66&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;66&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;66&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;66&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;66&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;66&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;66&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;98&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;98&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;98&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;98&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;98&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;98&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;98&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;98&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;130&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;130&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;130&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;130&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;130&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;130&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;130&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;130&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;162&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;162&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;162&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;162&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;162&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;162&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;162&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;162&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;194&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;194&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;194&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;194&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;194&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;194&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;194&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;194&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;226&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;226&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;226&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;226&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;226&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;226&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;226&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;226&quot; width=&quot;32&quot; height=&quot;32&quot;/&gt;&lt;rect class=&quot;ql&quot; x=&quot;66&quot; y=&quot;66&quot; width=&quot;128&quot; height=&quot;128&quot;/&gt;&lt;polyline class=&quot;cv&quot; points=&quot;18,18 50,18 82,18 114,18 146,18 178,18 210,18 242,18 18,50 50,50 82,50 114,50 146,50 178,50 210,50 242,50 18,82 50,82 82,82 114,82 146,82 178,82 210,82 242,82 18,114 50,114 82,114 114,114 146,114 178,114 210,114 242,114 18,146 50,146 82,146 114,146 146,146 178,146 210,146 242,146 18,178 50,178 82,178 114,178 146,178 178,178 210,178 242,178 18,210 50,210 82,210 114,210 146,210 178,210 210,210 242,210 18,242 50,242 82,242 114,242 146,242 178,242 210,242 242,242&quot;/&gt;&lt;text x=&quot;18&quot; y=&quot;18&quot;&gt;0&lt;/text&gt;&lt;text x=&quot;50&quot; y=&quot;18&quot;&gt;1&lt;/text&gt;&lt;text x=&quot;82&quot; y=&quot;18&quot;&gt;2&lt;/text&gt;&lt;text x=&quot;114&quot; y=&quot;18&quot;&gt;3&lt;/text&gt;&lt;text x=&quot;146&quot; y=&quot;18&quot;&gt;4&lt;/text&gt;&lt;text x=&quot;178&quot; y=&quot;18&quot;&gt;5&lt;/text&gt;&lt;text x=&quot;210&quot; y=&quot;18&quot;&gt;6&lt;/text&gt;&lt;text x=&quot;242&quot; y=&quot;18&quot;&gt;7&lt;/text&gt;&lt;text x=&quot;18&quot; y=&quot;50&quot;&gt;8&lt;/text&gt;&lt;text x=&quot;50&quot; y=&quot;50&quot;&gt;9&lt;/text&gt;&lt;text x=&quot;82&quot; y=&quot;50&quot;&gt;10&lt;/text&gt;&lt;text x=&quot;114&quot; y=&quot;50&quot;&gt;11&lt;/text&gt;&lt;text x=&quot;146&quot; y=&quot;50&quot;&gt;12&lt;/text&gt;&lt;text x=&quot;178&quot; y=&quot;50&quot;&gt;13&lt;/text&gt;&lt;text x=&quot;210&quot; y=&quot;50&quot;&gt;14&lt;/text&gt;&lt;text x=&quot;242&quot; y=&quot;50&quot;&gt;15&lt;/text&gt;&lt;text x=&quot;18&quot; y=&quot;82&quot;&gt;16&lt;/text&gt;&lt;text x=&quot;50&quot; y=&quot;82&quot;&gt;17&lt;/text&gt;&lt;text x=&quot;82&quot; y=&quot;82&quot;&gt;18&lt;/text&gt;&lt;text x=&quot;114&quot; y=&quot;82&quot;&gt;19&lt;/text&gt;&lt;text x=&quot;146&quot; y=&quot;82&quot;&gt;20&lt;/text&gt;&lt;text x=&quot;178&quot; y=&quot;82&quot;&gt;21&lt;/text&gt;&lt;text x=&quot;210&quot; y=&quot;82&quot;&gt;22&lt;/text&gt;&lt;text x=&quot;242&quot; y=&quot;82&quot;&gt;23&lt;/text&gt;&lt;text x=&quot;18&quot; y=&quot;114&quot;&gt;24&lt;/text&gt;&lt;text x=&quot;50&quot; y=&quot;114&quot;&gt;25&lt;/text&gt;&lt;text x=&quot;82&quot; y=&quot;114&quot;&gt;26&lt;/text&gt;&lt;text x=&quot;114&quot; y=&quot;114&quot;&gt;27&lt;/text&gt;&lt;text x=&quot;146&quot; y=&quot;114&quot;&gt;28&lt;/text&gt;&lt;text x=&quot;178&quot; y=&quot;114&quot;&gt;29&lt;/text&gt;&lt;text x=&quot;210&quot; y=&quot;114&quot;&gt;30&lt;/text&gt;&lt;text x=&quot;242&quot; y=&quot;114&quot;&gt;31&lt;/text&gt;&lt;text x=&quot;18&quot; y=&quot;146&quot;&gt;32&lt;/text&gt;&lt;text x=&quot;50&quot; y=&quot;146&quot;&gt;33&lt;/text&gt;&lt;text x=&quot;82&quot; y=&quot;146&quot;&gt;34&lt;/text&gt;&lt;text x=&quot;114&quot; y=&quot;146&quot;&gt;35&lt;/text&gt;&lt;text x=&quot;146&quot; y=&quot;146&quot;&gt;36&lt;/text&gt;&lt;text x=&quot;178&quot; y=&quot;146&quot;&gt;37&lt;/text&gt;&lt;text x=&quot;210&quot; y=&quot;146&quot;&gt;38&lt;/text&gt;&lt;text x=&quot;242&quot; y=&quot;146&quot;&gt;39&lt;/text&gt;&lt;text x=&quot;18&quot; y=&quot;178&quot;&gt;40&lt;/text&gt;&lt;text x=&quot;50&quot; y=&quot;178&quot;&gt;41&lt;/text&gt;&lt;text x=&quot;82&quot; y=&quot;178&quot;&gt;42&lt;/text&gt;&lt;text x=&quot;114&quot; y=&quot;178&quot;&gt;43&lt;/text&gt;&lt;text x=&quot;146&quot; y=&quot;178&quot;&gt;44&lt;/text&gt;&lt;text x=&quot;178&quot; y=&quot;178&quot;&gt;45&lt;/text&gt;&lt;text x=&quot;210&quot; y=&quot;178&quot;&gt;46&lt;/text&gt;&lt;text x=&quot;242&quot; y=&quot;178&quot;&gt;47&lt;/text&gt;&lt;text x=&quot;18&quot; y=&quot;210&quot;&gt;48&lt;/text&gt;&lt;text x=&quot;50&quot; y=&quot;210&quot;&gt;49&lt;/text&gt;&lt;text x=&quot;82&quot; y=&quot;210&quot;&gt;50&lt;/text&gt;&lt;text x=&quot;114&quot; y=&quot;210&quot;&gt;51&lt;/text&gt;&lt;text x=&quot;146&quot; y=&quot;210&quot;&gt;52&lt;/text&gt;&lt;text x=&quot;178&quot; y=&quot;210&quot;&gt;53&lt;/text&gt;&lt;text x=&quot;210&quot; y=&quot;210&quot;&gt;54&lt;/text&gt;&lt;text x=&quot;242&quot; y=&quot;210&quot;&gt;55&lt;/text&gt;&lt;text x=&quot;18&quot; y=&quot;242&quot;&gt;56&lt;/text&gt;&lt;text x=&quot;50&quot; y=&quot;242&quot;&gt;57&lt;/text&gt;&lt;text x=&quot;82&quot; y=&quot;242&quot;&gt;58&lt;/text&gt;&lt;text x=&quot;114&quot; y=&quot;242&quot;&gt;59&lt;/text&gt;&lt;text x=&quot;146&quot; y=&quot;242&quot;&gt;60&lt;/text&gt;&lt;text x=&quot;178&quot; y=&quot;242&quot;&gt;61&lt;/text&gt;&lt;text x=&quot;210&quot; y=&quot;242&quot;&gt;62&lt;/text&gt;&lt;text x=&quot;242&quot; y=&quot;242&quot;&gt;63&lt;/text&gt;&lt;/svg&gt;
&lt;figcaption&gt;Row by row, with a 4 × 4 query marked. The line follows the numbers; it jumps back at the end of every row.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The marked square holds numbers 18 to 21, 26 to 29, 34 to 37 and 42 to
45: four contiguous stretches of the index. I will call such a stretch a
run. Each run means jumping to a new place in the index and reading from
there, so a run is roughly a seek. In this order a rectangle costs one
run per row it covers, whatever its width, so a query one column wide
and a hundred tall costs a hundred.&lt;/p&gt;
&lt;p&gt;That is only half of the cost, though. A disk hands out pages, blocks of
consecutive keys, and a database reads them whole. In rows, a page is a
strip, a piece of one row. A square query
cuts through as many strips as it has rows and uses only the few cells
of each strip that fall inside it.&lt;/p&gt;
&lt;h2 id=&quot;a-curve&quot;&gt;A curve&lt;/h2&gt;
&lt;p&gt;A space-filling curve is just another order: a path through the grid
that visits every cell once, chosen so that cells close in the order are
also close on the grid. The name sounds like geometry, but all that
matters here is the numbering.&lt;/p&gt;
&lt;h2 id=&quot;z-order&quot;&gt;Z-order&lt;/h2&gt;
&lt;p&gt;The cheapest such order interleaves the bits of the two coordinates like
a zipper: the lowest bit of x, then the lowest bit of y, then the next
bit of x, and so on. The cell x = 2, y = 1 is x = 10 and y = 01 in
binary; interleaved, that is 0110, so the cell gets number 6. This is
Z-order, also called Morton order after G. M. Morton, who described it
for a map database at IBM in 1966.&lt;/p&gt;
&lt;figure class=&quot;grids&quot;&gt;
&lt;svg class=&quot;cgrid&quot; viewBox=&quot;0 0 212 212&quot; role=&quot;img&quot; aria-label=&quot;A 4 by 4 grid in Z-order: each 2 by 2 block numbered as a small Z, the blocks themselves in a Z&quot; style=&quot;--cell:52&quot;&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;2&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;54&quot; y=&quot;2&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;106&quot; y=&quot;2&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;158&quot; y=&quot;2&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;54&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;54&quot; y=&quot;54&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;106&quot; y=&quot;54&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;158&quot; y=&quot;54&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;106&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;54&quot; y=&quot;106&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;106&quot; y=&quot;106&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;158&quot; y=&quot;106&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;158&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;54&quot; y=&quot;158&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;106&quot; y=&quot;158&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;158&quot; y=&quot;158&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;polyline class=&quot;cv&quot; points=&quot;28,28 80,28 28,80 80,80 132,28 184,28 132,80 184,80 28,132 80,132 28,184 80,184 132,132 184,132 132,184 184,184&quot;/&gt;&lt;text x=&quot;28&quot; y=&quot;28&quot;&gt;0&lt;/text&gt;&lt;text x=&quot;80&quot; y=&quot;28&quot;&gt;1&lt;/text&gt;&lt;text x=&quot;132&quot; y=&quot;28&quot;&gt;4&lt;/text&gt;&lt;text x=&quot;184&quot; y=&quot;28&quot;&gt;5&lt;/text&gt;&lt;text x=&quot;28&quot; y=&quot;80&quot;&gt;2&lt;/text&gt;&lt;text x=&quot;80&quot; y=&quot;80&quot;&gt;3&lt;/text&gt;&lt;text x=&quot;132&quot; y=&quot;80&quot;&gt;6&lt;/text&gt;&lt;text x=&quot;184&quot; y=&quot;80&quot;&gt;7&lt;/text&gt;&lt;text x=&quot;28&quot; y=&quot;132&quot;&gt;8&lt;/text&gt;&lt;text x=&quot;80&quot; y=&quot;132&quot;&gt;9&lt;/text&gt;&lt;text x=&quot;132&quot; y=&quot;132&quot;&gt;12&lt;/text&gt;&lt;text x=&quot;184&quot; y=&quot;132&quot;&gt;13&lt;/text&gt;&lt;text x=&quot;28&quot; y=&quot;184&quot;&gt;10&lt;/text&gt;&lt;text x=&quot;80&quot; y=&quot;184&quot;&gt;11&lt;/text&gt;&lt;text x=&quot;132&quot; y=&quot;184&quot;&gt;14&lt;/text&gt;&lt;text x=&quot;184&quot; y=&quot;184&quot;&gt;15&lt;/text&gt;&lt;/svg&gt;
&lt;figcaption&gt;Z-order on a 4 × 4 grid. Every 2 × 2 block is a small Z, and the four blocks make a large one.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Every 2 × 2 block gets four consecutive numbers, every aligned 4 × 4
block sixteen, and so on up. That is the whole point: an aligned square
of any size is one contiguous stretch of the index. The price is the
jumps between blocks, the diagonal strokes of the Z, and some of them
are long.&lt;/p&gt;
&lt;h2 id=&quot;hilbert&quot;&gt;Hilbert&lt;/h2&gt;
&lt;p&gt;David Hilbert&#39;s curve, from 1891, is built from the same blocks, but
each block is turned so that the path leaves it right next to where the
next block starts. It never jumps: consecutive numbers are always
neighbouring cells.&lt;/p&gt;
&lt;figure class=&quot;grids&quot;&gt;
&lt;svg class=&quot;cgrid&quot; viewBox=&quot;0 0 212 212&quot; role=&quot;img&quot; aria-label=&quot;A 4 by 4 grid along Hilbert&#39;s curve: consecutive numbers are always neighbouring cells&quot; style=&quot;--cell:52&quot;&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;2&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;54&quot; y=&quot;2&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;106&quot; y=&quot;2&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;158&quot; y=&quot;2&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;54&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;54&quot; y=&quot;54&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;106&quot; y=&quot;54&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;158&quot; y=&quot;54&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;106&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;54&quot; y=&quot;106&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;106&quot; y=&quot;106&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;158&quot; y=&quot;106&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;158&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;54&quot; y=&quot;158&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;106&quot; y=&quot;158&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;158&quot; y=&quot;158&quot; width=&quot;52&quot; height=&quot;52&quot;/&gt;&lt;polyline class=&quot;cv&quot; points=&quot;28,28 80,28 80,80 28,80 28,132 28,184 80,184 80,132 132,132 132,184 184,184 184,132 184,80 132,80 132,28 184,28&quot;/&gt;&lt;text x=&quot;28&quot; y=&quot;28&quot;&gt;0&lt;/text&gt;&lt;text x=&quot;80&quot; y=&quot;28&quot;&gt;1&lt;/text&gt;&lt;text x=&quot;132&quot; y=&quot;28&quot;&gt;14&lt;/text&gt;&lt;text x=&quot;184&quot; y=&quot;28&quot;&gt;15&lt;/text&gt;&lt;text x=&quot;28&quot; y=&quot;80&quot;&gt;3&lt;/text&gt;&lt;text x=&quot;80&quot; y=&quot;80&quot;&gt;2&lt;/text&gt;&lt;text x=&quot;132&quot; y=&quot;80&quot;&gt;13&lt;/text&gt;&lt;text x=&quot;184&quot; y=&quot;80&quot;&gt;12&lt;/text&gt;&lt;text x=&quot;28&quot; y=&quot;132&quot;&gt;4&lt;/text&gt;&lt;text x=&quot;80&quot; y=&quot;132&quot;&gt;7&lt;/text&gt;&lt;text x=&quot;132&quot; y=&quot;132&quot;&gt;8&lt;/text&gt;&lt;text x=&quot;184&quot; y=&quot;132&quot;&gt;11&lt;/text&gt;&lt;text x=&quot;28&quot; y=&quot;184&quot;&gt;5&lt;/text&gt;&lt;text x=&quot;80&quot; y=&quot;184&quot;&gt;6&lt;/text&gt;&lt;text x=&quot;132&quot; y=&quot;184&quot;&gt;9&lt;/text&gt;&lt;text x=&quot;184&quot; y=&quot;184&quot;&gt;10&lt;/text&gt;&lt;/svg&gt;
&lt;figcaption&gt;Hilbert&#39;s curve on the same grid. Each quarter is a turned copy of the 2 × 2 pattern, so the path never lifts.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It is also harder to compute. Z-order is a bit shuffle, while Hilbert
has to know at every level how the block it is in is turned, and that is
a chain of decisions, each depending on the last. Making that cheap is
the subject of the next post.&lt;/p&gt;
&lt;h2 id=&quot;what-a-square-costs&quot;&gt;What a square costs&lt;/h2&gt;
&lt;p&gt;Here are both numbers for a setup that looks more like a database than a toy: a
256 × 256 grid, pages of 256 cells, and a 16 × 16 square query,
averaged over all 58 081 positions the square can take.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;order&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;runs&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;pages read&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;cells read for 256 wanted&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;rows&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;16.0&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;16.0&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;4096&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Z-order&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;30.0&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;3.7&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;957&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Hilbert&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;15.9&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;3.7&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;957&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Pages are where the curves win, and both win by the same margin. On a
curve a page is a block close to a square, because an aligned square of
the grid is a contiguous stretch of keys, and a square query cuts
through only a few such blocks. Reading a quarter of the data
is a real saving.&lt;/p&gt;
&lt;figure class=&quot;grids&quot;&gt;
&lt;svg class=&quot;cgrid&quot; viewBox=&quot;0 0 260 260&quot; role=&quot;img&quot; aria-label=&quot;A 16 by 16 grid in rows, each page a whole row; an 8 by 8 query touches eight pages&quot; style=&quot;--cell:16&quot;&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;2&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;18&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;34&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;50&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;194&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;210&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;226&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;242&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;2&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;18&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;34&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;50&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;194&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;210&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;226&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;242&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;2&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;18&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;34&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;50&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;194&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;210&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;226&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;242&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;2&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;18&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;34&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;50&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;194&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;210&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;226&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;242&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;2&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;18&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;34&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;50&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;194&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;210&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;226&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;242&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;2&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;18&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;34&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;50&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;194&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;210&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;226&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;242&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;2&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;18&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;34&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;50&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;194&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;210&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;226&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;242&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;2&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;18&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;34&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;50&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;194&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;210&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;226&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;rd&quot; x=&quot;242&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;path class=&quot;pg&quot; d=&quot;M2 18h16M18 18h16M34 18h16M50 18h16M66 18h16M82 18h16M98 18h16M114 18h16M130 18h16M146 18h16M162 18h16M178 18h16M194 18h16M210 18h16M226 18h16M242 18h16M2 34h16M18 34h16M34 34h16M50 34h16M66 34h16M82 34h16M98 34h16M114 34h16M130 34h16M146 34h16M162 34h16M178 34h16M194 34h16M210 34h16M226 34h16M242 34h16M2 50h16M18 50h16M34 50h16M50 50h16M66 50h16M82 50h16M98 50h16M114 50h16M130 50h16M146 50h16M162 50h16M178 50h16M194 50h16M210 50h16M226 50h16M242 50h16M2 66h16M18 66h16M34 66h16M50 66h16M66 66h16M82 66h16M98 66h16M114 66h16M130 66h16M146 66h16M162 66h16M178 66h16M194 66h16M210 66h16M226 66h16M242 66h16M2 82h16M18 82h16M34 82h16M50 82h16M66 82h16M82 82h16M98 82h16M114 82h16M130 82h16M146 82h16M162 82h16M178 82h16M194 82h16M210 82h16M226 82h16M242 82h16M2 98h16M18 98h16M34 98h16M50 98h16M66 98h16M82 98h16M98 98h16M114 98h16M130 98h16M146 98h16M162 98h16M178 98h16M194 98h16M210 98h16M226 98h16M242 98h16M2 114h16M18 114h16M34 114h16M50 114h16M66 114h16M82 114h16M98 114h16M114 114h16M130 114h16M146 114h16M162 114h16M178 114h16M194 114h16M210 114h16M226 114h16M242 114h16M2 130h16M18 130h16M34 130h16M50 130h16M66 130h16M82 130h16M98 130h16M114 130h16M130 130h16M146 130h16M162 130h16M178 130h16M194 130h16M210 130h16M226 130h16M242 130h16M2 146h16M18 146h16M34 146h16M50 146h16M66 146h16M82 146h16M98 146h16M114 146h16M130 146h16M146 146h16M162 146h16M178 146h16M194 146h16M210 146h16M226 146h16M242 146h16M2 162h16M18 162h16M34 162h16M50 162h16M66 162h16M82 162h16M98 162h16M114 162h16M130 162h16M146 162h16M162 162h16M178 162h16M194 162h16M210 162h16M226 162h16M242 162h16M2 178h16M18 178h16M34 178h16M50 178h16M66 178h16M82 178h16M98 178h16M114 178h16M130 178h16M146 178h16M162 178h16M178 178h16M194 178h16M210 178h16M226 178h16M242 178h16M2 194h16M18 194h16M34 194h16M50 194h16M66 194h16M82 194h16M98 194h16M114 194h16M130 194h16M146 194h16M162 194h16M178 194h16M194 194h16M210 194h16M226 194h16M242 194h16M2 210h16M18 210h16M34 210h16M50 210h16M66 210h16M82 210h16M98 210h16M114 210h16M130 210h16M146 210h16M162 210h16M178 210h16M194 210h16M210 210h16M226 210h16M242 210h16M2 226h16M18 226h16M34 226h16M50 226h16M66 226h16M82 226h16M98 226h16M114 226h16M130 226h16M146 226h16M162 226h16M178 226h16M194 226h16M210 226h16M226 226h16M242 226h16M2 242h16M18 242h16M34 242h16M50 242h16M66 242h16M82 242h16M98 242h16M114 242h16M130 242h16M146 242h16M162 242h16M178 242h16M194 242h16M210 242h16M226 242h16M242 242h16&quot;/&gt;&lt;rect class=&quot;ql&quot; x=&quot;66&quot; y=&quot;66&quot; width=&quot;128&quot; height=&quot;128&quot;/&gt;&lt;/svg&gt;
&lt;svg class=&quot;cgrid&quot; viewBox=&quot;0 0 260 260&quot; role=&quot;img&quot; aria-label=&quot;The same grid on Hilbert&#39;s curve, each page a 4 by 4 block; the same query touches four pages&quot; style=&quot;--cell:16&quot;&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;2&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;18&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;34&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;50&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;66&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;82&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;98&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;114&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;130&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;146&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;162&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;66&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;82&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;98&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;114&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;130&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;146&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;162&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;q&quot; x=&quot;178&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;178&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;194&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;210&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;226&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;2&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;18&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;34&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;50&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;66&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;82&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;98&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;114&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;130&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;146&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;162&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;178&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;194&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;210&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;226&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;rect class=&quot;c&quot; x=&quot;242&quot; y=&quot;242&quot; width=&quot;16&quot; height=&quot;16&quot;/&gt;&lt;path class=&quot;pg&quot; d=&quot;M66 2v16M130 2v16M194 2v16M66 18v16M130 18v16M194 18v16M66 34v16M130 34v16M194 34v16M2 66h16M18 66h16M34 66h16M66 50v16M50 66h16M66 66h16M82 66h16M98 66h16M130 50v16M114 66h16M130 66h16M146 66h16M162 66h16M194 50v16M178 66h16M194 66h16M210 66h16M226 66h16M242 66h16M66 66v16M130 66v16M194 66v16M66 82v16M130 82v16M194 82v16M66 98v16M130 98v16M194 98v16M2 130h16M18 130h16M34 130h16M66 114v16M50 130h16M66 130h16M82 130h16M98 130h16M130 114v16M114 130h16M130 130h16M146 130h16M162 130h16M194 114v16M178 130h16M194 130h16M210 130h16M226 130h16M242 130h16M66 130v16M130 130v16M194 130v16M66 146v16M130 146v16M194 146v16M66 162v16M130 162v16M194 162v16M2 194h16M18 194h16M34 194h16M66 178v16M50 194h16M66 194h16M82 194h16M98 194h16M130 178v16M114 194h16M130 194h16M146 194h16M162 194h16M194 178v16M178 194h16M194 194h16M210 194h16M226 194h16M242 194h16M66 194v16M130 194v16M194 194v16M66 210v16M130 210v16M194 210v16M66 226v16M130 226v16M194 226v16M66 242v16M130 242v16M194 242v16&quot;/&gt;&lt;rect class=&quot;ql&quot; x=&quot;66&quot; y=&quot;66&quot; width=&quot;128&quot; height=&quot;128&quot;/&gt;&lt;/svg&gt;
&lt;figcaption&gt;Pages of 16 cells, outlined: whole rows on the left, 4 × 4 blocks on Hilbert&#39;s curve on the right (Z-order&#39;s pages are the same blocks). The 8 × 8 query touches the shaded pages, eight against four. It is aligned to the blocks here, which flatters the curve; the table averages every position.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Runs are a different story. Hilbert only ties with plain rows, and
Z-order needs almost twice as many: every jump between blocks starts a
new run. For a square, a curve does not mean fewer seeks.
Whether runs or pages decide what a query really costs, and whether
something between Z-order and Hilbert does better, is what the rest of
this series measures.&lt;/p&gt;
&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;/h2&gt;
&lt;p&gt;Below are three orders: Z-order, Hilbert, and one between them that gets
a post of its own. Drag a rectangle across the grid; the curve outside
it dims and the runs inside stay lit, so you can count them.&lt;/p&gt;
&lt;figure class=&quot;demo&quot; data-demo=&quot;curves&quot;&gt;
  &lt;canvas aria-label=&quot;Morton (Z-order), Inside-out and Hilbert, computed in Rust compiled to WebAssembly. Drag to select a rectangle; the curve outside it dims, so the runs stay lit.&quot;&gt;&lt;/canvas&gt;
  &lt;noscript&gt;This demo needs JavaScript and WebAssembly.&lt;/noscript&gt;
  &lt;figcaption&gt;Morton (Z-order), Inside-out and Hilbert, computed in Rust compiled to WebAssembly. Drag to select a rectangle; the curve outside it dims, so the runs stay lit.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;script type=&quot;module&quot; src=&quot;https://panacan.xyz/demos/curves/main.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;where-this-lives&quot;&gt;Where this lives&lt;/h2&gt;
&lt;p&gt;Geohash is Z-order: the bits of latitude and longitude, interleaved and
written in base 32, so that nearby places share a prefix. Delta Lake can
sort the files of a table along it, &lt;code&gt;OPTIMIZE ... ZORDER BY&lt;/code&gt;, so that a
filter on either column skips most files. Google&#39;s S2 library numbers
cells on the faces of a cube along Hilbert&#39;s curve. And GPUs lay
textures out in tiles much like Z-order, because a triangle reads a
small square of texels, not a row.&lt;/p&gt;
&lt;h2 id=&quot;next&quot;&gt;Next&lt;/h2&gt;
&lt;p&gt;Three questions for the posts that follow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to compute Hilbert almost as cheaply as Z-order: one constant, and
sixty-four keys in one instruction.&lt;/li&gt;
&lt;li&gt;A curve between the two that takes away a third of Z-order&#39;s runs for
one shift and two XORs.&lt;/li&gt;
&lt;li&gt;Whether fewer runs make a cheaper query. They do, by less than the
count suggests.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;method&quot;&gt;Method&lt;/h2&gt;
&lt;p&gt;The numbers in the table come from a short script that numbers the grid
in each order, collects the keys of every 16 × 16 square, sorts them,
and counts runs as gaps between consecutive keys and pages as distinct
values of key / 256. The same script draws the figures, so the pictures
and the table cannot disagree. Hilbert is the classic construction, the
same one the demo uses.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Four lanes, one CAS</title>
        <published>2026-10-11T00:00:00+00:00</published>
        <updated>2026-10-11T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://panacan.xyz/blog/sni-router/"/>
        <id>https://panacan.xyz/blog/sni-router/</id>
        
        <content type="html" xml:base="https://panacan.xyz/blog/sni-router/">&lt;p&gt;The &lt;a href=&quot;https://panacan.xyz/blog/hello/&quot;&gt;first post&lt;/a&gt; mentioned a router I wrote over a
weekend: it sits on port 443, reads the server name from the TLS
handshake and passes the connection on without decrypting anything. A
week later it has grown IPv6, a plaintext port, the PROXY protocol,
metrics, and three kinds of connection limits, two of which are small
sketches packed four lanes to a 64-bit word. This post goes through all
of it, including the parts that broke.&lt;/p&gt;
&lt;h2 id=&quot;why-a-router-at-all&quot;&gt;Why a router at all&lt;/h2&gt;
&lt;p&gt;The server has one public address. Two things want its port 443: this
site, and a tunnel that exists because some networks I sit in let out
TCP on 80 and 443 and nothing else. Whoever connects to 443 says, in
the first message of the TLS handshake, which name it wants (Server Name
Indication, SNI). That is enough to tell the two apart before any
cryptography happens. Unknown names get the website, so somebody poking
at the tunnel&#39;s address sees an ordinary web server.&lt;/p&gt;
&lt;p&gt;The first post already told how this almost went wrong: the web server
behind the router picks a virtual host by the HTTP &lt;code&gt;Host&lt;/code&gt; header, not
by SNI, so &quot;public site&quot; in the handshake and &quot;internal dashboard&quot; in
the request would have served the dashboard to the internet. The public
site now runs on its own instance that knows nothing else.&lt;/p&gt;
&lt;h2 id=&quot;where-is-layer-4-anyway&quot;&gt;Where is layer 4, anyway&lt;/h2&gt;
&lt;p&gt;Load balancer vendors sort themselves into &quot;L4&quot; and &quot;L7&quot;, and this router
would be filed under L4. I have never found the layers much use, and not
only because the network ignores them.&lt;/p&gt;
&lt;p&gt;Start with the hardware. A network card does the physical layer and the
MAC, computes IP and TCP checksums, cuts TCP segments for the kernel
(TSO), hashes the addresses and ports to spread packets over its queues
(RSS), and newer ones encrypt TLS records. One chip, five layers.&lt;/p&gt;
&lt;p&gt;Then debugging, where problems refuse to stay on one floor. A DPI-evasion
tool on my laptop once split the ClientHello across TCP segments, which is
layer 4, and the TLS library on the other end refused the handshake,
which is layer 7. A firewall that drops ICMP, layer 3, makes a TCP
connection hang the first time it sends a large packet. Further down this
post a web server&#39;s HTTP redirect depends on a port number from a header
in front of the TCP stream. You switch between layers all the time, so
they do not even work as a filing system for bugs.&lt;/p&gt;
&lt;p&gt;And the stack is not seven floors. The tunnel behind this router carries
IP inside WireGuard inside WebSocket inside TLS inside TCP inside IP:
layer 3 inside layer 7. A fixed list of seven floors cannot say that.
What the wire carries is envelopes inside envelopes: a frame is a header
followed either by data or by another frame, as deep as anyone likes. A
&quot;layer&quot; is just how many envelopes deep you are.&lt;/p&gt;
&lt;p&gt;What the layers are good for is a contract about encapsulation: who owns
which header and who may change it. That contract is why IPv6 could slide
in under an unchanged TCP and why QUIC could be built on UDP. It is a
model for designing protocols, not for where the work happens or where
the failures hide. Even as a contract it gets broken: middleboxes read
into TCP, so new transport protocols like SCTP never made it through the
internet, and QUIC encrypts its own headers so that nobody can touch them.&lt;/p&gt;
&lt;p&gt;The model I actually use is &lt;em&gt;where on the wire is the packet, and what
happens to it there&lt;/em&gt;. A packet travels a chain of places, and each place
is a queue, a transformation and a decision:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;application buffer → socket send queue → qdisc → driver ring&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  → NIC (TSO, checksums) → wire → switches → … → NIC (RSS)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  → driver ring → NAPI/GRO → TCP receive queue → application&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The tools are built for this view: &lt;code&gt;ss&lt;/code&gt; for socket queues, &lt;code&gt;tc -s&lt;/code&gt; for
qdiscs, &lt;code&gt;ethtool -S&lt;/code&gt; for the card&#39;s rings and drops, &lt;code&gt;perf trace -e skb:kfree_skb&lt;/code&gt; for where the kernel threw a packet away and why. &quot;Where
are we losing time&quot; is a question about a queue, not about a layer.&lt;/p&gt;
&lt;p&gt;It needs one more axis: which bytes a place reads. A layer is then a
property of a decision, not of a box. RSS reads TCP ports from the bottom
of the stack. This router sits at the end of a TCP connection and decides
on bytes of TLS. It gets called &quot;L4&quot; for where it sits: it terminates TCP,
holds two sockets per connection, and never terminates TLS. Packet-level
balancers such as Maglev or Katran are &quot;L4&quot; too, and never terminate even
TCP: they only rewrite packets.&lt;/p&gt;
&lt;p&gt;Put together: a packet&#39;s trip is a chain of steps, and each step looks
at some bytes at the front (headers) or at the end (the Ethernet
checksum) and acts on them. The layered picture is the special case
where every step opens exactly one envelope. Almost nothing behaves that
way.&lt;/p&gt;
&lt;h2 id=&quot;reading-one-message&quot;&gt;Reading one message&lt;/h2&gt;
&lt;p&gt;The ClientHello is the only thing the router ever parses, and the only
code here that reads bytes chosen by strangers. TLS wraps it in records:
five bytes of header (type 22, version, length), then the payload. A
hello can be split across several records, and DPI-evasion tools split
it on purpose, sometimes in the middle of the name, to confuse
middleboxes exactly like this one.&lt;/p&gt;
&lt;p&gt;So the parser does not wait for &quot;enough bytes&quot;. It is a function of the
prefix read so far, answering one of four things: the name, no name,
not TLS at all, or need more. After every read the router calls it
again on the whole prefix:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;loop&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; let&lt;/span&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; hs&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;first&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; kind&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; CLIENT_HELLO&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; Hello&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;Invalid&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; let&lt;/span&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; hs&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;u24&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 4&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; +&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; MAX_HELLO&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; Hello&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;Invalid&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; let&lt;/span&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; hs&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; +&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt; client_hello&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;unwrap_or&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);&quot;&gt;Hello&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;Invalid&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; Header first: a non-TLS client must hear &amp;quot;no&amp;quot; now, not after it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; sends as many bytes as its first five happen to spell.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;h&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; records&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;take&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; else&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; Hello&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;NeedMore&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u16&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;from_be_bytes&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;[&lt;/span&gt;&lt;span&gt;h&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span&gt; h&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; 1 &amp;lt;= len &amp;lt;= MAX_RECORD in one unsigned compare.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u16&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;from_be_bytes&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;[&lt;/span&gt;&lt;span&gt;h&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span&gt; h&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; RECORD_MAGIC&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;        |&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;|&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;wrapping_sub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; MAX_RECORD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; Hello&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;Invalid&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt; Some&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;payload&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; records&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;take&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; else&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; Hello&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;NeedMore&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hs&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;extend_from_slice&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;payload&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Re-parsing from the start after each read is quadratic, but only in the
number of reads, and a cap on the hello (32 KiB) plus a timeout keep
that small. The comment about the header is about plain HTTP: if the
parser waited for a whole record before checking the header, a client
that sends &lt;code&gt;GET /&lt;/code&gt; would have its first five bytes read as a record
length, and the router would politely wait for kilobytes that never
come.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://panacan.xyz/blog/hello/&quot;&gt;first post&lt;/a&gt; has this parser compiled to
WebAssembly, where you can split a hello into records and send it byte
by byte.&lt;/p&gt;
&lt;p&gt;The decision costs nothing compared to what follows. Every byte read so
far goes to the backend first, so it sees the stream exactly as the
client sent it.&lt;/p&gt;
&lt;h2 id=&quot;splicing-without-buffers&quot;&gt;Splicing without buffers&lt;/h2&gt;
&lt;p&gt;After the decision the router copies bytes both ways until both sides
close. Tokio&#39;s &lt;code&gt;copy_bidirectional&lt;/code&gt; does this with two 8 KiB buffers
per connection, held for the whole life of the connection, and most
connections spend most of their life idle. Add the hello buffer, which
the first version kept until the end too, and an idle connection held
about 21 KiB of user-space memory. Four thousand of them, about 84 MiB,
for nothing.&lt;/p&gt;
&lt;p&gt;The replacement waits for readability holding nothing. When the socket
is readable it reads into a 16 KiB scratch buffer that belongs to the
worker thread, and writes straight on. There is no &lt;code&gt;.await&lt;/code&gt; between the
read and the write, so the scratch is free again before the task yields
and another connection on the same thread can use it:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;from&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;readable&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;let&lt;/span&gt;&lt;span&gt; rest&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; SCRATCH&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;with_borrow_mut&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;|&lt;/span&gt;&lt;span&gt;buf&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; match&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;try_read&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;buf&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; /*&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; 0 = EOF, WouldBlock = spurious &lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;*/&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; m&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; match&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;try_write&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;buf&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;..&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; /*&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; WouldBlock = 0 &lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;*/&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; Empty when everything went out: no allocation.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt;    Ok&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt;Some&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;buf&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;[&lt;/span&gt;&lt;span&gt;m&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;..&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;to_vec&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Only what the other side does not take right away is copied into a
buffer of its own, and that buffer is dropped, not just emptied, once
it drains. An idle connection now holds its task, around a kilobyte.
That number is computed from the sizes, not measured on the server.&lt;/p&gt;
&lt;p&gt;One detail I did measure. The first version tracked a partly written
remainder with an offset, and a mutation (&lt;code&gt;sent = m&lt;/code&gt; instead of
&lt;code&gt;sent += m&lt;/code&gt;) survived every test. To catch it I shrank the socket send
buffer to 4 KiB and counted: 29 MiB through the relay, over 1800
remainders, and every one went out in a single write. On loopback the kernel lets a
write overshoot the send buffer by a segment, so two short writes in a
row never happen. Instead of a test that cannot fail, the offset went
away: &lt;code&gt;left.drain(..m)&lt;/code&gt; has nothing to get wrong, and the memmove of at
most 16 KiB on a rare short write costs nothing.&lt;/p&gt;
&lt;h2 id=&quot;four-lanes-one-cas&quot;&gt;Four lanes, one CAS&lt;/h2&gt;
&lt;p&gt;The first limit is on concurrent connections per client, where a client
is an IPv4 address or an IPv6 /64 (what one subscriber usually gets).
Without it, one machine opens four thousand connections, never sends a
hello, and the router is full.&lt;/p&gt;
&lt;p&gt;The obvious version is a mutex around a &lt;code&gt;HashMap&lt;/code&gt; from client to count,
and that is what I wrote first. It works, but every connection takes a
lock, and the map grows with whatever addresses the internet throws at
it. The current version is a count-min sketch in a fixed table: each
&lt;code&gt;AtomicU64&lt;/code&gt; holds four 16-bit counters (lanes), and a client counts
against two lanes of one word, picked by a keyed hash. Six ways to
choose two lanes of four, so the pair comes from the hash too.&lt;/p&gt;
&lt;p&gt;Admitting a connection means checking that not both of the client&#39;s
lanes are at the cap, and adding one to both. All four lanes compare
against the cap at once:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; ONES&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 0x0001_0001_0001_0001&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; HIGH&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; ONES&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 15&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; Lanes of `word` that are at least `limit`, as their top bit.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt; lanes_at_least&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt;word&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt; limit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;word&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; HIGH&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; -&lt;/span&gt;&lt;span&gt; limit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; ONES&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; HIGH&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every lane stays below 2^15. Setting its top bit and subtracting the
limit therefore cannot borrow from the next lane, and the top bit
survives exactly when the lane was at least the limit. A lane holding 5
with limit 8: &lt;code&gt;0x8005 - 8 = 0x7ffd&lt;/code&gt;, top bit gone, below. A lane holding
9: &lt;code&gt;0x8009 - 8 = 0x8001&lt;/code&gt;, still set. The whole admission is one
compare-and-swap:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;let&lt;/span&gt;&lt;span&gt; mine&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; lanes&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 15&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; the client&amp;#39;s two top bits&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;loop&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt; lanes_at_least&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;cur&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span&gt; per_client&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; mine&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; ==&lt;/span&gt;&lt;span&gt; mine&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt; Err&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;Refusal&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;MaxConnsPerClient&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    match&lt;/span&gt;&lt;span&gt; cell&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;compare_exchange_weak&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;cur&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span&gt; cur&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; +&lt;/span&gt;&lt;span&gt; lanes&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; AcqRel&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; Relaxed&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt;        Ok&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; break&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-weight: bold;&quot;&gt;        Err&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;now&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; cur&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; now&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Releasing is &lt;code&gt;fetch_sub(lanes)&lt;/code&gt;. No lock, no allocation, 128 KiB of
table for four thousand connections.&lt;/p&gt;
&lt;p&gt;Why two lanes of &lt;em&gt;one&lt;/em&gt; word and not a real count-min with lanes in two
different words, which would collide less? Because two &lt;code&gt;fetch_add&lt;/code&gt;s are
not one atomic step. Let a client sit one below its cap, and two of its
connections arrive at once. In word 1 the first increments before the
second, in word 2 the other way round. Each sees one of its counters at
&lt;code&gt;cap - 1&lt;/code&gt;, the minimum is below the cap for both, and both get in. One
word and one CAS keep the bound exact.&lt;/p&gt;
&lt;p&gt;A lane is never below the number of live connections of any client on
it, so nobody gets more than the cap. The reverse can fail: an honest
client is refused when both of its lanes are full of other people. That
mostly takes a twin, a client in the same word with the same pair,
about &lt;code&gt;clients / (6 * words)&lt;/code&gt; of them. A test with 600 clients all
pushing toward a cap of 8 refuses 0.42 % of honest attempts. With the
real cap of 64 an honest twin does not get there, so in practice being
refused means sharing a cell with whoever is abusing it, and the keyed
hash keeps anyone from choosing their cell.&lt;/p&gt;
&lt;h2 id=&quot;the-trick-that-fails-and-then-works&quot;&gt;The trick that fails, and then works&lt;/h2&gt;
&lt;p&gt;Count-min has a well-known improvement, conservative update: add one
only to the lanes that hold the client&#39;s minimum. It cuts overestimates
a lot, which here means fewer refused twins. It is also wrong here, even
though each connection remembers which lanes it raised. Two clients, A
on lanes (L1, L3), B on (L1, L2):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A opens 5 connections: L1 = L3 = 5.&lt;/li&gt;
&lt;li&gt;B opens 3. L1 is above B&#39;s minimum, so only L2 grows: L2 = 3.&lt;/li&gt;
&lt;li&gt;A closes all 5: L1 = 0.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;B now has three live connections and a minimum of zero. The bound is
gone, and B can open its full cap on top of them.&lt;/p&gt;
&lt;p&gt;Plain count-min survives this because every connection does the same
thing to the table: opening adds one to both lanes, closing takes one
from both, so a closing undoes its opening exactly, whatever happened in
between. In algebra this is called a homomorphism of groups.
Conservative update makes what an opening does depend on the lanes at
that moment, and the closing, later, has no way to undo just that.&lt;/p&gt;
&lt;p&gt;Below is one word of the table with the router&#39;s own comparison, three
clients and a cap of 3. Open and close connections by hand and watch
the top bits decide, or press replay for the same story as above with
smaller numbers. With conservative update off, B stops at the cap.
Switch it on and replay, and B ends up with five.&lt;/p&gt;
&lt;figure class=&quot;demo&quot; data-demo=&quot;lanes&quot;&gt;
  &lt;canvas aria-label=&quot;One word of the per-client table, checked by the router&#39;s own lanes_at_least.&quot;&gt;&lt;/canvas&gt;
  &lt;noscript&gt;This demo needs JavaScript and WebAssembly.&lt;/noscript&gt;
  &lt;figcaption&gt;One word of the per-client table, checked by the router&#39;s own lanes_at_least.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;script type=&quot;module&quot; src=&quot;https://panacan.xyz/demos/lanes/main.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;The second limit is on the &lt;em&gt;rate&lt;/em&gt; of new connections per client, which
the first does not cover: a client that opens and closes connections in
a loop never holds many at once. The classic algorithm is GCRA. It
keeps one number per client, the theoretical arrival time (TAT): a
connection at time &lt;code&gt;now&lt;/code&gt; is let in when &lt;code&gt;max(TAT, now) - now &amp;lt;= tau&lt;/code&gt;,
and then &lt;code&gt;TAT = max(TAT, now) + T&lt;/code&gt;, with &lt;code&gt;T&lt;/code&gt; the interval at the
sustained rate and &lt;code&gt;tau = (burst - 1) * T&lt;/code&gt;. Nothing but &lt;code&gt;max&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt;:
arithmetic in the max-plus semiring.&lt;/p&gt;
&lt;p&gt;The TATs go into the same shape of table: 16-bit lanes, two per client,
one CAS. A lane holds the largest TAT of everybody on it, so it never
says a client&#39;s TAT is earlier than it is, and a collision can only make
the limit stricter. And here conservative update works: the new TAT
estimate comes from the smaller lane, and each lane is raised only to
that, &lt;code&gt;lane = max(lane, tat + T)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here nothing is ever undone. A TAT is not taken back when a connection
closes, it just falls behind as time passes, and raising a lane with
&lt;code&gt;max&lt;/code&gt; twice is the same as raising it once. So a lane never drops below
anyone&#39;s true TAT. Counting needs undoing and breaks; taking a maximum
never does and holds. Algebra has names for the two, a group and a
semilattice.&lt;/p&gt;
&lt;p&gt;Lanes count ticks since an epoch, and 15 bits run out. Once the epoch is
a window old, the next admission moves it to now and subtracts the
difference from the whole table, four lanes per word at once, saturating
at zero:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; `max(lane - d, 0)` in every lane, for lanes and `d` below 2^15.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt; saturating_sub&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt;word&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; Surviving lanes as 0xffff each: the comparison&amp;#39;s top bits,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;    //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; moved to the bottom of the lane and multiplied out.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; keep&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;lanes_at_least&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;word&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 15&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 0xffff&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;word&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; HIGH&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; -&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; ONES&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt;HIGH&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; keep&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rebase moves the epoch first and the words after it. Admissions
read the epoch before and after their word and start over if it moved,
in the style of a seqlock. One that read a word before the shift and
writes it after fails its CAS, unless the word was all zeros, in which
case its write is late by the shift, which again only makes the limit
stricter. The defaults are 10 new connections per second with bursts
of 40, enough for a reload spree, far below a scanner.&lt;/p&gt;
&lt;h2 id=&quot;evicting-the-silent&quot;&gt;Evicting the silent&lt;/h2&gt;
&lt;p&gt;A slowloris connects and says nothing until the hello timeout. The per-client
caps limit how many slots one address can take, but a botnet has
many addresses, and once the router is full the classic response, turn
newcomers away, works for the attacker. An honest client sends its
hello one round trip after connecting. So when the router is full, the
connection that has been silent the longest goes, and the newcomer gets
its slot.&lt;/p&gt;
&lt;p&gt;That needs the oldest of the connections still waiting for a hello, and
it needs it under a flood. Waiting connections go into a ring of 64
time slots, each a slice of the hello timeout over 32 (156 ms at the
default 5 s), so everyone waiting fits in half the ring. A &lt;code&gt;u64&lt;/code&gt; says
which slots are occupied. The oldest slot is the first set bit counting
from the slot after the current one, which is the one 64 slices ago:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;let&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#179299, #94E2D5);font-style: italic;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;slot_at&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;now&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; %&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; SLOTS&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;let&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; (&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; +&lt;/span&gt;&lt;span&gt; ring&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span&gt;bits&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;rotate_right&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;trailing_zeros&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; %&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-weight: bold;&quot;&gt; SLOTS&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rotate so the oldest possible slot is bit 0, count trailing zeros, done.
The same structure sits in the
&lt;a href=&quot;https://panacan.xyz/blog/offset/&quot;&gt;allocator&lt;/a&gt; as its size-class bitmap; there it finds the
smallest class with a free block, here the oldest slice with a silent
connection. Since nobody waits longer than the timeout, one word is
enough and the second level of the allocator&#39;s bitmap is not needed.&lt;/p&gt;
&lt;p&gt;The oldest connection must also have been silent for at least a second
before it is evicted. Under a flood of fresh connections that never
waited, everyone is young, and evicting would only make honest clients
evict each other; the newcomer is turned away as before.&lt;/p&gt;
&lt;h2 id=&quot;proxy-and-a-web-server-that-believes-it&quot;&gt;PROXY, and a web server that believes it&lt;/h2&gt;
&lt;p&gt;The web server behind the router used to see every visitor as
127.0.0.1. The PROXY protocol fixes that: before the first byte of the
connection the router sends a small binary header with the client&#39;s
address and the address it connected to. Sixteen bytes of signature and
lengths, then the addresses. The header and the hello go out in one
write, so in one segment.&lt;/p&gt;
&lt;p&gt;Then the plaintext port, so that &lt;code&gt;http://&lt;/code&gt; redirects to &lt;code&gt;https://&lt;/code&gt;. The
web server&#39;s PROXY support is global, so it now expects the header on
port 80 too, and the router forwards port 80 without parsing anything,
header first. In the local test the redirect returned 404 whatever I
did. The reason: with PROXY on, the web server takes the server port
from the header, which is the public port 80, while it listened on 8080,
so its &quot;this is my HTTP port, redirect&quot; rule never fired. The fix was to
give it the same ports on loopback that the world sees, 80 and 443. It
is now consistent with the outside, and the redirect comes with a clean
&lt;code&gt;https://panacan.xyz/...&lt;/code&gt; instead of an internal port.&lt;/p&gt;
&lt;p&gt;The access log now has real addresses. A pipeline adds country, city
and network operator from the free DB-IP databases, and a dashboard
shows where the visitors come from, which pages, which referrers, and
which bots. City is approximate at best: my phone, lying next to the laptop, shows
up in a village 350 km east, because mobile operators hand out addresses
from large pools.&lt;/p&gt;
&lt;h2 id=&quot;testing-against-exact-models&quot;&gt;Testing against exact models&lt;/h2&gt;
&lt;p&gt;Most of the tests compare the router with something slower that is
obviously right:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the lane comparison and the saturating subtraction against loops,
100 000 random words each;&lt;/li&gt;
&lt;li&gt;the connection sketch against an exact count per client, 200 000
random admits and releases: nobody over the cap, the table back to
zero at the end, honest refusals under 1 %;&lt;/li&gt;
&lt;li&gt;the rate sketch against exact GCRA per client on the same tick grid,
300 000 steps with hour-long pauses that force epoch moves: whenever
the sketch lets a connection in, exact GCRA would have too;&lt;/li&gt;
&lt;li&gt;end to end on loopback: routing, fragmented hellos, timeouts, caps,
the PROXY header byte for byte, eviction under a full router.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then mutations: break one line, check that a test fails. Rebase without
moving the epoch, raise only one lane, &lt;code&gt;min&lt;/code&gt; turned into &lt;code&gt;max&lt;/code&gt;, no
rotation in the ring, no minimum age for eviction, eviction off: each
fails a test, the first by hanging it. One survives by design: the epoch check against
concurrent admissions. It is reasoned through in a comment, and the
tests are single-threaded.&lt;/p&gt;
&lt;h2 id=&quot;what-broke-this-time&quot;&gt;What broke this time&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;A timeout around nothing.&lt;/strong&gt; The first version of the plaintext mode
read &lt;code&gt;let read = read_hello(&amp;amp;mut client).await;&lt;/code&gt; and then wrapped &lt;code&gt;read&lt;/code&gt;
in a timeout. The timeout guarded a value that was already there. Found
on reading it back, before any test, which is the kind of luck that
does not repeat.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resets that were refusals.&lt;/strong&gt; The new end-to-end tests failed with
&quot;connection reset by peer&quot;. A connection refused right after accept is
closed with the client&#39;s bytes unread, and the kernel answers that with
RST, not FIN. The tests now count a reset as the router hanging up,
which is what it is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quotes.&lt;/strong&gt; The dashboard&#39;s log queries worked against the log database
and failed in Grafana: its plugin mangles quotes in queries on the way
through. The fix was to compute the field in the log pipeline, so the
queries need no regular expression at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The dashboard that took Grafana down.&lt;/strong&gt; I gave the data sources fixed
identifiers so the dashboard could refer to them. Grafana looks up
existing sources by that identifier, did not find the old ones, and
refused to start. The provisioning now deletes them by name and creates
them again on every start.&lt;/p&gt;
&lt;h2 id=&quot;the-neighbourhood&quot;&gt;The neighbourhood&lt;/h2&gt;
&lt;p&gt;Rust has a few relatives of this router.
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/junkurihara/rust-rpxy-l4&quot;&gt;rpxy-l4&lt;/a&gt; is the closest:
TCP and UDP, routing by SNI and ALPN including QUIC, and PROXY in both
directions, still marked as work in progress.
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/plabayo/rama&quot;&gt;Rama&lt;/a&gt; is a framework for programmable
proxies and lists SNI proxies explicitly. ByteDance&#39;s
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/bytedance/g3&quot;&gt;g3proxy&lt;/a&gt; has an SNI proxy mode inside
an enterprise forward proxy. What none of them does in this form is the
sketches, as far as I could see: fixed memory under attack, one CAS per
decision, and a bound that holds by algebra rather than by a lock.&lt;/p&gt;
&lt;h2 id=&quot;next&quot;&gt;Next&lt;/h2&gt;
&lt;p&gt;QUIC carries the same server name in its first packet, encrypted with
keys anyone can derive from a public salt. Routing UDP on port 443 means
decrypting that, reading the hello, and then following connection IDs
instead of sockets. Others already do this well: rpxy-l4 routes QUIC by
SNI today, and the big proxies have known QUIC inside out for years. So
naturally I will try to implement it my own way, break it a few times on
the way, and maybe learn something.&lt;/p&gt;
&lt;p&gt;Further out is Encrypted Client Hello in split mode: the router would
hold the key, decrypt the inner hello and route on the real name, while
anything watching the wire sees only &lt;code&gt;panacan.xyz&lt;/code&gt;. For a router whose
reason to exist is a network that allows nothing but 443, that is the
logical end.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Size as an 8-bit float</title>
        <published>2026-10-06T00:00:00+00:00</published>
        <updated>2026-10-11T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://panacan.xyz/blog/offset/"/>
        <id>https://panacan.xyz/blog/offset/</id>
        
        <content type="html" xml:base="https://panacan.xyz/blog/offset/">&lt;p&gt;The GPU hands you a large chunk of memory, say 256 MiB, and you are on
your own from there. Hundreds of buffers and textures live in that
chunk, created and destroyed every frame. So I need an allocator, but
an odd one: I cannot see into that memory. I cannot write a block
header into it like &lt;code&gt;malloc&lt;/code&gt; does, and I cannot walk it. The whole
allocator has to live on the side and hand out nothing but numbers,
offsets into the chunk. Hence: an offset allocator.&lt;/p&gt;
&lt;p&gt;It has to be fast and, above all, predictable. An allocation in the
middle of a frame that takes ten times longer once in a while is worse
than one that is always a little slow.&lt;/p&gt;
&lt;p&gt;The result is &lt;a rel=&quot;external&quot; href=&quot;https://github.com/mightsleep/holeinone&quot;&gt;holeinone&lt;/a&gt;, a
hole in one. This post is how it got there.&lt;/p&gt;
&lt;h2 id=&quot;naive-a-list-of-holes&quot;&gt;Naive: a list of holes&lt;/h2&gt;
&lt;p&gt;The simplest allocator keeps a list of free ranges, holes. To allocate,
it walks the list and takes the first hole the request fits (first
fit), or the smallest one it fits (best fit), and puts the rest of the
hole back. To free, it returns the range and glues it to neighbouring
holes, if there are any.&lt;/p&gt;
&lt;p&gt;It works, and it is linear. With a thousand holes that is a thousand
comparisons per allocation, and holes multiply exactly when memory is
most fragmented, that is, when it already hurts. Sorting the holes by
size into a tree gives a logarithm, which is decent, but still a
search.&lt;/p&gt;
&lt;h2 id=&quot;buddy-powers-of-two-and-xor&quot;&gt;Buddy: powers of two and XOR&lt;/h2&gt;
&lt;p&gt;The Linux kernel allocates pages differently. Every block is a power of
two in size and sits at an offset that is a multiple of it. A block of
size &lt;code&gt;2^k&lt;/code&gt; at offset &lt;code&gt;o&lt;/code&gt; then has exactly one possible partner, its
buddy, at &lt;code&gt;o ^ (1 &amp;lt;&amp;lt; k)&lt;/code&gt;. Freeing does not search, it computes: is the
buddy free? Merge the two into a block one order larger and try again.
Free blocks are kept in lists per order, so an allocation takes the
first non-empty list from the right order up.&lt;/p&gt;
&lt;p&gt;Beautiful, but it costs memory. A request for 65 KiB gets 128 KiB. In
the worst case almost half is thrown away.&lt;/p&gt;
&lt;h2 id=&quot;size-as-a-float&quot;&gt;Size as a float&lt;/h2&gt;
&lt;p&gt;Buddy has size classes by powers of two, which is too coarse. Linear
classes would be too fine: from bytes to gigabytes there would be
billions of them. I want something in between, and we all know that
something: a float. A float has an exponent, so it covers a huge range,
and a mantissa, so it tells a few steps apart within one power of two.&lt;/p&gt;
&lt;p&gt;So I take the size and encode it in eight bits as a small float: three
bits of mantissa, five of exponent. The exponent is the position of the
highest set bit, one &lt;code&gt;lzcnt&lt;/code&gt; instruction, and the mantissa is the three
bits below it:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt; uint_to_float_round_down&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 8&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;        return&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; highest_set_bit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 31&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; -&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;leading_zeros&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; mantissa_start_bit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; highest_set_bit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; exp&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span&gt; mantissa_start_bit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; mantissa&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; (&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; mantissa_start_bit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 7&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    (&lt;/span&gt;&lt;span&gt;exp&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; |&lt;/span&gt;&lt;span&gt; mantissa&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That makes 256 codes, of which sizes in &lt;code&gt;u32&lt;/code&gt; reach 240, and the top
class starts at 3.75 GiB. Each power of two holds eight classes, so the
sizes of blocks in one class differ by at most an eighth. A few
examples:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;size&lt;/th&gt;&lt;th&gt;class&lt;/th&gt;&lt;th&gt;class range&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;36&lt;/td&gt;&lt;td&gt;96 to 103&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;1,000&lt;/td&gt;&lt;td&gt;63&lt;/td&gt;&lt;td&gt;960 to 1,023&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;4,096&lt;/td&gt;&lt;td&gt;80&lt;/td&gt;&lt;td&gt;4,096 to 4,607&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;1,000,000&lt;/td&gt;&lt;td&gt;143&lt;/td&gt;&lt;td&gt;983,040 to 1,048,575&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;And this is not a float only figuratively. Convert the size to &lt;code&gt;f64&lt;/code&gt;
and look at the bits. The exponent of an &lt;code&gt;f64&lt;/code&gt; is &lt;code&gt;1023 + h&lt;/code&gt;, where &lt;code&gt;h&lt;/code&gt;
is the position of the highest bit, and the top three bits of the
mantissa sit at bits 49 to 51. My exponent is &lt;code&gt;h − 2&lt;/code&gt;, so a shift and a
subtraction do it:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt; round_down_f64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;   //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; for size &amp;gt;= 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;to_bits&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 49&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;1025&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt; round_up_f64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt;     //&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);font-style: italic;&quot;&gt; for size &amp;gt;= 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;to_bits&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 49&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 49&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt;1025&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rounding up is adding &quot;almost one&quot; just below the three mantissa bits.
When the mantissa overflows from &lt;code&gt;0b111&lt;/code&gt;, the carry walks into the
exponent by itself, exactly as with any other float. I checked this
against the original functions for every size from 8 to 2³² − 1, and
they never differ. It is not faster, the conversion to &lt;code&gt;f64&lt;/code&gt; has a
longer latency than &lt;code&gt;lzcnt&lt;/code&gt;. But nobody can claim any more that it is
only &lt;em&gt;like&lt;/em&gt; a float.&lt;/p&gt;
&lt;p&gt;A free block goes into the class of its size rounded down. A request is
rounded up instead: whoever wants 100 bytes searches from class 37,
that is, from 104. That guarantees any block in class 37 or above fits,
and nothing inside a class needs comparing. I take the first block of
the list and I am done. Not exactly best fit, but at worst an eighth
off.&lt;/p&gt;
&lt;h2 id=&quot;where-is-the-nearest-non-empty-class&quot;&gt;Where is the nearest non-empty class&lt;/h2&gt;
&lt;p&gt;What remains is finding the smallest non-empty class from 37 up.
Naively, walk the lists one by one, all 256 in the worst case. But &quot;is
this class non-empty&quot; is one bit, and 256 bits fit in four words. And
&quot;find the first one bit from position k on&quot; is a mask and a &lt;code&gt;tzcnt&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CDD6F4); background-color: light-dark(#EFF1F5, #1E1E2E);&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8839EF, #CBA6F7);font-weight: bold;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt; find_lowest_bit_set_after&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt;mask&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #FAB387);font-style: italic;&quot;&gt; start_bit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt; Option&lt;/span&gt;&lt;span style=&quot;color: light-dark(#04A5E5, #89DCEB);&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#04A5E5, #89DCEB);&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;    (&lt;/span&gt;&lt;span&gt;mask&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: light-dark(#DF8E1D, #F9E2AF);&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #89B4FA);font-weight: bold;&quot;&gt;u32&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;low_ones&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span&gt;start_bit&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6E3A1);font-weight: bold;font-style: italic;&quot;&gt;first_set&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #9399B2);&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(&lt;code&gt;low_ones&lt;/code&gt; and &lt;code&gt;first_set&lt;/code&gt; come from
&lt;a rel=&quot;external&quot; href=&quot;https://crates.io/crates/hakmem&quot;&gt;hakmem&lt;/a&gt;; otherwise it is a plain
&lt;code&gt;mask &amp;amp; !((1 &amp;lt;&amp;lt; k) - 1)&lt;/code&gt; and &lt;code&gt;trailing_zeros&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;To make it one word instead of four, the bitmap has two levels, shaped
exactly like the float: the top five bits of the class (the exponent)
pick one of the 32 bits of the top mask, the bottom three (the
mantissa) one of the eight bits of the byte below it. The search then
goes: try the rest of the byte in your own power of two, and if it is
empty, jump in the top mask to the next non-empty power and take its
lowest class. Two bit searches, no loop, no walking lists. Allocation
is O(1), and the constant really is small.&lt;/p&gt;
&lt;h2 id=&quot;free-neighbours-by-offset&quot;&gt;Free: neighbours by offset&lt;/h2&gt;
&lt;p&gt;To free, I need to glue the block to its free neighbours. Buddy
computed them with an XOR; here blocks have arbitrary sizes, so XOR is
no help. What helps is that every block, free or used, remembers its
left and right neighbour in memory. Freeing looks at two pointers: is
the neighbour free? Take it out of its class and attach it. Then put the
result into the class of its new size. O(1) again, no search again.&lt;/p&gt;
&lt;p&gt;Well, it should be. My first port had singly linked class lists. That
saves 4 bytes per node and is enough for allocation, which always takes
the head of a list. But the neighbour I merge with has to come out of
the &lt;em&gt;middle&lt;/em&gt; of its list, and that needs its predecessor. A singly
linked list finds it only by walking from the head. I defended this in
a comment: classes tend to be short, and fine classes &quot;naturally bound&quot;
their length. They do not. Nothing bounds how many blocks one class can
hold.&lt;/p&gt;
&lt;p&gt;Allocate n equal blocks, free every other one (n/2 blocks in one class),
then free the rest. Every free merges with a neighbour deep in the
list:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;n&lt;/th&gt;&lt;th&gt;singly linked&lt;/th&gt;&lt;th&gt;offset-allocator&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;10,000&lt;/td&gt;&lt;td&gt;3,361 ns per free&lt;/td&gt;&lt;td&gt;23 ns&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;20,000&lt;/td&gt;&lt;td&gt;6,481 ns&lt;/td&gt;&lt;td&gt;23 ns&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;40,000&lt;/td&gt;&lt;td&gt;12,764 ns&lt;/td&gt;&lt;td&gt;23 ns&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The time per free grows linearly, the whole thing is quadratic.
Upstream has doubly linked lists and holds a constant. A regression I
had brought into my own fork, for 4 bytes.&lt;/p&gt;
&lt;p&gt;The fix is a doubly linked list, and the 4 bytes can be found
elsewhere. A node that sits in no list and no allocation has its list
link unused, so the stack of free nodes can be threaded through those
nodes instead of a separate array of indices. A node stays at 24 bytes,
as before (20 plus 4 in the array), and there is a bonus: nodes are
taken from the reserved array only when first needed. Creating an
allocator with 128 Ki nodes went from 101 µs to 81 ns and &lt;code&gt;reset&lt;/code&gt; from
80 µs to 30 ns, because neither touches the node array any more. And
under churn at 90 % occupancy, where merging never stops, allocate and
free together got twice as fast (80 against 39 ns per operation),
without any constructed worst case.&lt;/p&gt;
&lt;h2 id=&quot;the-asymmetry-where-the-bug-hid&quot;&gt;The asymmetry where the bug hid&lt;/h2&gt;
&lt;p&gt;I insert rounding down and search rounding up. What if exactly one free
block of size 100 exists and someone wants exactly 100? The block sits
in class 36, the search starts at class 37 and skips it. The allocator
reports out of memory with a perfectly fitting block right there.&lt;/p&gt;
&lt;p&gt;This is not an academic exercise. The cleanest case is a fresh
allocator holding its whole capacity in one block, asked for its whole
capacity. Unless the capacity lies on a class boundary, the answer is
&lt;code&gt;None&lt;/code&gt;. The Rust port
&lt;a rel=&quot;external&quot; href=&quot;https://crates.io/crates/offset-allocator&quot;&gt;&lt;code&gt;offset-allocator&lt;/code&gt;&lt;/a&gt; has it
as a known bug (pcwalton #9, sebbbi #11 in the original). The fix is a
slow path: when the fast search finds nothing, walk the list of the
round-down class as well and check the actual block sizes. That class
usually holds few blocks, and the fast path stays untouched.&lt;/p&gt;
&lt;p&gt;It can all be said algebraically, and then it is clear why the bug
happened. Rounding up is rounding down the number one smaller, plus
one:&lt;/p&gt;
&lt;div data-typst=&quot;prelude&quot; hidden data-src=&quot;&amp;#10;#let rd = math.op(&amp;quot;rd&amp;quot;)&amp;#10;#let ru = math.op(&amp;quot;ru&amp;quot;)&amp;#10;&quot;&gt;&lt;/div&gt;
&lt;div data-typst=&quot;block&quot; data-src=&quot;&amp;#10;ru(r) = rd(r - 1) + 1&amp;#10;&quot;&gt;&lt;/div&gt;
&lt;p&gt;It holds because sizes are integers: a class&#39;s lower bound is at least
&lt;code&gt;r&lt;/code&gt; exactly when it is greater than &lt;code&gt;r − 1&lt;/code&gt;. With floats it would not
hold.&lt;/p&gt;
&lt;p&gt;So the fast path searches for the &lt;em&gt;strict successor&lt;/em&gt; of the class that
&lt;code&gt;r − 1&lt;/code&gt; falls in. But the blocks that would fit exactly sit in class
&lt;code&gt;round_down(r)&lt;/code&gt;, and unless &lt;code&gt;r&lt;/code&gt; lies on a class boundary, that is the
same class as &lt;code&gt;round_down(r − 1)&lt;/code&gt;: precisely the one the strict
successor skips. The right query is &quot;successor or equal&quot; for
&lt;code&gt;round_down(r)&lt;/code&gt;, with sizes to check in that one class only. The slow
path does exactly this, it just has a name now. And the second rounding
function is not needed any more.&lt;/p&gt;
&lt;h2 id=&quot;the-tip-of-the-iceberg&quot;&gt;The tip of the iceberg&lt;/h2&gt;
&lt;p&gt;But the slow path only gets its turn when everything above
&lt;code&gt;round_down(r)&lt;/code&gt; is empty. Until then the class is skipped every time.
Whoever wants 100 bytes while class 36 holds a block of 101 does not
get it: they get a piece of the first block a class or more higher, and
that one gets split. On an empty allocator it does not matter. On a
full one it turns into rubble.&lt;/p&gt;
&lt;p&gt;I measured it on a long workload: log-uniform sizes in a range,
allocate until occupancy reaches 90 %, then free random allocations,
round and round a million times. How many allocations failed:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;64 MiB, blocks 64 B to 64 KiB&lt;/th&gt;&lt;th&gt;256 MiB, blocks 64 B to 4 MiB&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;search from &lt;code&gt;round_up&lt;/code&gt; (original)&lt;/td&gt;&lt;td&gt;11.65 %&lt;/td&gt;&lt;td&gt;30.95 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;own &lt;code&gt;round_down&lt;/code&gt; class first&lt;/td&gt;&lt;td&gt;0.049 %&lt;/td&gt;&lt;td&gt;21.1 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;and 16 classes per power of two&lt;/td&gt;&lt;td&gt;&lt;strong&gt;0.010 %&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;19.2 %&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The fix is that identity again, this time in the fast path. The bitmap
is asked not for the strict successor of class &lt;code&gt;round_down(r)&lt;/code&gt; but for
&quot;successor or equal&quot;. When the &lt;code&gt;round_down&lt;/code&gt; class is empty, which on a
lightly used allocator it nearly always is, the query returns exactly
what it did before: the same instructions, a different start bit. When
it is not empty, I check at most four of its blocks, and if none fits,
continue one class up.&lt;/p&gt;
&lt;p&gt;The third row is the second lever. The asymmetry never goes away, the
width of a class only sets how much of its own class a request skips.
With four mantissa bits a class is a sixteenth wide instead of an
eighth, and failures on the smaller blocks drop another five times, at
the same speed, for 1 KiB more of class heads. With the large blocks,
90 % is past what any placement survives: even an exact best fit over
a tree of free ranges fails 18.7 % of the same requests, so 19.2 % is
at the ceiling.&lt;/p&gt;
&lt;p&gt;Try it: two 4 MiB heaps get exactly the same stream of requests (blocks
of 64 B to 8 KiB, occupancy held at the target) and differ only in where
the allocator starts searching. Both hold the same occupancy, so both
have the same amount of free memory. The difference is &lt;em&gt;where&lt;/em&gt; that
free memory is: the original has it broken into holes an ordinary
request does not fit, and so it fails. The lower chart shows it
directly, free memory by hole size.&lt;/p&gt;
&lt;figure class=&quot;demo&quot; data-demo=&quot;offset&quot;&gt;
  &lt;canvas aria-label=&quot;The same workload, two search policies. The allocator is Rust compiled to WebAssembly, a faithful miniature of the one measured here.&quot;&gt;&lt;/canvas&gt;
  &lt;noscript&gt;This demo needs JavaScript and WebAssembly.&lt;/noscript&gt;
  &lt;figcaption&gt;The same workload, two search policies. The allocator is Rust compiled to WebAssembly, a faithful miniature of the one measured here.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;script type=&quot;module&quot; src=&quot;https://panacan.xyz/demos/offset/main.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;cutting-in-place&quot;&gt;Cutting in place&lt;/h2&gt;
&lt;p&gt;After all the fixes, holeinone was faster than upstream wherever blocks
are freed and reused. Only allocation alone, carving up one large block
in sequence, was 1.23 times slower. So I looked at where the time went.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;perf annotate&lt;/code&gt; showed allocation bound by the latency of a chain of
dependent loads: the bitmap, the class head (20 % of samples), the node,
the store of the new head (9 %), the remainder&#39;s class and its head
(18 %). The block comes out of its list, the allocation is cut off its
front, and the rest goes back in. But when one large block is being
carved up, the rest almost always lands in the &lt;em&gt;same&lt;/em&gt; class the block
came from. The list empties, the bitmap bits are cleared, and right
after, the same list fills up again and the bits are set.&lt;/p&gt;
&lt;p&gt;Turn it around: the free node keeps the rest. It stays where it is, in
the same list, with its offset moved up and its size reduced, and the
allocation gets the new node. Neither the lists nor the bitmap are
touched. Placement does not change, the allocation still takes the
front of the block, so the failure counts on the long workload came out
identical to the last block. Only the cost changed: sequential
allocation went from 44.9 to 32.4 µs, 0.89 of upstream.&lt;/p&gt;
&lt;p&gt;One trap on the way: I generalised it to a cut at any offset, to cover
aligned allocations with front padding as well, and the unaligned path
slowed back down to 40 µs. The general function, one branch richer, was
expensive on the hot path. The unaligned path now has its own
specialised version.&lt;/p&gt;
&lt;h2 id=&quot;beyond-4-gib-and-freeing-when-the-gpu-is-done&quot;&gt;Beyond 4 GiB, and freeing when the GPU is done&lt;/h2&gt;
&lt;p&gt;Offsets in &lt;code&gt;u32&lt;/code&gt; mean a heap of up to 4 GiB, and since the top bit of a
size marks a node used, in fact up to 2 GiB. That is enough for blocks
of the size VMA and friends allocate, but not for one huge buffer
holding all geometry. So holeinone counts in quanta inside, units of a
power-of-two number of bytes, and speaks bytes in &lt;code&gt;u64&lt;/code&gt; outside. A node
stays 24 bytes for any capacity, the quantum is chosen as the smallest
that covers the capacity (one byte up to 2 GiB), and GPU resources need
alignment of tens of bytes and more anyway.&lt;/p&gt;
&lt;p&gt;The second thing I only realised when I imagined actually using the
crate: a renderer cannot free a frame&#39;s buffers when the CPU is done
with them. The GPU reads them one to three frames later. Hence
&lt;code&gt;free_after(allocation, value)&lt;/code&gt;, with a fence or timeline semaphore
value, and &lt;code&gt;retire(completed)&lt;/code&gt;, which frees everything up to that
value. Transients freed three frames later cost 33.2 µs against 28.3 µs
for freeing right away: about 7 % is the queue, the rest more merging,
since blocks leave while more of their neighbours are alive.&lt;/p&gt;
&lt;h2 id=&quot;what-it-buys&quot;&gt;What it buys&lt;/h2&gt;
&lt;p&gt;The core is not mine: it is Sebastian Aaltonen&#39;s OffsetAllocator
(2023), by way of Patrick Walton&#39;s Rust port. Against
&lt;code&gt;offset-allocator&lt;/code&gt; 0.2 on a laptop, median of three criterion runs, the
ratio being holeinone&#39;s time over upstream&#39;s:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;workload&lt;/th&gt;&lt;th&gt;holeinone&lt;/th&gt;&lt;th&gt;offset-allocator&lt;/th&gt;&lt;th&gt;ratio&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;allocate and free 2,000, random order&lt;/td&gt;&lt;td&gt;35.5 µs&lt;/td&gt;&lt;td&gt;44.3 µs&lt;/td&gt;&lt;td&gt;0.80&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;allocate and free 2,000, LIFO&lt;/td&gt;&lt;td&gt;29.5 µs&lt;/td&gt;&lt;td&gt;44.0 µs&lt;/td&gt;&lt;td&gt;0.67&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;transients, 10 frames × 200&lt;/td&gt;&lt;td&gt;28.3 µs&lt;/td&gt;&lt;td&gt;45.4 µs&lt;/td&gt;&lt;td&gt;0.62&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;8 assets plus transients&lt;/td&gt;&lt;td&gt;11.6 µs&lt;/td&gt;&lt;td&gt;18.9 µs&lt;/td&gt;&lt;td&gt;0.61&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;allocate only, 5,000 × 64 B to 64 KiB&lt;/td&gt;&lt;td&gt;32.4 µs&lt;/td&gt;&lt;td&gt;36.4 µs&lt;/td&gt;&lt;td&gt;0.89&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;the same into a full heap (90 % fail)&lt;/td&gt;&lt;td&gt;14.9 µs&lt;/td&gt;&lt;td&gt;11.3 µs&lt;/td&gt;&lt;td&gt;1.32&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;aligned to 4096, 500 × 64 B to 1 KiB&lt;/td&gt;&lt;td&gt;12.0 µs&lt;/td&gt;&lt;td&gt;4.0 µs&lt;/td&gt;&lt;td&gt;3.0&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The last two rows are not the same work. A failing request in mine
still checks the blocks in its own class; upstream gives up at once,
at the price of bug #9. And with alignment, upstream users allocate
&lt;code&gt;size + alignment − 1&lt;/code&gt; and the padding stays inside the allocation, so
at an alignment of 4096 the heap holds several times what was asked
for. holeinone gives the padding back.&lt;/p&gt;
&lt;h2 id=&quot;benchmarks-that-lied&quot;&gt;Benchmarks that lied&lt;/h2&gt;
&lt;p&gt;This part was not planned, and it taught me the most.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The probe that cost 18 %.&lt;/strong&gt; The first measurement on a light workload
said the probe into the &lt;code&gt;round_down&lt;/code&gt; class cost 5 to 18 %. But the
counter said that on the light workload it never once touched a
non-empty class. So I measured A/A: two variants with the same fast
path, differing only in dead code in the slow path. One of them &quot;got
faster&quot; by 3 to 10 %. On microsecond benchmarks, a shift in code
alignment is as large as what you are trying to measure. The
instruction count from &lt;code&gt;perf stat&lt;/code&gt; settled it: the probe adds 2 to 5 %
instructions and is indistinguishable from noise in cycles.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A fresh allocator every iteration.&lt;/strong&gt; The benches built a new
allocator in the iteration setup and consumed it in the timed part.
Once the node array became lazy, the page faults moved from the
constructor into the timed part and holeinone looked slower. What was
measured was when the pages got paid for, not how fast allocation is.
Now each implementation keeps one allocator, reset between iterations
outside the timing, the way a real program uses it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The bench that measured failure.&lt;/strong&gt; &quot;Allocate into 16 MiB&quot; allocated
5,000 blocks of 32 KiB on average. A tenth of them fit. The bench
pretended to measure allocation and measured the failure path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Same code, another binary, a third off.&lt;/strong&gt; Adding two branches to
&lt;code&gt;main&lt;/code&gt; of a measuring harness moved the times of an entirely different
function by a third. I trust only comparisons within one binary, or
instruction counts from &lt;code&gt;perf stat&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cross-crate inlining.&lt;/strong&gt; After the API became a thin wrapper over an
inner function, the body of allocation started being instantiated in
the caller&#39;s crate, and small helpers without &lt;code&gt;#[inline]&lt;/code&gt; could not be
inlined across the crate boundary. A forced &lt;code&gt;#[inline(always)]&lt;/code&gt;, on the
other hand, made sequential allocation 3 % faster and the full-heap
path almost twice as slow.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;An estimate from one harness.&lt;/strong&gt; I estimated the cost of the new API
at 7 % from a harness that dropped the returned handle almost at once.
Criterion, which passes it on, showed over 20 %. Then &lt;code&gt;perf&lt;/code&gt; showed it
was about neither: 96 % of the time was in the allocation function, and
that is where the road to cutting in place started.&lt;/p&gt;
&lt;h2 id=&quot;1994&quot;&gt;1994&lt;/h2&gt;
&lt;p&gt;I started seeing the pattern everywhere: &quot;round the key to a small
float, get few classes, put a bitmap with &lt;code&gt;lzcnt&lt;/code&gt; over them&quot;. Timers:
since 2016 the Linux kernel sorts timers into buckets with a
granularity of about an eighth, and admits a timer may expire that much
later. The commit says it outright, &quot;worst case inaccuracy of 12.5%&quot;
(&lt;a rel=&quot;external&quot; href=&quot;https://github.com/torvalds/linux/commit/500462a9de657f86edaa102f8ab6bff7f7e43fc2&quot;&gt;500462a9de65&lt;/a&gt;).
A priority queue for Dijkstra: the radix heap. Sets of integers: the
van Emde Boas tree. I wrote a timer wheel on this pattern and measured
it against &lt;code&gt;BinaryHeap&lt;/code&gt; from std: seven times faster on dense data. That
is to be expected: a binary heap knows nothing of keys being small
integers. But then I wrote a priority queue for Dijkstra on the same
pattern (Dial&#39;s algorithm: buckets by distance, a two-level bitmap over
them), about a hundred lines, and measured it against the &lt;code&gt;radix-heap&lt;/code&gt;
crate. The radix heap is a structure capable people have been refining
since Ahuja, Mehlhorn, Orlin and Tarjan described it in 1990. On dense
graphs my queue was 1 to 22 % faster, on sparse ones 31 to 74 %. To be
fair: a radix heap takes any monotone keys, mine needs a bounded edge
weight and a bucket for every distance in the window, and the gain is
exactly that with monotone keys nothing gets redistributed. Still. A
general pattern! A universal primitive!&lt;/p&gt;
&lt;p&gt;Then I found Matias, Vitter and Young,
&lt;a rel=&quot;external&quot; href=&quot;https://arxiv.org/abs/cs/0205010&quot;&gt;&lt;em&gt;Approximate Data Structures with Applications&lt;/em&gt;&lt;/a&gt;,
SODA 1994. Keys rounded to a truncated float, error at most &lt;code&gt;1 + ε&lt;/code&gt; in
value, operations in constant time, and as the application exactly
Dijkstra, with a proof of how the error adds up along the path. Their
constant time comes with hashing, so only with high probability; two
bitmaps over the classes do it deterministically. Three mantissa bits
are their &lt;code&gt;ε = 1/8&lt;/code&gt;, four are &lt;code&gt;ε = 1/16&lt;/code&gt;. Thirty-year-old theory that
authors of allocators, kernels and network packet schedulers have since
reinvented more or less independently. TLSF from 2004 has a first- and
second-level index, an exponent and a mantissa, and the Vulkan Memory
Allocator uses it today with five mantissa bits, 32 classes per power
of two.&lt;/p&gt;
&lt;p&gt;I noted two things. That I was not thinking wrong, only thirty years
late. And that it pays to search before naming the thing.&lt;/p&gt;
&lt;h2 id=&quot;so&quot;&gt;So&lt;/h2&gt;
&lt;p&gt;An offset allocator is a float and two bitmaps. The float squeezes a
huge range of sizes into a few hundred classes with an error of at
most a sixteenth, the bitmap turns &quot;find the nearest non-empty class&quot;
into two instructions, neighbour links turn merging into two
comparisons, and doubly linked lists keep it O(1) in a full class.
Nothing is searched, everything is computed. A single character in the
bitmap query, &quot;successor or equal&quot; instead of &quot;successor&quot;, decides
whether memory crumbles under load. And the fastest list operation is
the one that does not happen.&lt;/p&gt;
&lt;h2 id=&quot;method&quot;&gt;Method&lt;/h2&gt;
&lt;p&gt;Times are from a laptop with criterion, median of three runs that
agree within 1 %; the ratios matter, not the microseconds. Each
implementation keeps one allocator, reset between iterations outside
the timing. Allocation sizes come from a xorshift with a fixed seed,
the same for both implementations. The cost of individual changes:
&lt;code&gt;perf stat&lt;/code&gt; (instructions, cycles, mispredictions) and &lt;code&gt;perf annotate&lt;/code&gt;,
A/B only within one binary. The timer wheel against &lt;code&gt;BinaryHeap&lt;/code&gt;:
100,000 timers, dense distribution, 6 ns against 46 ns per operation.
Dijkstra: an N × N grid with four neighbours, edge weights uniform in
1 to W, shortest paths from a corner, all queues must produce the same
distances; &quot;dense&quot; means W ≤ 200, &quot;sparse&quot; W ≥ 500.&lt;/p&gt;
&lt;p&gt;Long workload (&lt;code&gt;examples/rd_first_churn.rs&lt;/code&gt; in holeinone): a million
operations, log-uniform sizes, target occupancy 90 %, a failure frees a
random allocation; percentages are the mean over three seeds. The best
fit for comparison is an exact allocator over a tree of free ranges in
a simplified simulation. Worst case of singly linked lists: n blocks of
64 B, free the odd ones, time freeing the even ones.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>First post, delivered late by a router</title>
        <published>2026-10-04T00:00:00+00:00</published>
        <updated>2026-10-04T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://panacan.xyz/blog/hello/"/>
        <id>https://panacan.xyz/blog/hello/</id>
        
        <content type="html" xml:base="https://panacan.xyz/blog/hello/">&lt;p&gt;This is the first post. Before it existed, the site already had a static
generator, a search index, a WebAssembly build, a Nix flake, a web server and
an SNI router in front of it. I would read that ordering less as an accident
and more as a fairly accurate portrait of the author.&lt;/p&gt;
&lt;h2 id=&quot;who-writes-here&quot;&gt;Who writes here&lt;/h2&gt;
&lt;p&gt;By day I tune SQL in old ERP systems, the kind full of well-meant
integrations: queries that ran fine for ten years, until a consultant and a
developer had an idea. I was hired to do analytics on a data warehouse; the
performance work found me anyway.&lt;/p&gt;
&lt;p&gt;By night it is algebra, discrete math and bit tricks, mostly in Rust, and
further down than is reasonable, which lately means compilers. The handle is
&lt;code&gt;might_sleep()&lt;/code&gt;, the kernel&#39;s annotation for a function that may sleep: call
it from the wrong context and you get a warning. Given the hours, it fit.&lt;/p&gt;
&lt;p&gt;These days most of the night shift ends up in the Rust data stack, arrow-rs,
DataFusion and Vortex, because that is where the two shifts meet: the day
job is databases, the night is bit tricks, and a columnar engine is mostly
bit tricks pretending to be a database. A few small patches of mine got
merged there. The rest went into &lt;a rel=&quot;external&quot; href=&quot;https://crates.io/crates/hakmem&quot;&gt;hakmem&lt;/a&gt;,
a crate that tries to treat bit tricks as an algebra with laws instead of a
bag of one-line spells, named after a 1972 MIT memo it will never live up
to, and into a Vulkan renderer whose geometry pass has been &quot;almost working&quot;
for long enough to count as a research topic.&lt;/p&gt;
&lt;p&gt;The pattern, if you squint: a weakness for problems that look serial but hide
an algebra. A scan that is secretly a monoid. A predicate that is secretly a
truth table. A curve that is secretly a Gray code.&lt;/p&gt;
&lt;h2 id=&quot;what-you-will-find&quot;&gt;What you will find&lt;/h2&gt;
&lt;p&gt;Short posts about such things, each with code and, where it helps, a demo that
runs right in the page. Rust, C, occasional trace amounts of functional
programming and good database design (usually by accident).&lt;/p&gt;
&lt;p&gt;Measurements will always come with the method, because designing it is
sometimes more interesting than the speedup itself. Some posts will admit that
an idea turned out slower. Those are the ones you learn the most from, and
let&#39;s be honest, they are not exactly a thrilling read for most normal people.&lt;/p&gt;
&lt;p&gt;Posting schedule: yes.&lt;/p&gt;
&lt;h2 id=&quot;tech-stack&quot;&gt;Tech stack&lt;/h2&gt;
&lt;p&gt;Zola renders Markdown, Pagefind builds a search index that runs entirely in
your browser, and each demo is a small Rust crate built with &lt;code&gt;wasm-bindgen&lt;/code&gt;.
One Nix derivation turns all of it into a directory, and a deploy is a new
directory plus a flipped pointer.&lt;/p&gt;
&lt;p&gt;It is served by Ferron, a web server written in Rust, from a small container
at vpsFree. In front of it sits a router I wrote over this weekend: it reads
the TLS ClientHello, looks at the server name and forwards the connection
without decrypting anything. About four hundred lines, plus two hundred and
fifty lines of tests, which took most of the time.&lt;/p&gt;
&lt;p&gt;Below is roughly the first thing your browser sent to get this page, built in
Rust and checked against the router&#39;s own parser, compiled to WebAssembly. Type
another name, split the hello across more records, or press send and watch
the bytes arrive the way TCP delivers them. The router never decrypts
anything; it follows a few lengths, skips everything else, and only answers
once the whole message is in.&lt;/p&gt;
&lt;figure class=&quot;demo&quot; data-demo=&quot;sni&quot;&gt;
  &lt;canvas aria-label=&quot;A TLS 1.3 ClientHello as the router sees it. The parser is the router&#39;s, byte for byte.&quot;&gt;&lt;/canvas&gt;
  &lt;noscript&gt;This demo needs JavaScript and WebAssembly.&lt;/noscript&gt;
  &lt;figcaption&gt;A TLS 1.3 ClientHello as the router sees it. The parser is the router&#39;s, byte for byte.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;script type=&quot;module&quot; src=&quot;https://panacan.xyz/demos/sni/main.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;what-broke-on-the-way&quot;&gt;What broke on the way&lt;/h2&gt;
&lt;p&gt;The ordering in the first paragraph has a price, and it is only fair to list
it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The certificate that renewed itself into the void.&lt;/strong&gt; The domain has two DNS
views: Cloudflare answers the public internet, and a resolver of my own answers
inside a private network, with records nobody outside should see. Let&#39;s
Encrypt checks ownership through a TXT record that only Cloudflare holds. The
ACME client then waited for that record to propagate by asking the system
resolver, which was my own one, which is authoritative for the domain and has
never heard of the record. Renewal became a lottery, and on 21 September the
lottery lost. The fix is one line telling it to ask 1.1.1.1. Split-horizon DNS
is a fine idea right until something needs to see both horizons.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The resolver.&lt;/strong&gt; The same box runs Hickory as a recursive resolver, validating
DNSSEC from the root down. Version 0.26.3 had three bugs that all showed up in
one evening: a validation loop on unsigned delegations, answers with the
address before the CNAME that leads to it, and a validator that shuffled the
answer again through a &lt;code&gt;HashSet&lt;/code&gt; even after the second bug was patched. glibc
reads the chain in order and gives up, so about a quarter of lookups for
&lt;code&gt;cache.nixos.org&lt;/code&gt; ended in &quot;Could not resolve host&quot;. I spent half a day
patching 0.26 before checking that main had already fixed all three. It now
runs a pinned commit from main, which is not a sentence I expected to write
about a DNS server.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The ghost on port 443.&lt;/strong&gt; Before the web server, &lt;code&gt;tailscale serve&lt;/code&gt; exposed a
dashboard. I deleted the systemd unit that set it up, and the web server
refused to start: address already in use. The serve config lives in
tailscaled&#39;s own state, not in the unit, and outlives it. &lt;code&gt;tailscale serve reset&lt;/code&gt;. Declarative configuration, meet the one imperative command that
remembers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The router I almost misconfigured.&lt;/strong&gt; The plan was simple: the router reads
SNI, sends one name to another service and everything else to the existing web
server. But that web server picks a virtual host by the HTTP &lt;code&gt;Host&lt;/code&gt; header,
not by SNI. A client could say &quot;public site&quot; in the handshake and &quot;internal
dashboard&quot; in the request, and get the dashboard from the internet. Domain
fronting, self-hosted. The public site therefore gets its own web server
instance that knows only public hosts.&lt;/p&gt;
&lt;p&gt;Each of these ended as a one-line fix and a comment three times longer than
the fix. That ratio is probably the most honest metric on this site.&lt;/p&gt;
&lt;h2 id=&quot;feedback&quot;&gt;Feedback&lt;/h2&gt;
&lt;p&gt;If something here is wrong, slow, or already in a 1972 memo, I want to know.
GitHub: &lt;a rel=&quot;external&quot; href=&quot;https://github.com/mightsleep&quot;&gt;mightsleep&lt;/a&gt;, email:
&lt;a href=&quot;mailto:acannix@proton.me&quot;&gt;acannix@proton.me&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
</feed>
