3.4 Case Folding

Key names and value names are case-insensitive but case-preserving. loregd implements this by storing both forms: the name as written, and a folded form alongside it in a _folded column.

The folded form is computed once, when the name is written, and it is the folded column that appears in every WHERE clause and every primary key. Lookups are therefore plain binary comparisons :

SELECT * FROM path_entries
WHERE parent_guid = ? AND child_name_folded = ?

This is why no custom SQLite collation is registered anywhere in loregd — the case-insensitivity has already happened by the time SQLite sees the query.

The canonical name is what comes back in responses, so callers see the case they originally supplied while storage compares the folded form.

Hive names are folded too, though not stored : routing a request to a hive and rejecting duplicate hive declarations (§2.1) both compare folded names.

Layer names are not folded. They are compared as binary, so layer names are case-sensitive.

3.4.1 How the folded form is computed #

The folded form is Unicode Simple Case Folding: each codepoint is replaced by its status C or S mapping from CaseFolding.txt, Unicode 16.0.0, or left alone when it has none. This is the same rule the kernel applies when it compares layer names and every other name in LCS, and loregd must produce byte-identical results, because a name the two fold differently is a key that exists for one side and not the other.

Identity is guaranteed by construction rather than by care. loregd does not derive the fold from the Go standard library, whose case tables implement lowercasing (a different operation) at a different Unicode version. Its table is generated by the kernel's own generator, pkm/tools/lcs/generate_casefold_table.py, from the same CaseFolding.txt that produces the kernel's table; the generated Go file records the source version and checksum, and the lookup mirrors the kernel's binary search over the same ranges and pairs. A Unicode version bump regenerates both outputs together.

Edit this page