#!/usr/bin/env python3 """Build, independently verify, and measure the retention experiment.""" import argparse import csv import hashlib import json import os from pathlib import Path import platform import random import shlex import signal import statistics import struct import subprocess import tempfile import time ROOT = Path(__file__).resolve().parent FLAGS = ["-std=c17", "-Wall", "-Wextra", "-Wpedantic", "-Werror", "-O2", "-g"] def digest(path): with open(path, "rb") as stream: return hashlib.file_digest(stream, "sha256").hexdigest() def dump(path, value): path.write_text(json.dumps(value, indent=2, ensure_ascii=False) + "\n") def build(cc, output, sanitizer=False): command = [*cc, *FLAGS] if sanitizer: command += ["-fsanitize=address,undefined", "-fno-omit-frame-pointer"] command += [str(ROOT / "benchmark.c"), "-o", str(output)] result = subprocess.run(command, capture_output=True, text=True, check=True) return {"command": command, "stderr": result.stderr, "sha256": digest(output), "size_bytes": output.stat().st_size} def shape_for(shape, rng, i): if shape == "sparse": return 65536, 64 if shape == "dense": return 65536, 49152 if shape == "mixed": source = rng.choice([4096, 16384, 65536, 262144]) keep = max(16, source // rng.choice([1, 2, 4, 8, 64, 1024])) return source, keep if shape == "test": return [(1, 1), (63, 17), (4097, 12), (65536, 49152), (127, 127)][i % 5] raise ValueError(shape) def fixture(path, shape, count, seed): rng = random.Random(seed) expected = hashlib.sha256() total = 0 with path.open("wb") as stream: for i in range(count): size, keep = shape_for(shape, rng, i) offset = rng.randrange(size - keep + 1) # All input bytes exist on disk; no sparse files or seeking past data. tile = rng.randbytes(256) payload = (tile * ((size + 255) // 256))[:size] stream.write(struct.pack(" size - keep: raise ValueError("invalid frame") if len(data) - at < size: raise ValueError("short payload") result.extend(struct.pack("