Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.withContext
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.sync.withPermit
Expand Down Expand Up @@ -331,48 +332,49 @@ class LibraryRepository @Inject constructor(
}
}

val channel = Channel<Pair<String, List<LibraryItem>>>(Channel.UNLIMITED)
activeGroups.forEach { channel.trySend(it.key to it.value) }
channel.close()

val allUpdates = coroutineScope {
activeGroups.map { (baseTitle, items) ->
val workers = (1..5).map {
async {
semaphore.withPermit {
val localUpdates = mutableListOf<LibraryItem>()
for ((baseTitle, items) in channel) {
if (items.isNotEmpty()) {
val latestInLibrary = items.last()
if (latestInLibrary.baseNovelUrl.isNotBlank() && latestInLibrary.sourceName.isNotBlank()) {
runCatching("Failed to refresh updates for $baseTitle", emptyList()) {
val details =
exploreRepository.getNovelDetails(
latestInLibrary.baseNovelUrl,
latestInLibrary.sourceName
)
val newUpdates = runCatching("Failed to refresh updates for $baseTitle", emptyList<LibraryItem>()) {
val details = exploreRepository.getNovelDetails(
latestInLibrary.baseNovelUrl,
latestInLibrary.sourceName
)
if (details != null && details.chapters.isNotEmpty()) {
val sourceChapterCount = details.chapters.size
if (sourceChapterCount > latestInLibrary.totalChapters) {
val itemToMark =
items.find { it.isCurrentlyReading } ?: latestInLibrary
val updatedItems = items.map { item ->
val itemToMark = items.find { it.isCurrentlyReading } ?: latestInLibrary
items.map { item ->
var newItem = item.copy(totalChapters = sourceChapterCount)
if (item.id == itemToMark.id && !item.hasUpdates) {
newItem = newItem.copy(hasUpdates = true)
}
newItem
}
updatedItems
} else {
emptyList()
emptyList<LibraryItem>()
}
} else {
emptyList()
emptyList<LibraryItem>()
}
} ?: emptyList()
} else {
emptyList()
localUpdates.addAll(newUpdates)
}
} else {
emptyList()
}
}
localUpdates
}
}.awaitAll().flatten()
}
workers.awaitAll().flatten()
}

if (allUpdates.isNotEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,11 @@ class LibraryRepositoryBenchmarkTest {

@Test
fun benchmarkRefreshLibraryUpdates() = runBlocking {
// Setup 100 novels (groups).
// 50 "recent" (lastRead within 2 days)
// 50 "old" (lastRead older than 10 days)
// Setup 10000 novels (groups).

val recentCutoff = System.currentTimeMillis() - 2 * 24 * 60 * 60 * 1000L
val oldCutoff = System.currentTimeMillis() - 10 * 24 * 60 * 60 * 1000L

val recentItems = (1..50).map { i ->
val recentItems = (1..10000).map { i ->
LibraryItem(
id = "recent_$i",
title = "Recent Novel $i",
Expand All @@ -59,27 +56,10 @@ class LibraryRepositoryBenchmarkTest {
)
}

val oldItems = (1..50).map { i ->
LibraryItem(
id = "old_$i",
title = "Old Novel $i",
url = "url_old_$i",
baseTitle = "Old Novel $i",
baseNovelUrl = "novel_old_$i",
sourceName = "Source1",
totalChapters = 10,
lastRead = oldCutoff - 10000L, // Definitely old
dateAdded = oldCutoff - 10000L // Added long ago
)
}

val allItems = recentItems + oldItems

whenever(libraryDao.getAllItems()).thenReturn(flowOf(allItems))
whenever(libraryDao.getAllItems()).thenReturn(flowOf(recentItems))

// Mock getNovelDetails with a delay to simulate network latency
// Mock getNovelDetails with NO delay to simulate pure overhead
whenever(exploreRepository.getNovelDetails(any(), any())).thenAnswer {
Thread.sleep(10) // Simulate 10ms network delay per request
ExploreItem("Dummy", "url", source = "Source1", chapters = emptyList())
}

Expand All @@ -90,7 +70,7 @@ class LibraryRepositoryBenchmarkTest {
repository.refreshLibraryUpdates(exploreRepository)
}

println("BENCHMARK_RESULT: ${time}ms for 100 novels (50 recent, 50 old)")
println("BENCHMARK_RESULT: ${time}ms for 10000 novels")

assertTrue(time > 0)
}
Expand Down
Loading