feat: 实现大书远距目录跳转与后台补全优化方案

Phase 1: 稳定性优先
- 新增 RDEPUBJumpSession 保护机制,防止远距跳转后翻页串章
- 升级页图接管条件,增加 JumpSession 保护区检查
- 窗口扩展改为基于当前权威窗口方向

Phase 2: 补全优先级重排
- 新增 RDEPUBBackgroundPriorityPolicy 策略配置
- 实现 hot/warm/cold zone 优先级排序
- 添加失败重试机制(指数退避,最多3次)

Phase 3: 分段覆盖与最终收敛
- 新增 RDEPUBBackgroundCoverageStore 分段存储
- 新增 RDEPUBPageMapReconciliationCoordinator 页图接管仲裁
- 实现 LRU 淘汰和内存警告处理

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-06-15 16:28:11 +08:00
co-authored by Claude Opus 4.7
parent e976ceebd5
commit c64460988a
13 changed files with 2797 additions and 92 deletions
@@ -296,31 +296,41 @@ extension RDEPUBReaderController: RDReaderDataSource, RDReaderDelegate {
reconcileTextPaginationSizeIfNeeded(for: pageNum)
// map
let previousCurrentPage = readerView.currentPage
runtime.applyPendingFullPageMapIfNeeded()
let effectivePageNum = readerView.currentPage >= 0 ? readerView.currentPage : pageNum
if previousCurrentPage != readerView.currentPage, effectivePageNum != pageNum {
return
}
if readerContext.bookPageMap != nil {
_ = runtime.prepareOnDemandChapter(forAbsolutePageNumber: pageNum + 1)
runtime.extendPartialBookPageMapIfNeeded(currentPageNumber: pageNum + 1)
_ = runtime.prepareOnDemandChapter(forAbsolutePageNumber: effectivePageNum + 1)
runtime.extendPartialBookPageMapIfNeeded(currentPageNumber: effectivePageNum + 1)
}
let totalPages = pageCountOfReaderView(readerView: readerView)
if totalPages > 0, pageNum == totalPages - 1 {
if totalPages > 0, effectivePageNum == totalPages - 1 {
delegate?.epubReaderDidReachEnd(self)
}
if (textBook != nil || readerContext.bookPageMap != nil),
let location = resolvedTextLocation(forPageNumber: pageNum + 1) {
let location = resolvedTextLocation(forPageNumber: effectivePageNum + 1) {
persist(location: location)
synchronizeTextReadingState(pageNumber: pageNum + 1, location: location)
synchronizeTextReadingState(pageNumber: effectivePageNum + 1, location: location)
// JumpSession
runtime.locationCoordinator.recordPageChangeIfNeeded()
return
}
if let location = fallbackLocation(for: pageNum) {
if let location = fallbackLocation(for: effectivePageNum) {
persist(location: location)
}
if readingSession?.navigatorState == .jumping || readingSession?.navigatorState == .moving {
readingSession?.transition(to: .idle)
}
// JumpSession
runtime.locationCoordinator.recordPageChangeIfNeeded()
}
///