feat(collections): Buffer is a List #382
Loading…
Reference in a new issue
No description provided.
Delete branch "loop/300-buffer-list-bytes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Refs #300
Buffer<Item>joins theListfamily:extend<Item> Buffer<Item> with List<Item> {}; theEquals/Show/Hashimpls of std/core go (the checker forbids a second one). Tests and a conformance program; the benchmarks andtools/buffer-cost.share added here so that the follow-up changes nothing in them.Scope (reviewer finding 1): this PR is only the first half of #300, hence
Refs, notCloses. The second half,refactor(stream): Bytes is Buffer<UInt8>, is its own PR; it needs the baseline numbers of tier B of this PR (bytes-pass-list,compression-round-tripat the merge base) to be measured against. #300 stays open until that PR merges and carriesCloses #300.The probe that the extend compiles with a published nightly (nightly-20261015,
torb check) passed. Related finding while writing the tests: #381 (Option equality over a concreteListtype fails in the VM; independent of this change).Also in this commit, needed by the extend:
compiler/src/ir/witness.trbnames the witness table of aBufferapart from the one ofArrayList(same IR type, so the first to meet a trait handed its members to the other and left an uncalled wrapper behind:-Werror=unused-functionin the C ofbuffer-strings-leaks.trb). The witness members of the boxed-list test move by one index (member 6to7,9to10) because the table now carries one more member; the expectation ofboxed-updates.test.trbfollows that and nothing else.Test
CI only (tier A and tier B; the bootstrap, gates and measurements do not run on the machine of the author). Locally, with the published nightly:
torb checkof std/core, std/collections, benchmarks and the new conformance program,torb format --check,torb testof std/collections and std/core, and the conformance program in the VM against its.expected.Raised
.allocationsbudgetstests/conformance/buffer-basics: 274 to 275 (+1 block). Expected cause:printof aBuffernow goes through theShowofList(std/collections) instead of the removedBuffer-specific one, which costs one block more for the parts list. The figure is the one tier B measures.tests/conformance/buffer-list: new program, budget 1014 as measured by tier B (--update-budgets).Performance
The acceptance bound (
bytes-passagainstbytes-pass-listat 1.10, std/compression round trip per commit at 1.10) belongs to the second PR:Bytesis still aList<UInt8>here, so this PR changes none of the measured code paths. The tier B run of this head prints the baseline (tools/buffer-cost.sh); its numbers are pasted here once the run is final.`extend<Item> Buffer<Item> with List<Item> {}` in std/collections declares what the members of `Buffer` already satisfy, so every signature that says `List<Item>` takes a `Buffer`, and the defaults of the trait (sorting, searching, the participles, windows, chunks, part, splitAt) run on one and answer a `Buffer`. The three impls of Equals, Show and Hash that std/core kept for it go: the checker forbids a second one, and the ones of every `List` are the same. A `Buffer` keeps what makes it a `Buffer` also when it is seen as a `List`: its slice is a copy, and `buffer[from..to] = values` and `update` change it in place. Tests: std/collections/tests/buffer-list.test.trb and tests/conformance/buffer-list.trb. The benchmarks the next commit is measured with are added here, so that it changes nothing in them: benchmarks/bytes-pass.trb against benchmarks/bytes-pass-list.trb, and benchmarks/compression-round-trip.trb. tools/buffer-cost.sh builds and runs them (fastest of nine), and tier B prints its result.3f355970becf7ccf60a6Changes requested on head
3f35597. CI is final and red; the causes below are from the job logs of this head.Closes #300with half of the change. The title and the keyword say "Bytes isBuffer<UInt8>", but the PR has only commit 1 (feat(collections): Buffer is a List). Commit 2 (refactor(stream): Bytes is Buffer<UInt8>) is announced as "follows once the baseline numbers are in". Merging as is would close #300 with theBytespart undone. Either push commit 2 to this PR, or change the PR toRefs #300(and retitle) and let commit 2 be its own PR.benchmarks/README.md: stale: body changed since the last stamp(pdisc.py refresh benchmarks/README.md).docs/standard-library/core.md:254: The block of Buffer is not what the package declares: extend<Item: Equals> Buffer<Item> with Equals has to be ''. Run torb docs declarations. Removing the impls from std/core needs the regenerated docs block.A nested write through a boxed list > the write is one call of update, and the rest of the path is its closurefails itsfunctionText(found, "write")assertion (shard 2, the only failing test of 2984). Either this change moves the lowering of that write (then the expectation needs a reason and an update) or it is a regression; please find out which.tests/conformance/buffer-strings-leaks.trb: the generated C does not compile:n_std_x2f_collections_list_ArrayList_append__String defined but not used [-Werror=unused-function]. Theextend ... with Listnow pulls in anArrayList<String>.appendinstantiation that nothing calls, so the new impl leaks an unused function into the emitted C. This is a real defect of the change (a program that merely usesBuffer<String>no longer builds), not a budget issue.tests/conformance/buffer-basics.trb: allocated 275 blocks, over its budget of 274 by 1. Raising the budget is fine only with the reason in the PR body, under "Raised.allocationsbudgets".tests/conformance/buffer-list.trb: no allocation budget (1014 blocks):sh tools/conformance.sh --update-budgets --filter tests/conformance/buffer-list.trb..allocationsbudgets" and "Performance" are still(to be filled from the CI run). The acceptance bound (bytes-pass against bytes-pass-list at 1.10, std/compression round trip at 1.10) has no numbers yet, and tier B did not get to the measurements. Fill them from a green run.Non-blocking: none. Request a review again once CI is green on a new head.
Buffer is a List, and Bytes is Buffer<UInt8>to feat(collections): Buffer is a Listcf7ccf60a6441f437b74441f437b7462b2b7335862b2b733580f63b4acbfApproved on head
0f63b4a. CI is green for exactly this head (gates, tier A, tier B, pdisc, bootstrap).Earlier findings (round 1, head
3f35597):Refs #300, second half announced as its own PR. okcompiler/tests/buffer-tables.test.trbthat pins the two separately namedListtables. okunused-functiondefect is fixed at the root (tableNameOfinir/witness.trbnames aBuffertable apart from theArrayListone);buffer-basicsbudget raised with a stated reason;buffer-listbudget added. okChecklist: tests (std/collections
buffer-list.test.trb, compilerbuffer-tables.test.trb, conformancebuffer-list) ok; correctness ok; scope = first half of #300 ok; security/secrets ok; data ok; docs (core.md and the skill copy regenerated, pitfalls documented on the extend) ok; workflow change is one measurement step ingates.yml, which by its header design asks for no token.Non-blocking:
buffer-listbudget is 1014, the committedbuffer-list.allocationssays 1084 (tier B passes with it). Fix the body figure.Byteschange, where the 1.10 bound is checked.Buffer<Item>joins theListfamily andBytesbecomesBuffer<UInt8>#300