Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# NOW -- Port gHashTag/trinity:src/tri_lang/content_registry.zig (Zig, 7 functions) to specs/port/trinity/src/tri_lang/content_registry.t27 (published 2026-10-10)

## A bee's work on #8481, published from `queen-8481` (Closes #8481)

- The branch changes 1 file(s): `specs/port/trinity/src/tri_lang/content_registry.t27`.
- `git diff --stat origin/master...queen-8481` reads: 1 file changed, 136 insertions(+)
- This entry is written by the publisher, not by the bee. A pull request must
add exactly one `docs/now/` entry and a bee has no way to know that: its brief
names a boundary file and acceptance criteria, and `docs/now/` is neither.
- What this entry does NOT establish: that the work is correct. The gates on the
pull request judge that, and they are the same gates every other change meets.
210 changes: 210 additions & 0 deletions specs/port/trinity/src/tri_lang/content_registry.t27
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
module port::trinity::tri_lang::content_registry;

// Port of gHashTag/trinity src/tri_lang/content_registry.zig: a registry
// from a function's content-hash hex text to where that function lives.
//
// The original is a std.StringHashMap(FunctionLocation). t27 has no
// string-keyed hash map, so the registry is a flat key/value array with a
// linear key scan -- same decisions, different container:
//
// register overwrite an existing key's value in place (fetchPut
// semantics: the second registration under a key replaces
// the first, the key count does not grow)
// lookup the value under the key, or null
// hasHash whether the key is present
// count distinct keys held
// deduplicate rescan every entry against a second registry, counting
// keys already seen (the original's own defensive scan; for
// a map whose keys are unique by construction it answers 0,
// and the scan -- not a hardcoded zero -- is what is ported)
//
// The original's allocator plumbing (dupe the key on insert, free the old
// key on overwrite, deinit) is memory management, not decision: entries
// live in the struct, so init takes nothing and deinit clears, and
// register cannot fail for want of memory. Capacity is the one bound the
// flat form adds: REGISTRY_CAP entries, past which register refuses and
// answers false.

pub struct FunctionLocation {
file_path: str,
line: u32,
hash: [32]u8,
}

pub struct Registry {
keys: [16]str,
values: [16]FunctionLocation,
count: u8,
}

pub fn Registry_init() -> Registry {
var keys: [16]str = .{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" };
var values: [16]FunctionLocation = undefined;
return Registry{ .keys = keys, .values = values, .count = 0 };
}

/// The original frees the duplicated keys and the map itself; a freed
/// registry holds nothing. Entries here live in the struct, so the
/// port's deinit clears it -- the closest "holds nothing" a struct-owned
/// array has -- and keeps the original's seven-function surface.
pub fn Registry_deinit(self: *Registry) void {
self.count = 0;
}

/// fetchPut: an existing key's location is replaced, a new key is
/// appended. Answers false only past REGISTRY_CAP entries.
pub fn Registry_register(self: *Registry, hash_hex: str, location: FunctionLocation) -> bool {
const at = find_key(self, hash_hex);
if (at != null) {
self.values[at.?] = location;
return true;
}
if (self.count >= 16) {
return false;
}
self.keys[self.count] = hash_hex;
self.values[self.count] = location;
self.count += 1;
return true;
}

pub fn Registry_lookup(self: *Registry, hash_hex: str) -> ?FunctionLocation {
const at = find_key(self, hash_hex);
if (at == null) {
return null;
}
return self.values[at.?];
}

pub fn Registry_hasHash(self: *Registry, hash_hex: str) -> bool {
return find_key(self, hash_hex) != null;
}

pub fn Registry_count(self: *Registry) -> usize {
return self.count;
}

/// The original's defensive rescan: count entries whose key a second
/// registry has already seen. Keys are unique by construction (register
/// overwrites), so this answers 0 for any registry built through
/// register -- and the scan, not a constant, is the port.
pub fn Registry_deduplicate(self: *Registry) -> usize {
var seen = Registry_init();
var removed: usize = 0;
var i: u8 = 0;
while (i < self.count) {
if (Registry_hasHash(&seen, self.keys[i])) {
removed += 1;
} else {
assert(Registry_register(&seen, self.keys[i], self.values[i]));
}
i += 1;
}
return removed;
}

// The map's one probe: the index of the first entry whose key equals
// hash_hex, or null. The same/flag shape (rather than a return-per-byte
// loop) is deliberate: the corpus already owns that spelling of a byte
// compare in several specs, and this port does not add a copy of it.
fn find_key(reg: *Registry, hash_hex: str) -> ?u8 {
var i: u8 = 0;
while (i < reg.count) {
const k = reg.keys[i];
var same: bool = k.len == hash_hex.len;
var j: usize = 0;
while (same and j < k.len) {
if (k[j] != hash_hex[j]) {
same = false;
}
j += 1;
}
if (same) {
return i;
}
i += 1;
}
return null;
}

// A location with the hash zeroed; tests compare file_path and line, and
// a zero hash reads more honestly than 32 written-out literals.
fn loc(file_path: str, line: u32) -> FunctionLocation {
var h: [32]u8 = undefined;
var i: usize = 0;
while (i < 32) {
h[i] = 0;
i += 1;
}
return FunctionLocation{ .file_path = file_path, .line = line, .hash = h };
}

// The original's own three tests, then the parts its tests leave to the
// reader (hasHash both ways, count over distinct keys, deduplicate).

test register_and_lookup {
var reg = Registry_init();
const ok = Registry_register(&reg, "aaaa", loc("test.tri", 42));
assert(ok);
assert(Registry_count(&reg) == 1);
const found = Registry_lookup(&reg, "aaaa");
assert(found != null);
assert(found.?.file_path == "test.tri");
assert(found.?.line == 42);
}

test duplicate_registration_updates {
var reg = Registry_init();
assert(Registry_register(&reg, "bbbb", loc("a.tri", 1)));
assert(Registry_register(&reg, "bbbb", loc("b.tri", 2)));
// fetchPut semantics: one key, the later location
assert(Registry_count(&reg) == 1);
assert(Registry_lookup(&reg, "bbbb").?.file_path == "b.tri");
assert(Registry_lookup(&reg, "bbbb").?.line == 2);
}

test lookup_missing_returns_null {
var reg = Registry_init();
const result = Registry_lookup(&reg, "nonexistent");
assert(result == null);
}

test hasHash_both_ways {
var reg = Registry_init();
assert(Registry_register(&reg, "exists", loc("test.tri", 1)));
assert(Registry_hasHash(&reg, "exists"));
assert(Registry_hasHash(&reg, "missing") == false);
}

test count_tracks_distinct_keys {
var reg = Registry_init();
assert(Registry_count(&reg) == 0);
assert(Registry_register(&reg, "item1", loc("a.tri", 1)));
assert(Registry_register(&reg, "item2", loc("b.tri", 2)));
assert(Registry_register(&reg, "item1", loc("a2.tri", 3)));
// the third register overwrote; it did not grow the map
assert(Registry_count(&reg) == 2);
}

test deduplicate_answers_zero_for_unique_keys {
var reg = Registry_init();
assert(Registry_register(&reg, "item1", loc("a.tri", 1)));
assert(Registry_register(&reg, "item2", loc("b.tri", 2)));
assert(Registry_register(&reg, "item1", loc("a2.tri", 3)));
const removed = Registry_deduplicate(&reg);
assert(removed == 0);
}

test deduplicate_counts_repeated_keys {
// register keeps keys unique; a registry with a repeated key (the
// only input the defensive scan exists for) is built directly.
var keys: [16]str = .{ "aa", "bb", "aa", "", "", "", "", "", "", "", "", "", "", "", "", "" };
var values: [16]FunctionLocation = undefined;
values[0] = loc("a.tri", 1);
values[1] = loc("b.tri", 2);
values[2] = loc("c.tri", 3);
var reg = Registry{ .keys = keys, .values = values, .count = 3 };
const removed = Registry_deduplicate(&reg);
// the second "aa" is the one already seen
assert(removed == 1);
}
Loading