Repository navigation
perf(scan): move bundle-size walk off the scan critical path - #23
Merged
Merged
Conversation
Summing every file inside every plugin bundle during the scan was the dominant cost of a full scan (audio bundles ship large sample/preset trees). BundleMetadataExtractor no longer walks bundle contents; the scan now reads only Info.plist + the Mach-O header. Bundle size is resolved lazily by a new BundleSizeService actor after the plugin list is shown, cached per bundle modification date so a rescan only re-walks bundles that actually changed. Plugin gains a sizeCacheMtime field; PluginReconciler preserves the stored size when the scan produces none (fileSize is now optional on PluginMetadata). Adds BundleSizeService tests (cache hit/miss/stale) and reconciler coverage for size preservation. Full suite: 323 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Problem
A full scan was slow because
BundleMetadataExtractorrecursively walked every file inside every plugin bundle on every scan just to populate the Size column. Audio bundles ship large sample/preset/wavetable trees (this library is ~65 GB across 1,800+ files), so each scan meant hundreds of thousands of filesystem stat calls — the dominant cost. It ran on the critical path and recomputed from scratch each time, even for unchanged plugins.Fix
BundleMetadataExtractorno longer walks bundle contents. The scan now reads onlyInfo.plist+ the Mach-O header.PluginMetadata.fileSizeis now optional (nilduring the scan).BundleSizeServiceactor resolves sizes lazily after the list is shown, cached per bundle modification date — a rescan only re-walks bundles that actually changed.Plugingains asizeCacheMtimefield;PluginReconcilerpreserves the stored size when the scan produces none.AppStatestarts the background size pass right after reconcile (overlapping the update check), for both full and incremental scans.Net effect: the plugin list appears as soon as plist+arch metadata is read; size fills in shortly after and is essentially free on subsequent scans.
Tests
BundleSizeServicesuite: cache hit / miss / stale-mtime, recursion, nonexistent dir, multi-bundle.swift test, macOS, Xcode 26.6). Build clean; SwiftLint clean on changed files.Context
First increment of a larger effort to match PluginHub / Plugoff. Category classifier + offload backends and the remaining UI (duplicate detection, catalog + insights, offloading, PluginHub-style update UX) are on separate branches and will follow as their own PRs.
🤖 Generated with Claude Code