Fix #169: keep TV episodes contiguous when cache space is tight#170
Merged
StudioNirin merged 1 commit intoMay 29, 2026
Merged
Conversation
…tight Two layers were causing the "S04E03 skipped, S04E04+E05 cached" gap pattern when episode sizes varied within a show (e.g. 4K vs SDR mix). 1. Ordering was lost before space-fit. _gather_media_to_cache collected paths into a set(), so OnDeck "current + next N episodes" arrived at _apply_cache_limit in arbitrary hash-bucket order. Switched to a dict-as-ordered-set so insertion order survives: pinned, then OnDeck in fetch order, then siblings, then watchlist. 2. The space-fit loop in _apply_cache_limit was greedy first-fit, so a large episode would be skipped and smaller later episodes of the same show would be packed instead, creating viewing gaps. Now tracks shows whose sequence broke at the space boundary and skips every later file mapped to that show via media_info_map. Movies and other shows still pack independently. Added TestNoGapShowOrdering in tests/test_plexcache_quota.py covering the gap scenario, mid-sequence breaks, cross-show independence, the no-metadata fallback, and the all-fit happy path.
StudioNirin
approved these changes
May 26, 2026
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 #169.
When cache space is tight, the next OnDeck episode (e.g. S04E03) could be skipped while later episodes of the same show (E04, E05) got cached anyway — leaving a viewing gap. Two layers were contributing.
What was happening
1. Ordering was destroyed before the space-fit step.
_gather_media_to_cachecollected paths into aset()and then didlist(modified_paths_set)to hand off to_apply_cache_limit. Pythonsethas no defined iteration order, so OnDeck's "current + next N episodes" sequence arrived at the fitter in arbitrary hash-bucket order.2.
_apply_cache_limitwas a greedy first-fit pack. If an episode didn't fit, the loop just skipped it and kept going. So a 15 GB 4K E03 with 10 GB free would be skipped, then 2 GB E04 + 2 GB E05 would both fit and get cached.What this PR does
modified_paths_set(aset) becomesmodified_paths: Dict[str, None]used as an ordered set — Python dicts preserve insertion order, so OnDeck fetch order survives all the way through. Final priority order: pinned → OnDeck → OnDeck siblings → watchlist._apply_cache_limitnow tracksshows_at_capacity. Once an episode of show X doesn't fit, every later file mapped to show X viamedia_info_mapis skipped, even if it would individually fit. Movies and other shows still pack independently into the remaining space, so one oversized 4K episode doesn't starve everything else.The space-limit warning now appends
(N skipped to keep show episodes contiguous)when gap-skips happen, so the behavior is visible in logs.Test plan
(N skipped to keep show episodes contiguous)note when applicableNew
TestNoGapShowOrderingclass intests/test_plexcache_quota.pycovers: