fix: module compression incorrectly reused first file's root pointer#5
Merged
Conversation
Contributor
Author
|
(If anyone is interested in what the Claude conversation looked like, it's here.) |
digama0
force-pushed
the
fix_module_bug
branch
from
October 23, 2025 00:22
5e0cbc3 to
92221b6
Compare
The module compression feature (added in commits 067cd65 and ff253cb) had a bug where all three module files (.olean, .olean.server, .olean.private) were compressed using the first file's root pointer. Bug diagnosis and fix by Claude (@anthropics). ## The Bug Two related issues in src/lgz.rs compress(): 1. Line 261: Used `root` instead of `header2.root` when storing each file's metadata. This caused all Data entries to reference the same root object from the first file. 2. Line 279: Used `root` instead of `d.root` during reference counting, only marking the first file's root as referenced. ## The Symptom When compressing three module files together: - First file (.olean): Compressed correctly → ~48KB - Second file (.server): Decompressed to 96 bytes instead of 2.3KB - Third file (.private): Decompressed to 96 bytes instead of 46KB The second and third files were truncated to just the olean header because the compressor thought it had already written their root objects (since they all pointed to the first file's root). ## The Fix Two one-line changes: 1. Line 261: `root` → `header2.root` 2. Line 279: `root` → `d.root` Each file now correctly stores and compresses its own root pointer, producing three complete, distinct object graphs. ## Testing Added integration tests in tests/module_compression.rs with test data from Plausible.Attr module. Tests verify byte-identical roundtrip for both single-file and multi-file (module) compression. Before fix: test_module_roundtrip FAILED (files truncated to 96 bytes) After fix: test_module_roundtrip PASSED (all files match perfectly) Note: This diagnosis and fix were performed by Claude Code. While tests pass, this needs careful review by @digama0 to ensure correctness. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
digama0
force-pushed
the
fix_module_bug
branch
from
October 23, 2025 00:29
92221b6 to
b5e975d
Compare
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.
Summary
Fixes a bug in the module compression feature where
.olean.serverand.olean.privatefiles were being truncated to 96 bytes (just the header) instead of being fully compressed.Note: This diagnosis and fix were performed by Claude Code (@anthropics). While integration tests pass, this needs careful review by @digama0 to ensure correctness, as I (@kim-em) cannot vouch for the implementation details.
The Bug
Two related issues in
src/lgz.rscompress()function:Line 261: Used
rootinstead ofheader2.rootwhen storing each file's metadataDataentries to reference the same root object from the first fileLine 279: Used
rootinstead ofd.rootduring reference countingSymptom
When compressing three module files (
.olean,.olean.server,.olean.private):.olean): Compressed correctly → ~48KB.server): Decompressed to 96 bytes instead of 2.3KB.private): Decompressed to 96 bytes instead of 46KBThe second and third files were truncated because the compressor's backref cache thought it had already written their root objects (since all three files pointed to the first file's root).
The Fix
Two one-line changes in
src/lgz.rs:root→header2.rootroot→d.rootEach file now correctly stores and compresses its own root pointer, producing three complete, distinct object graphs.
Testing
#4 added integration tests in
tests/module_compression.rswith test data fromPlausible.Attrmodule.Before fix:
After fix:
cc @digama0 for review