邻接窗口淘汰不再清除前瞻预取章节

scheduleAdjacentChapterPrefetches 的窗口外淘汰会把
maybePrefetchUpcomingChapters 刚预取的后续章节清掉,下一次
prepare 又触发重建,形成"淘汰-重建"循环。淘汰时保留当前章之后
lookahead 范围内的章节,lookahead 数量提为共享常量。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
shenlei 2026-07-06 11:56:22 +09:00
parent 7132e4952b
commit bd6e915fbd

View File

@ -32,6 +32,8 @@ final class RDEPUBChapterWarmupOrchestrator {
private let prepareRequestDebounceInterval: CFTimeInterval = 0.15
private static let upcomingChapterLookaheadCount = 2
init(
context: RDEPUBReaderContext,
store: RDEPUBChapterRuntimeStore,
@ -392,7 +394,10 @@ final class RDEPUBChapterWarmupOrchestrator {
windowRadius: context.configuration.chapterWindowRadius
)
for evictable in store.evictableSpineIndices() {
// Keep chapters that maybePrefetchUpcomingChapters is responsible for,
// otherwise the two policies evict/rebuild the same chapter in a loop.
let retainedLookaheadIndices = upcomingLookaheadSpineIndices(after: spineIndex)
for evictable in store.evictableSpineIndices() where !retainedLookaheadIndices.contains(evictable) {
store.evict(spineIndex: evictable)
}
@ -410,11 +415,18 @@ final class RDEPUBChapterWarmupOrchestrator {
}
}
private func upcomingLookaheadSpineIndices(after spineIndex: Int) -> Set<Int> {
guard let publication = context.publication else { return [] }
let buildableIndices = buildableSpineIndices(in: publication)
guard let currentPosition = buildableIndices.firstIndex(of: spineIndex) else { return [] }
return Set(buildableIndices.dropFirst(currentPosition + 1).prefix(Self.upcomingChapterLookaheadCount))
}
private func maybePrefetchUpcomingChapters(
aroundAbsolutePageNumber pageNumber: Int,
in bookPageMap: RDEPUBBookPageMap,
threshold: Int = 3,
lookaheadChapterCount: Int = 2
lookaheadChapterCount: Int = RDEPUBChapterWarmupOrchestrator.upcomingChapterLookaheadCount
) {
guard let publication = context.publication else { return }
let absolutePageIndex = pageNumber - 1