<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pure/benchmarks/http, branch master</title>
<subtitle>Verified execution runtime unifying state, persistence, and replication.
</subtitle>
<id>http://git.yeowoo.org/pure/atom?h=master</id>
<link rel='self' href='http://git.yeowoo.org/pure/atom?h=master'/>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/'/>
<updated>2026-10-18T18:30:16Z</updated>
<entry>
<title>Module format v7, 027's 4b-2: keyed documents gone, a keyed list of records holding bytes doing their work: no collections table, DOC, DOC_SIZE or REPLACE (106 opcodes now 103, those from LEN on moved up), keyed messages or a base revision (pure_app_message takes an input and a payload), no PureData document callbacks (a data host opens states and saves them together), no burst by document key; the header 38 bytes; pure-edit-module gone; pure-serve without /objects, ETag, If-Match and If-None-Match, 412 or an app a thread for a module of documents alone (one without states or outputs runs so); a hole closed: an instruction in no handler's, view's or function's block was never verified yet the load's later passes read its arguments (a damaged module read out of bounds once the header moved what the mutation test damaged), now blanked to CONST 0; checks moved: server_documents (DOCS_SOURCE, keyed byte documents with the app's revision, against a Python model, one and three connection threads, a restart) in place of the parity with editor.pure, pipelining and bursts through kill -9 on its inputs and views, the lent budget on a text view (lending a document's read is server_lent_views' already), clocks and tokens on it; message tests without a document host; the HTTP benchmark's document suite runs the earlier document server and the baselines alone; the count harness builds against either message API (runs.sh build: -DPURE_KEYED_MESSAGES before 4b); counts: b33 against b32 with batches within 0.002% but BFS -0.33%, without batches BFS +0.63%, knapsack +0.52%, join +0.38%; the bank's queries (s32 on a v6 module, s33 on v7) field +0.68%, found +0.44%, large +0.42%, the rest within 0.13%; 008 as v7, 027's 4b-2 as made and 4c designed</title>
<updated>2026-10-18T18:30:16Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-18T18:30:16Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=b22b8c3f6c5378b47c36370225d7c41d4394bb7c'/>
<id>urn:sha1:b22b8c3f6c5378b47c36370225d7c41d4394bb7c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Watch a subscriber for writing only while it keeps output, and measure freshness by push and polling (019)</title>
<updated>2026-10-04T14:36:51Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-04T14:36:51Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=90c8edece941f26cd280686c7063a7c9149a2212'/>
<id>urn:sha1:90c8edece941f26cd280686c7063a7c9149a2212</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Take an app's requests only with a token its tokens file grants (017, 3b)</title>
<updated>2026-10-04T11:46:34Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-04T11:46:34Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6'/>
<id>urn:sha1:9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6</id>
<content type='text'>
An app given a tokens file (tokens=FILE in --apps, --tokens FILE for the
one app of a host) answers a request only when it bears a token
(Authorization: Bearer) whose SHA-256 the file lists with a grant: read
for its views, queries and documents, write for all, input=NAME for
those inputs alone; 401 unauthorized (WWW-Authenticate: Bearer) without
one, 403 forbidden past its grant. A delivery sealed by a key --sender
names needs none. The digests are compared in constant time; a
connection keeps its last token's digest, so the same token is hashed
once. SHA-256 is the host's own (serve/sha256.c), no OpenSSL loaded. A
reading puts a changed tokens file in place with the app running on; a
file that is not one stops the app. pure-serve --make-token GRANT makes
a token and its line. load takes PURE_LOAD_TOKEN.
</content>
</entry>
<entry>
<title>Let the load tool put an app's name before its paths</title>
<updated>2026-10-01T02:23:27Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-01T02:23:27Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=a0840d6ebfcc6d992d60d119fb596cf76d54c7cc'/>
<id>urn:sha1:a0840d6ebfcc6d992d60d119fb596cf76d54c7cc</id>
<content type='text'>
load takes a ninth argument, PREFIX, put before every path: /NAME for
an app of a host of apps (pure-serve --apps, 017). Without it, as
before.
</content>
</entry>
<entry>
<title>Run pgbench's transaction on a bank of 100,000 accounts, beside SQLite (090)</title>
<updated>2026-09-27T22:39:29Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T22:39:29Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=44740eb93a69a052ee7b4c46f2ccac384c9d4f36'/>
<id>urn:sha1:44740eb93a69a052ee7b4c46f2ccac384c9d4f36</id>
<content type='text'>
benchmarks/bank/bank.aup keeps accounts, tellers and branches as keyed
lists and a history list; a transfer changes a row of each and appends a
history row in one event, as pgbench's TPC-B-like transaction does in
SQL. run.py makes a scale's rows and drives transfers through the load
generator's new transfer kind; sqlite-bank.c runs the same tables and
SQL on SQLite 3.46.1, a connection a thread, WAL.

With lists as trees, transfers run at 30.5k a second on 1,000 accounts
and 24.5k on 100,000 (RAM store, one connection thread, HTTP and JSON
included), where they ran at 3.2k on 30,000 before. Durable on the SD
card, Pure makes 1,339 a second and SQLite with synchronous=FULL 84 to
153. SQLite in process with no HTTP makes about 40k in RAM: recorded as
it is, with the write amplification of 100,000-row tables on the card
and ad hoc queries as what comes next.
</content>
</entry>
<entry>
<title>Add a sampling profiler for machines without perf</title>
<updated>2026-09-27T17:47:05Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T17:47:05Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=76f5edb2bcc227c2be743873753792dbc5af1f48'/>
<id>urn:sha1:76f5edb2bcc227c2be743873753792dbc5af1f48</id>
<content type='text'>
benchmarks/sample.c runs a command and samples where its threads spend
user time (the task clock every 50 us, one perf_event_open event a CPU,
since the kernel maps no ring for an inherited per-task event), then
names the samples from the ELF symbol tables of the files the command had
mapped: a stripped library from its debug file by build id. On arm64 it
also takes the link register, so time in a library's leaf (memcpy,
strcmp) is shown again by its caller. The command's user and system time
head the report.

</content>
</entry>
<entry>
<title>Show the new layout costs nothing, and keep code where it was</title>
<updated>2026-09-27T12:43:49Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T12:43:49Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=628e72621693af9be8bf94ef42f3164c45763a7b'/>
<id>urn:sha1:628e72621693af9be8bf94ef42f3164c45763a7b</id>
<content type='text'>
The benchmark runs an earlier pure-serve build in turn with the current one
(--baseline). Against the build before the move, linking through libpure.a
costs nothing: a one-command build with the library's object order has the
same size and the same CPU per request. What moved was code placement, so
the runtime links last again, as it did; the two orders now differ by less
than rounds of one build do (total -0.4%, page +1.2%, mixed -0.1%). The
binary is 5,008 B smaller: unused flow.c functions stay in the library, and
the linker's A53 erratum padding is gone.

</content>
</entry>
<entry>
<title>Lay Pure out as a core with the parts selected around it</title>
<updated>2026-09-27T12:14:38Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T12:14:38Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=37d3a1e152707d2da587440c4cea8601b9ef0fd2'/>
<id>urn:sha1:37d3a1e152707d2da587440c4cea8601b9ef0fd2</id>
<content type='text'>
The app model, the tree store and the HTTP host lived in
prototypes/connections among the earlier document runtime, the store was
known only by its format's name, and Vega compiled six Pure sources by path.
Now, as the README's principle has it:

  core/   runtime, flow and the app model (module*.c), with what the core
          asks of storage (state.h, store.h)
  store/  the tree store (PURETRE3, PUREREC1)
  serve/  pure-serve: HTTP host, outbound delivery, JSON in place
  cli/    pure-run, pure-edit-module

A top-level make builds libpure.a (app model and store, for hosts to link)
and the hosts; make check runs the store's and the app model's tests. The
earlier runtime still builds from prototypes/connections against core/ and
store/ (check, check-tree and check-core pass). Design 009 records the rule:
parts by role behind libraries; git repositories split by coupling, so the
store stays here while its contract moves with the core, and Vega stays apart.

</content>
</entry>
<entry>
<title>Read JSON bodies in place, groups included (082)</title>
<updated>2026-09-27T06:30:51Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T06:30:51Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=eb37aad3ae7f9df1d6c0b09108e3a2d69d0d4d82'/>
<id>urn:sha1:eb37aad3ae7f9df1d6c0b09108e3a2d69d0d4d82</id>
<content type='text'>
pure-serve no longer copies a JSON body's strings into the message's
payload. The ingress is the prefix, a table of each field's start and
size, and the body as it came; the connection thread scans the body
once, puts numbers into the prefix and records where each string is.
Only a string with escapes is unescaped, over itself (it never grows).
A group of fields comes as an object inside the body and, for a fixed
field, as its path in the query (?to.zip=7). A group where a field
belongs, a value where a group does, an array or true/false/null is
json_type; an unknown member, inside a group too, json_field.

The string scan and UTF-8 checks now pass over eight bytes at a time
while none needs a look (pure_utf8_step, so every text check gains).
On the Pi, posting {"name":"k","text":"x..."} to a stateless app went
from 652-655 to 3,737-3,953 requests/s with 256 KiB of text (server
CPU 1.52 to 0.25 ms a request, peak RSS 5.2 to 3.2-3.4 MiB) and from
29.1k to 76.3-76.7k/s with 4 KiB; the load generator gains a json
method and benchmarks/http/echo.aup is the app.

</content>
</entry>
<entry>
<title>Show views from the last save's snapshot on connection threads (080)</title>
<updated>2026-09-26T21:56:47Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T21:56:47Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=a51232af741cb952d7deb72f238c583919ababc0'/>
<id>urn:sha1:a51232af741cb952d7deb72f238c583919ababc0</id>
<content type='text'>
The owner publishes a snapshot of the saved states after every save,
before it hands back the answers; connection threads take the newest
one each round and show views from it with a reader app of their own.
A read made after a write's answer sees the write, nothing unsaved or
undone is ever shown, and reads no longer wait while the owner applies
events or syncs. Apps with states always get an owner thread, even
with one connection thread. A round's inputs go to the owner first;
its views are shown and then answered together (answering each one as
it was shown made one thread's 20-row page 8% slower).

On the Pi 5, with 8 connections posting durable scores and 56 reading
the total, reads went from 10-16k/s at p99 13-29 ms to 107-149k/s at
p99 0.6-0.7 ms, and posts stayed in range; axum and drogon, which sync
under their lock, read 1.1-1.3k/s at p99 111-156 ms. A snapshot of a
changed 1,024-item list costs 1.2 us (65,536 items: 87 us) against a
3-4 ms save.

</content>
</entry>
</feed>
