Retract the uniformity claim everywhere it still stood, including the API docs
The record-length retraction had been applied to the tests and to the section
that discovered the problem, but the same claim was still standing in four other
places -- including the rustdoc for has_uniform_record_length(), which is what a
caller would actually read:
crates/gc-formats/src/chunks.rs:206 "Measured: true for 1,509 of 1,509 chunks"
docs/roadmap.md:448 "uniform record length (1,509 of 1,509)"
docs/formats/core-data-regions.md a whole section titled
"Every chunk has a uniform record length"
All three now say 257 of 1,509, and the method's rustdoc explains WHY the old
number was an artefact -- that resolve sliced at the first offset delta, so every
record came out the same length by construction and the predicate was confirming
the parser back to itself.
That section also contained a withdrawal, and the withdrawal was wrong:
"This withdraws the previous commit's variable-length type. That came from
taking minlen/maxlen over all of a type's records at once, pooling across
chunks; rule 3a's pooled claim, third time this session."
The pooling rule fired correctly and was overruled by a measurement with no
independent content. The per-chunk check that should have caught the pooled
signal was itself reporting the parser's own slicing, so it agreed with the wrong
answer for the same reason the original claim did. Two errors stacked: a real
signal dismissed by a rule that had been right twice already, and a predicate
that could not have told the difference.
This is the third time this session that a test was asserting the parser's
behaviour rather than the disc's, and the third time it was the only thing
standing between a claim and a retraction. has_uniform_record_length is the
clearest instance: a predicate named after a property of the data, returning a
confident answer about the code.
245 tests, clippy clean.
This commit is contained in:
@@ -203,10 +203,21 @@ impl<'a> ResolvedChunk<'a> {
|
|||||||
|
|
||||||
/// True when every record in this chunk has the same length.
|
/// True when every record in this chunk has the same length.
|
||||||
///
|
///
|
||||||
/// **Measured: true for 1,509 of 1,509 chunks** across all 27 levels. Record
|
/// **Measured: true for 257 of 1,509 chunks** across all 27 levels. Record
|
||||||
/// length varies *between* chunks of the same type -- one type runs 76 to 104
|
/// length varies *between* chunks of the same type -- one type runs 76 to 104
|
||||||
/// bytes -- but never within one. An earlier claim that some type had
|
/// bytes -- and, on 1,252 chunks, *within* one as well.
|
||||||
/// variable-length records was pooling across chunks; it is withdrawn.
|
///
|
||||||
|
/// This method used to report 1,509 of 1,509, and that was an artefact of
|
||||||
|
/// `resolve`: it sliced every record at the chunk's first offset delta, so
|
||||||
|
/// every record came out the same length by construction, and this predicate
|
||||||
|
/// was confirming the parser back to itself. `resolve` now bounds each record
|
||||||
|
/// by its successor's offset, which is the only coherent reading -- a record
|
||||||
|
/// of the nominal stride would overlap the next one whenever the delta is
|
||||||
|
/// smaller, and an explicit offset table cannot express an overlap.
|
||||||
|
///
|
||||||
|
/// So the earlier withdrawal, "an earlier claim that some type had
|
||||||
|
/// variable-length records was pooling across chunks", was also wrong. The
|
||||||
|
/// records are variable-length and were never anything else.
|
||||||
pub fn has_uniform_record_length(&self) -> bool {
|
pub fn has_uniform_record_length(&self) -> bool {
|
||||||
let mut it = self.records.iter().filter(|r| !r.is_empty());
|
let mut it = self.records.iter().filter(|r| !r.is_empty());
|
||||||
let Some(first) = it.next().map(|r| r.len()) else {
|
let Some(first) = it.next().map(|r| r.len()) else {
|
||||||
|
|||||||
@@ -1429,15 +1429,28 @@ fits and `None` otherwise, so the 247 unexplained chunks are distinguishable
|
|||||||
from the 1,262 explained ones and nothing skips a leading byte on the strength of
|
from the 1,262 explained ones and nothing skips a leading byte on the strength of
|
||||||
a rule that does not apply.
|
a rule that does not apply.
|
||||||
|
|
||||||
### Every chunk has a uniform record length
|
### RETRACTED: "every chunk has a uniform record length"
|
||||||
|
|
||||||
**1,509 of 1,509 chunks.** Length varies between chunks of the same type -- one
|
**Claimed: 1,509 of 1,509 chunks. True: 257 of 1,509.**
|
||||||
type runs 76 to 104 bytes -- but never within one chunk.
|
|
||||||
|
|
||||||
This **withdraws the previous commit's "variable-length type"**. That came from
|
Length varies between chunks of the same type -- one type runs 76 to 104 bytes --
|
||||||
taking `minlen`/`maxlen` over all of a type's records at once, pooling across
|
and on 1,252 chunks it varies *within* one as well.
|
||||||
chunks; rule 3a's pooled claim, third time this session. Within any one chunk the
|
|
||||||
length is fixed.
|
**Both halves of that old entry were wrong, and both were mine.**
|
||||||
|
|
||||||
|
"Never within one chunk" was `resolve` slicing every record at the chunk's first
|
||||||
|
offset delta. Every record then came out the same length by construction, so the
|
||||||
|
predicate was confirming the parser back to itself.
|
||||||
|
|
||||||
|
And this section's *withdrawal* of "variable-length type" was wrong too. It read
|
||||||
|
the pooled observation as a partitioning artifact -- `minlen`/`maxlen` taken across
|
||||||
|
all of a type's records at once. Rule 3a is right about pooling in general, and it
|
||||||
|
was applied to a real signal here: the type genuinely has variable-length records,
|
||||||
|
and the per-chunk check that would have caught it was itself reporting the
|
||||||
|
parser's own slicing.
|
||||||
|
|
||||||
|
Two errors stacked. The pooling rule fired correctly and was overruled by a
|
||||||
|
measurement that had no independent content.
|
||||||
|
|
||||||
## The first TWO bytes encode the record's own index
|
## The first TWO bytes encode the record's own index
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -444,10 +444,12 @@ Phase 1 hands over the extents; this phase works out what each one contains.
|
|||||||
chunks, 34,491 records.** Moby class IDs enrich at 9,493 hits against
|
chunks, 34,491 records.** Moby class IDs enrich at 9,493 hits against
|
||||||
246.1 expected with contiguous per-type arrays -- but the arrays land in a
|
246.1 expected with contiguous per-type arrays -- but the arrays land in a
|
||||||
different place for each type, so no single pooled scan finds them.
|
different place for each type, so no single pooled scan finds them.
|
||||||
- [x] **Chunk record framing is closed.** Every chunk has a **uniform record
|
- [x] **Chunk record framing is closed**, but the uniformity claim in it is
|
||||||
length** (1,509 of 1,509) -- length varies *between* chunks of a type, never
|
**retracted**: only **257 of 1,509** chunks have a uniform record length, and
|
||||||
within one, which withdrew an earlier "variable-length type" claim that had
|
1,252 are variable within the chunk. "1,509 of 1,509" was `resolve` slicing
|
||||||
been pooled across chunks. The record's leading byte is a **per-chunk phase
|
at the chunk's first offset delta and the predicate confirming the parser
|
||||||
|
back to itself. An earlier withdrawal ("variable-length was a pooled
|
||||||
|
artifact") was wrong too -- the records were always variable. The record's leading byte is a **per-chunk phase
|
||||||
counter** (`bucket_rule`, 1,262 of 1,509 chunks) and on **1,235** of them
|
counter** (`bucket_rule`, 1,262 of 1,509 chunks) and on **1,235** of them
|
||||||
*both* leading bytes encode the record's own index in mixed radix
|
*both* leading bytes encode the record's own index in mixed radix
|
||||||
(`index_rule`), so the leading bytes carry no per-record information.
|
(`index_rule`), so the leading bytes carry no per-record information.
|
||||||
|
|||||||
Reference in New Issue
Block a user