Skip to content

Commit c50adf6

Browse files
committed
docs: add consolidated project documentation
1 parent 2ec089f commit c50adf6

6 files changed

Lines changed: 1660 additions & 5 deletions

File tree

META.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"provides": {
1919
"acdat": {
2020
"file": "sql/acdat--0.2.0.sql",
21-
"docfile": "docs/usage.md",
21+
"docfile": "docs/USAGE.md",
2222
"version": "0.2.0",
2323
"abstract": "Compiled multi-pattern matching for PostgreSQL"
2424
}

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,10 @@ verification remain release gates.
185185

186186
Documentation:
187187

188-
- [Usage guide](docs/usage.md)
189-
- [Performance report](docs/performance-2026-08-24.md)
188+
- [Usage guide](docs/USAGE.md)
189+
- [Performance report](docs/PERFORMANCE.md)
190190
- [Benchmark notes](docs/BENCHMARK.md)
191191
- [Changelog](docs/CHANGELOG.md)
192-
- [Version 0.2.0 design](docs/v0.2.0.md)
193-
- [Product and machine-format contract](PRD.md)
194192

195193
A runnable end-to-end example is available at [examples/demo.sql](examples/demo.sql):
196194

docs/BENCHMARK.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# acdat benchmark notes
2+
3+
The comprehensive real-corpus Go-versus-PostgreSQL report for the current
4+
Apple M5 Max test host is recorded in
5+
[`PERFORMANCE.md`](PERFORMANCE.md).
6+
7+
## 2026-08-24: v0.2.0 benchmark-gated changes
8+
9+
Environment:
10+
11+
- Apple arm64, Apple clang 21.0.0
12+
- `-O3 -DNDEBUG`
13+
- 16 MiB deterministic input per scan
14+
- three runs per cell; table values are medians
15+
- materialized format-major-1 runtime, matching the PostgreSQL cache path
16+
17+
Command:
18+
19+
```bash
20+
BENCH_REPEATS=3 BENCH_INPUT_MIB=16 make bench-matrix
21+
```
22+
23+
The comparison baseline was captured with the expanded benchmark immediately
24+
before the v0.2.0 core changes. The workload generator and compiler settings
25+
were otherwise identical.
26+
27+
| 100K profile | v0.1 build | v0.2 build | v0.1 scan | v0.2 scan |
28+
|---|---:|---:|---:|---:|
29+
| ASCII miss | 0.280 s | 0.116 s | 59.97 MiB/s | 64.80 MiB/s |
30+
| Root-only miss | 0.278 s | 0.077 s | 449.67 MiB/s | 936.06 MiB/s |
31+
| ASCII hit-heavy | 0.278 s | 0.115 s | 226.42 MiB/s | 402.27 MiB/s |
32+
| UTF-8 byte miss | 19.269 s | 0.109 s | 485.55 MiB/s | 928.29 MiB/s |
33+
34+
The UTF-8 build regression was caused by globally unique BASE values, a
35+
constraint needed by label-only Compact CHECK but not by acdat's parent-state
36+
Basic CHECK. Removing the constraint reduced the 100K UTF-8 base search to
37+
1,206,195 candidates, produced 1,303,302 slots for 1,303,082 states, and
38+
removed the `used_base` builder array. This simple change was sufficient; a
39+
free-list, XOR placement, and tail fallback were not added.
40+
41+
The runtime output-chain preparation retains the format-major-1 artifact but
42+
releases the materialized `output_link` array. At 100K ASCII patterns, runtime
43+
bytes fell from 31,051,372 to 25,095,160 (19.2%). Artifact bytes also fell from
44+
31,051,452 to 30,367,716 because the relaxed BASE placement produced fewer
45+
vacant slots. A 1 KiB root transition table accounts for the small fixed
46+
runtime overhead.
47+
48+
Two paper-derived experiments were rejected and removed:
49+
50+
- LexDFS improved build time and the hit-heavy scan, but slowed the primary
51+
100K ASCII-miss workload by about 60% and did not consistently improve the
52+
UTF-8 miss workload. LexBFS remains the only placement path.
53+
- Packed array-of-struct runtime states improved some large-machine cells but
54+
regressed a 1K machine by roughly 25%, slightly regressed the root-only cell,
55+
and added a second full materialization copy. The single SoA runtime remains.
56+
57+
PostgreSQL 18.4, 100K generated `pattern-NNNNNNNN` rules, and one million
58+
short root-miss rows completed in a median 127.54 ms over three warm runs. The
59+
corresponding v0.1.0 note below recorded 275 ms. This is a PostgreSQL
60+
end-to-end measurement including function-call and executor overhead, not just
61+
the standalone scanner.
62+
63+
These are local engineering results, not cross-platform release claims. Linux
64+
amd64/arm64, PostgreSQL short-row, parallel-worker, and package-lab results
65+
remain separate release gates.
66+
67+
## 2026-08-22: byte256 ACDAT baseline
68+
69+
Environment:
70+
71+
- Apple arm64, Apple clang 21.0.0
72+
- `-O3 -DNDEBUG`
73+
- Synthetic deterministic lowercase patterns, 16 bytes each
74+
- Deterministic lowercase random no-hit input
75+
76+
Command:
77+
78+
```bash
79+
PATTERNS=100000 PATTERN_BYTES=16 INPUT_MIB=16 make core-bench
80+
```
81+
82+
Results after the next-check-position density optimization:
83+
84+
| Patterns | States | DAT slots | Occupancy | Artifact | Build | Scan |
85+
|---:|---:|---:|---:|---:|---:|---:|
86+
| 10,000 | 140,703 | 144,561 | 97.3% | 3.29 MB | 0.023 s | 88 MiB/s |
87+
| 100,000 | 1,318,279 | 1,356,597 | 97.2% | 31.13 MB | 0.271 s | 65 MiB/s |
88+
89+
The pre-optimization 10K build took 5.5 seconds, and the 100K build did not
90+
finish within 150 seconds. The improvement comes from advancing the global
91+
base-search cursor when the scanned check-array window is at least 95% full,
92+
instead of repeatedly scanning isolated early holes.
93+
94+
These are engineering baselines, not release claims. Follow-up benchmarks must
95+
include real Chinese/URL/IOC dictionaries, hit-heavy and overlap-heavy inputs,
96+
cold/warm TOAST, PostgreSQL per-row overhead, parallel workers, and a packed or
97+
sparse AC comparator.
98+
99+
## 2026-08-22: PostgreSQL wrapper and TOAST cache
100+
101+
PostgreSQL 18.4, local temporary table, 100K generated text patterns:
102+
103+
- In-database aggregate compile + serialize: 86 ms
104+
- Artifact: 6.22 MB, 111,127 states, 111,205 slots
105+
- 1,000,000 short no-hit rows through one function expression: 275 ms
106+
107+
The first implementation called `PG_GETARG_VARLENA_PP` before checking
108+
`fn_extra`; a 6.22 MB out-of-line value was therefore detoasted once per row and
109+
the same query ran for more than four minutes before cancellation. The fixed
110+
path compares the small on-disk TOAST pointer first and detoasts, validates, and
111+
materializes only when the build changes. This cache behavior is a release
112+
correctness/performance invariant and has dedicated regression/benchmark
113+
coverage.
114+
115+
## 2026-08-22: historical Chinese dictionary
116+
117+
The original repository's `dict.txt` contains 1,114 Chinese movie/music
118+
patterns. PostgreSQL 18.4 results:
119+
120+
- Aggregate compile + serialize: 5.4 ms
121+
- 10,840 states / 11,357 DAT slots (95.4% occupancy)
122+
- Artifact: 283,074 bytes, including 11,182 replacement bytes
123+
- Maximum pattern: 40 UTF-8 bytes / 14 characters
124+
- 100,000 short hit-heavy rows through `acdat.contains`: 22.2 ms
125+
126+
This confirms exact UTF-8 byte matching on the historical workload, but it is
127+
far smaller than the 100K target and does not replace a modern real-world CJK
128+
corpus benchmark.

docs/CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Changelog
2+
3+
## 0.2.0 - 2026-08-24
4+
5+
- Removed the unnecessary globally unique BASE constraint from the Basic
6+
parent-state CHECK builder, eliminating pathological UTF-8 dictionary build
7+
searches while improving DAT occupancy and reducing builder memory.
8+
- Added cancellable PostgreSQL compilation, a base-candidate safety budget,
9+
and standalone build-work metrics.
10+
- Added a materialized runtime output chain that releases one four-byte array
11+
per DAT slot without changing the format-major-1 artifact.
12+
- Added a 256-entry root transition table for low-hit and root-miss scans.
13+
- Made machine-cache replacement exception-safe and made serialization reject
14+
runtime-prepared automata explicitly.
15+
- Expanded the standalone benchmark with ASCII miss, root miss, hit-heavy,
16+
UTF-8 byte-oriented, and worst-overlap profiles plus materialization and
17+
runtime-memory measurements.
18+
- Evaluated and rejected Packed runtime states and LexDFS placement because
19+
their workload-specific wins did not justify permanent selection complexity.
20+
- Preserved the 0.1.0 SQL API and machine format, with an extension update path
21+
to 0.2.0.
22+
23+
## 0.1.0 - 2026-08-22
24+
25+
- Rebuilt the original ACDAT experiment as a C and PGXS PostgreSQL extension.
26+
- Added deterministic `text` and `bytea` dictionary compilation.
27+
- Added `contains`, `matches`, `replace`, machine inspection, validation,
28+
import, export, and fingerprint APIs.
29+
- Added immutable dictionary builds with transactional publish, activate,
30+
rollback, and retirement workflows in the fixed `acdat` schema.
31+
- Added PostgreSQL 14-18 regression, sanitizer, dump/restore, cache, and
32+
cross-version tests.
33+
- Added a detailed usage guide, runnable SQL demonstration, and performance
34+
baselines.

0 commit comments

Comments
 (0)