Skip to content

feat: add ReadHeader, ReadMany, and ReadManyHeaders#38

Open
ajroetker wants to merge 3 commits intotidwall:masterfrom
ajroetker:feat/count-and-read-header
Open

feat: add ReadHeader, ReadMany, and ReadManyHeaders#38
ajroetker wants to merge 3 commits intotidwall:masterfrom
ajroetker:feat/count-and-read-header

Conversation

@ajroetker
Copy link

@ajroetker ajroetker commented Mar 6, 2026

Summary

New methods for efficient partial and batch reads from the WAL.

ReadHeader(index, n) — read the first n bytes of an entry without copying the full payload. Useful for inspecting embedded metadata headers (retry counts, item counts, etc.) without deserializing the full entry.

ReadMany(start, count) — batch read a contiguous range of entries, returning [][]byte. Reuses loaded segments across the range instead of calling loadSegment per entry.

ReadManyHeaders(start, count, n) — batch read the first n bytes of each entry in a range. Combines the efficiency of ReadHeader with the segment reuse of ReadMany.

Design

  • ReadHeader always copies the result even with NoCopy — the segment buffer can be evicted by the LRU cache between calls.
  • ReadMany and ReadManyHeaders track the current segment and only call loadSegment when crossing segment boundaries.
  • Internal helpers readEntry and readEntryHeader are extracted from Read/ReadHeader and shared by the batch methods.
  • Read is refactored to use readEntry.
  • All methods use RLock, consistent with existing read paths.
  • Ranges are clamped to [FirstIndex, LastIndex] — out-of-bounds requests return partial results rather than errors.

ReadHeader returns only the first n bytes of an entry's data, enabling
efficient scanning of fixed-size metadata headers without copying full
payloads. This supports use cases like WAL-backed queues that embed
retry counts or item counts in entry headers.

ReadHeader always copies the result (even with NoCopy enabled) because
the segment buffer may be evicted by the LRU cache, making a slice
into it unsafe for the caller to hold.
Add batch read methods that reuse loaded segments across contiguous
index ranges, avoiding redundant segment lookups. Extract readEntry
and readEntryHeader helpers from Read and ReadHeader. Refactor Read
to use readEntry.

- ReadMany(start, count) returns [][]byte for a range of entries
- ReadManyHeaders(start, count, n) returns first n bytes of each entry
- Segment reuse: only calls loadSegment when crossing segment boundaries
@ajroetker ajroetker changed the title feat: add ReadHeader method feat: add ReadHeader, ReadMany, and ReadManyHeaders Mar 6, 2026
@ajroetker
Copy link
Author

also conveniently aligns with #17 I think

- Fix integer overflow in end-index calculation for ReadMany/
  ReadManyHeaders by using overflow-safe arithmetic
- Fix NoCopy safety: ReadMany always copies entry data since segment
  eviction can invalidate slices from earlier iterations
- Fix ReadHeader returning []byte{} instead of nil for n<=0, and move
  n<=0 check after corrupt/closed guards so closed logs still error
- Extract shared readMany helper to deduplicate ReadMany/ReadManyHeaders
- Add tests: max-count overflow, closed-n-zero, JSON format headers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant