feat: configurable chapter window & parallel metadata parsing with benchmark
1. Configurable chapter window size (onDemandChapterWindowSize: 3-15) - Parameterized window radius in RDEPUBChapterRuntimeStore - Updated RDEPUBChapterWindowCoordinator to use configurable radius - RDEPUBChapterWindowSnapshot.from() accepts chapter array instead of fixed prev/next - Even numbers round up to odd (4→5), min 3, max 15 2. Configurable metadata parsing concurrency (metadataParsingConcurrency) - Default equals CPU core count - Parallel execution via OperationQueue in paginateMetadataOnly - Each worker creates independent builder instance - NSLock protects result aggregation 3. Per-chapter and total wall-clock timing instrumentation - Separated render vs I/O timing per chapter - Summary log with wallClockMs, renderTotalMs, writeTotalMs, avgRenderMs - Timing stored in RDEPUBReaderContext for test access 4. UI automation test infrastructure - Added --demo-window-size, --demo-concurrency, --demo-clear-cache launch args - DemoReaderState exposes windowSize, parseMs, parseConcurrency - ConfigurableWindowTests: 5 test cases for window size 3/5/15 - ConcurrentParsingTests: 4 test cases for concurrency 2/4 - MetadataParseBenchmarkTests: serial vs parallel benchmark 5. Bug fixes - Fixed page snap-back during background parsing (isUserInteracting check) - Reduced BookPageMap refresh frequency from 16 to 32 chapters - Moved waitForReadingInteractionToSettle outside operation loop 6. Design doc: dual-layer PageMap (estimated + precise mixed)
This commit is contained in:
+12
-8
@@ -23,7 +23,7 @@ final class RDEPUBChapterRuntimeStore {
|
||||
/// 当前章 spineIndex
|
||||
private(set) var currentSpineIndex: Int?
|
||||
|
||||
/// 当前窗口内的 spineIndex 集合(当前 + prev + next)
|
||||
/// 当前窗口内的 spineIndex 集合(以当前章为中心,按配置半径展开)
|
||||
private(set) var windowSpineIndices: [Int] = []
|
||||
|
||||
// MARK: - 请求通道(前台导航 vs 后台预取,语义独立,互不抢占)
|
||||
@@ -75,13 +75,17 @@ final class RDEPUBChapterRuntimeStore {
|
||||
|
||||
// MARK: - 窗口管理
|
||||
|
||||
/// 设定当前章,自动计算 ±1 窗口
|
||||
func setCurrentChapter(spineIndex: Int, totalSpineCount: Int) {
|
||||
/// 设定当前章,自动计算按半径展开的窗口
|
||||
func setCurrentChapter(spineIndex: Int, totalSpineCount: Int, windowRadius: Int = 1) {
|
||||
currentSpineIndex = spineIndex
|
||||
var window = [spineIndex]
|
||||
if spineIndex > 0 { window.append(spineIndex - 1) }
|
||||
if spineIndex < totalSpineCount - 1 { window.append(spineIndex + 1) }
|
||||
windowSpineIndices = window
|
||||
let radius = max(0, windowRadius)
|
||||
let lowerBound = max(0, spineIndex - radius)
|
||||
let upperBound = min(totalSpineCount - 1, spineIndex + radius)
|
||||
guard lowerBound <= upperBound else {
|
||||
windowSpineIndices = [spineIndex]
|
||||
return
|
||||
}
|
||||
windowSpineIndices = Array(lowerBound...upperBound)
|
||||
}
|
||||
|
||||
/// 返回窗口外、应该淘汰的 spineIndex
|
||||
@@ -183,4 +187,4 @@ final class RDEPUBChapterRuntimeStore {
|
||||
pageCountCache.removeAll()
|
||||
imageCache.removeAllObjects()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user