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