From 9fcd7914dcce26dfe537cd4b87deeeda63d2bbed Mon Sep 17 00:00:00 2001 From: OneWay Date: Tue, 1 Sep 2026 13:36:23 +0800 Subject: [PATCH] refactor: slim IndexingProgress to a producer-supplied [0,1] progress perFileProgress was never populated and its progress branch was unreachable; currentFile, currentIndex, currentFileProgress and label were write-only (no consumer read them); progressPercent had no callers; the -1f aggregate sentinel is gone along with the fallback branches that only fired when the tracker was absent. --- .../core/domain/model/IndexingProgress.kt | 39 +++--------------- .../repository/LocalDictionaryRepository.kt | 41 +++++-------------- 2 files changed, 16 insertions(+), 64 deletions(-) diff --git a/app/src/main/java/com/example/research/core/domain/model/IndexingProgress.kt b/app/src/main/java/com/example/research/core/domain/model/IndexingProgress.kt index f3bd41c..b14e647 100644 --- a/app/src/main/java/com/example/research/core/domain/model/IndexingProgress.kt +++ b/app/src/main/java/com/example/research/core/domain/model/IndexingProgress.kt @@ -1,42 +1,13 @@ package com.example.research.core.domain.model -import kotlin.math.roundToInt /** * Snapshot of an ongoing indexing operation. * - * [progress] is the authoritative [0f, 1f] completion value and is O(1) to - * compute: the repository's internal `ProgressTracker` maintains a running - * sum across files incrementally and stores it in [aggregateSum], avoiding - * an O(n) walk over [perFileProgress] on every read. - * [perFileProgress] is kept for diagnostics; callers should prefer - * [progress] / [progressPercent]. + * [progress] is the authoritative [0f, 1f] completion value: the repository + * aggregates a file-size-weighted sum across files incrementally while + * indexing, so reading it is O(1). */ data class IndexingProgress( - val currentFile: String = "", - val currentIndex: Int = 0, - val totalFiles: Int = 0, val isIndexing: Boolean = false, - val currentFileProgress: Float = 0f, - val label: String = "", - val perFileProgress: Map = emptyMap(), - /** Pre-aggregated sum in [0f, totalFiles] supplied by the producer; -1f = unknown. */ - val aggregateSum: Float = -1f, -) { - val progress: Float - get() = if (totalFiles > 0) { - when { - aggregateSum >= 0f -> (aggregateSum / totalFiles).coerceIn(0f, 1f) - perFileProgress.isNotEmpty() -> { - val totalProgress = perFileProgress.values.sum() - (totalProgress / totalFiles).coerceIn(0f, 1f) - } - else -> { - val completedFiles = (currentIndex - 1).coerceAtLeast(0) - ((completedFiles + currentFileProgress) / totalFiles).coerceIn(0f, 1f) - } - } - } else 0f - - val progressPercent: Int - get() = (progress * 100).roundToInt().coerceIn(0, 100) -} + val progress: Float = 0f, +) diff --git a/app/src/main/java/com/example/research/data/repository/LocalDictionaryRepository.kt b/app/src/main/java/com/example/research/data/repository/LocalDictionaryRepository.kt index 452e812..1b49e0b 100644 --- a/app/src/main/java/com/example/research/data/repository/LocalDictionaryRepository.kt +++ b/app/src/main/java/com/example/research/data/repository/LocalDictionaryRepository.kt @@ -70,13 +70,9 @@ private class ProgressTracker(files: List + filesToIndex.map { file -> async { indexingSemaphore.withPermit { coroutineContext.ensureActive() yield() - val res = indexDictionary(file) { _, op, prog -> + val res = indexDictionary(file) { _, _, prog -> if (prog >= 0f) { progressTracker?.updateFileProgress(file.name, prog) } - val tracker = progressTracker - val aggregate = tracker?.aggregateSum() ?: -1f - val newPercent = if (filesToScan.isNotEmpty() && aggregate >= 0f) { - ((aggregate / filesToScan.size) * 100f).toInt().coerceIn(0, 100) - } else -1 + val progress = progressTracker?.progress() ?: 0f + val newPercent = (progress * 100f).toInt().coerceIn(0, 100) - val currentIdx = filesToScan.size - filesToIndex.size + index + 1 - val previous = mutableIndexingProgress.value val now = SystemClock.elapsedRealtime() - val percentChanged = newPercent >= 0 && newPercent != lastEmittedPercent.get() - val fileChanged = previous.currentFile != file.name + val percentChanged = newPercent != lastEmittedPercent.get() val completed = newPercent >= 100 || prog >= 1f val intervalElapsed = now - lastProgressEmitMs.get() >= MIN_PROGRESS_EMIT_INTERVAL_MS - val shouldEmit = fileChanged || completed || (percentChanged && intervalElapsed) + val shouldEmit = completed || (percentChanged && intervalElapsed) if (shouldEmit) { - if (newPercent >= 0) lastEmittedPercent.set(newPercent) + lastEmittedPercent.set(newPercent) lastProgressEmitMs.set(now) mutableIndexingProgress.update { p -> - p.copy( - currentFile = file.name, - currentIndex = currentIdx, - currentFileProgress = prog, - label = op.ifEmpty { p.label }, - aggregateSum = aggregate, - ) + p.copy(progress = progress) } } }