Paginator class to compute page number by offset
parent
c5c84c8630
commit
be595af075
@ -1,7 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="TestsAndReport" type="CompoundRunConfigurationType">
|
||||
<toRun name="MangaParserTest" type="GradleRunConfiguration" />
|
||||
<toRun name="kotatsu-parsers [generateTestsReport]" type="GradleRunConfiguration" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@ -0,0 +1,50 @@
|
||||
package org.koitharu.kotatsu.parsers
|
||||
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.util.Paginator
|
||||
|
||||
@InternalParsersApi
|
||||
abstract class PagedMangaParser(
|
||||
source: MangaSource,
|
||||
pageSize: Int,
|
||||
searchPageSize: Int = pageSize,
|
||||
) : MangaParser(source) {
|
||||
|
||||
protected val paginator = Paginator(pageSize)
|
||||
protected val searchPaginator = Paginator(searchPageSize)
|
||||
|
||||
override suspend fun getList(offset: Int, query: String): List<Manga> {
|
||||
return getList(searchPaginator, offset, query, null, defaultSortOrder)
|
||||
}
|
||||
|
||||
override suspend fun getList(offset: Int, tags: Set<MangaTag>?, sortOrder: SortOrder?): List<Manga> {
|
||||
return getList(paginator, offset, null, tags, sortOrder ?: defaultSortOrder)
|
||||
}
|
||||
|
||||
@InternalParsersApi
|
||||
@Deprecated("You should use getListPage for PagedMangaParser", level = DeprecationLevel.HIDDEN)
|
||||
final override suspend fun getList(
|
||||
offset: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> = throw UnsupportedOperationException("You should use getListPage for PagedMangaParser")
|
||||
|
||||
abstract suspend fun getListPage(page: Int, query: String?, tags: Set<MangaTag>?, sortOrder: SortOrder): List<Manga>
|
||||
|
||||
private suspend fun getList(
|
||||
paginator: Paginator,
|
||||
offset: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
val page = paginator.getPage(offset)
|
||||
val list = getListPage(page, query, tags, sortOrder)
|
||||
paginator.onListReceived(offset, page, list.size)
|
||||
return list
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package org.koitharu.kotatsu.parsers.util
|
||||
|
||||
import androidx.collection.SparseArrayCompat
|
||||
import androidx.collection.set
|
||||
|
||||
class Paginator constructor(private val initialPageSize: Int) {
|
||||
|
||||
var firstPage = 1
|
||||
private var pages = SparseArrayCompat<Int>()
|
||||
|
||||
fun getPage(offset: Int): Int {
|
||||
if (offset == 0) { // just an optimization
|
||||
return firstPage
|
||||
}
|
||||
pages[offset]?.let { return it }
|
||||
val pageSize = initialPageSize
|
||||
val intPage = offset / pageSize
|
||||
val tail = offset % pageSize
|
||||
return intPage + firstPage + if (tail == 0) 0 else 1
|
||||
}
|
||||
|
||||
fun onListReceived(offset: Int, page: Int, count: Int) {
|
||||
pages[offset + count] = if (count > 0) page + 1 else page
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package org.koitharu.kotatsu.parsers.util
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class PaginatorTest {
|
||||
|
||||
@Test
|
||||
fun singlePaginationTest() {
|
||||
val paginator = Paginator(24)
|
||||
assertEquals(1, paginator.getPage(0))
|
||||
assertEquals(2, paginator.getPage(24))
|
||||
assertEquals(3, paginator.getPage(48))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun adaptivePaginationTest() {
|
||||
val paginator = Paginator(12)
|
||||
assertEquals(1, paginator.getPage(0))
|
||||
paginator.onListReceived(0, 1, 24)
|
||||
assertEquals(2, paginator.getPage(24))
|
||||
paginator.onListReceived(24, 2, 18)
|
||||
assertEquals(3, paginator.getPage(42))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun endReachPaginationTest() {
|
||||
val pageSize = 24
|
||||
val paginator = Paginator(pageSize)
|
||||
var size = 0
|
||||
repeat(5) { i ->
|
||||
val offset = i * pageSize
|
||||
assertEquals(i + 1, paginator.getPage(offset))
|
||||
paginator.onListReceived(offset, i + 1, pageSize)
|
||||
size += pageSize
|
||||
}
|
||||
val nextPage = paginator.getPage(size)
|
||||
assertEquals(nextPage, paginator.getPage(size))
|
||||
paginator.onListReceived(size, nextPage, 0)
|
||||
assertEquals(nextPage, paginator.getPage(size))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue