test: implement TrickleReader as a stream, not a readVec - #46
Merged
Conversation
stream is the only operation a std.Io.Reader must supply. discard, readVec and
rebase all default to implementations derived from it. TrickleReader had that
inverted: it stubbed stream out to return EndOfStream and hand-wrote readVec
and discard instead, so it was correct only in the situations it happened to be
tried in.
Every problem with it followed from that. readVec discarded the destination it
was handed and returned 1 anyway, which under readSliceShort both lost the byte
and miscounted it; once the reader's own buffer filled it returned 0 with no
progress and the caller spun forever. discard returned EndOfStream whenever a
skip reached past what was already buffered, so skipAny could not run against
it. stream itself would have broken anything reaching for streamRemaining.
Implementing stream and deleting the other two overrides is less code and
correct everywhere. defaultReadVec already picks whichever of the caller's
destination or the reader's buffer is larger, which is better than the
hand-written version, and defaultDiscard routes through a Writer.Discarding.
Two tests this unblocks, neither of which could run before:
- a 200 byte string decoded through buffers of 16, 33 and 64 bytes. String
values are copied out rather than borrowed, so unlike map keys they have no
size limit relative to the reader's buffer. This one used to hang.
- skipAny over a value larger than the buffer, landing exactly on the value
that follows. This one used to fail with EndOfStream.
|
Warning Review limit reachedNext included review available in 43 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #44. Replaces #45, which fixed one symptom while leaving the cause in place.
streamis the only operation astd.Io.Readermust supply —discard,readVecandrebaseall default to implementations derived from it:TrickleReaderhad that inverted. It stubbedstreamout to returnerror.EndOfStreamand hand-wrotereadVecanddiscardinstead, so it was correct only in the situations it happened to be tried in. Every problem with it followed from that:readVecdiscarded the destination it was handed and returned 1 anyway. UnderreadSliceShortthat both lost the byte and miscounted it; once the reader's own buffer filled it returned 0 with no progress and the caller spun forever.discardreturnedEndOfStreamwhenever a skip reached past what was already buffered, soskipAnycould not run against it.streamwould have broken anything reaching forstreamRemainingorreadAlloc.Implementing
streamand deleting the other two overrides is less code and correct everywhere.defaultReadVecalready does the empty-vs-non-empty destination handling, and better — it picks whichever ofdata[0]orr.bufferis larger.defaultDiscardroutes through aWriter.Discarding.Net −19 lines from the type, +2 tests.
Two tests this unblocks
Neither could run before:
skipAnyover a value larger than the buffer, checking it lands exactly on the value that follows. This used to fail witherror.EndOfStreamdespite the bytes being available — which matters now thatskip_unknown_fieldsis built onskipAny.Why #45 was the wrong fix
It made
readVechandle both drivers correctly, which removed the hang, but leftdiscardandstreamstubbed. The next gap would have beendiscardthe moment someone testedskip_unknown_fieldsagainst a streaming reader — and the one after that,stream. Deriving everything from one correct primitive removes the whole class instead of one instance.zig build test: 185/185 pass, up from 183.