Use ArrayDeque in reader
parent
a885709ba9
commit
72fdc7796f
@ -1,229 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.ui.reader.base
|
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class GroupedList<K, T> {
|
|
||||||
|
|
||||||
private val data = LinkedList<Pair<K, List<T>>>()
|
|
||||||
|
|
||||||
private var intSize: Int = -1
|
|
||||||
private var lruGroup: List<T>? = null
|
|
||||||
private var lruGroupKey: K? = null
|
|
||||||
private var lruGroupFirstIndex = -1
|
|
||||||
|
|
||||||
val size: Int
|
|
||||||
get() {
|
|
||||||
if (intSize < 0) {
|
|
||||||
computeSize()
|
|
||||||
}
|
|
||||||
return intSize
|
|
||||||
}
|
|
||||||
|
|
||||||
val groupCount: Int
|
|
||||||
get() = data.size
|
|
||||||
|
|
||||||
val isEmpty: Boolean
|
|
||||||
get() = size == 0
|
|
||||||
|
|
||||||
val isNotEmpty: Boolean
|
|
||||||
get() = size != 0
|
|
||||||
|
|
||||||
operator fun get(index: Int): T {
|
|
||||||
if (index >= lruGroupFirstIndex) {
|
|
||||||
val relIndex = index - lruGroupFirstIndex
|
|
||||||
lruGroup?.let {
|
|
||||||
if (relIndex in it.indices) {
|
|
||||||
return it[relIndex]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (intSize < 0 || index < intSize shr 1) {
|
|
||||||
var firstIndex = 0
|
|
||||||
for (entry in data.iterator()) {
|
|
||||||
if (index < firstIndex + entry.second.size && index >= firstIndex) {
|
|
||||||
lruGroup = entry.second
|
|
||||||
lruGroupKey = entry.first
|
|
||||||
lruGroupFirstIndex = firstIndex
|
|
||||||
return entry.second[index - firstIndex]
|
|
||||||
}
|
|
||||||
firstIndex += entry.second.size
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var lastIndex = intSize
|
|
||||||
for (entry in data.descendingIterator()) {
|
|
||||||
if (index < lastIndex && index >= lastIndex - entry.second.size) {
|
|
||||||
lruGroup = entry.second
|
|
||||||
lruGroupKey = entry.first
|
|
||||||
lruGroupFirstIndex = lastIndex - entry.second.size
|
|
||||||
return entry.second[index - lruGroupFirstIndex]
|
|
||||||
}
|
|
||||||
lastIndex -= entry.second.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw IndexOutOfBoundsException()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getOrNull(index: Int) = try {
|
|
||||||
get(index)
|
|
||||||
} catch (e: IndexOutOfBoundsException) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLastKey() = data.peekLast()?.first
|
|
||||||
|
|
||||||
fun getFirstKey() = data.peekFirst()?.first
|
|
||||||
|
|
||||||
fun getGroup(key: K): List<T>? {
|
|
||||||
if (key == lruGroupKey && lruGroup != null) {
|
|
||||||
return lruGroup
|
|
||||||
} else {
|
|
||||||
for(entry in data) {
|
|
||||||
if (entry.first == key) {
|
|
||||||
return entry.second
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getRelativeIndex(absIndex: Int): Int {
|
|
||||||
if (absIndex >= lruGroupFirstIndex) {
|
|
||||||
val relIndex = absIndex - lruGroupFirstIndex
|
|
||||||
lruGroup?.let {
|
|
||||||
if (relIndex in it.indices) {
|
|
||||||
return relIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (intSize < 0 || absIndex < intSize shr 1) {
|
|
||||||
var firstIndex = 0
|
|
||||||
for (entry in data.iterator()) {
|
|
||||||
if (absIndex < firstIndex + entry.second.size && absIndex >= firstIndex) {
|
|
||||||
return absIndex - firstIndex
|
|
||||||
}
|
|
||||||
firstIndex += entry.second.size
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var lastIndex = intSize
|
|
||||||
for (entry in data.descendingIterator()) {
|
|
||||||
if (absIndex < lastIndex && absIndex >= lastIndex - entry.second.size) {
|
|
||||||
return absIndex - lruGroupFirstIndex
|
|
||||||
}
|
|
||||||
lastIndex -= entry.second.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
fun findGroupByIndex(absIndex: Int): K? {
|
|
||||||
if (absIndex >= lruGroupFirstIndex && lruGroupKey != null) {
|
|
||||||
val relIndex = absIndex - lruGroupFirstIndex
|
|
||||||
lruGroup?.let {
|
|
||||||
if (relIndex in it.indices) {
|
|
||||||
return lruGroupKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (intSize < 0 || absIndex < intSize shr 1) {
|
|
||||||
var firstIndex = 0
|
|
||||||
for (entry in data.iterator()) {
|
|
||||||
if (absIndex < firstIndex + entry.second.size && absIndex >= firstIndex) {
|
|
||||||
return entry.first
|
|
||||||
}
|
|
||||||
firstIndex += entry.second.size
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var lastIndex = intSize
|
|
||||||
for (entry in data.descendingIterator()) {
|
|
||||||
if (absIndex < lastIndex && absIndex >= lastIndex - entry.second.size) {
|
|
||||||
return entry.first
|
|
||||||
}
|
|
||||||
lastIndex -= entry.second.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGroupOffset(key: K): Int {
|
|
||||||
if (lruGroupKey == key && lruGroupFirstIndex >= 0) {
|
|
||||||
return lruGroupFirstIndex
|
|
||||||
}
|
|
||||||
var offset = 0
|
|
||||||
for (entry in data) {
|
|
||||||
if (entry.first == key) {
|
|
||||||
return offset
|
|
||||||
}
|
|
||||||
offset += entry.second.size
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
fun indexOf(item: T): Int {
|
|
||||||
var offset = 0
|
|
||||||
for ((_, list) in data) {
|
|
||||||
for ((i, x) in list.withIndex()) {
|
|
||||||
if (x == item) {
|
|
||||||
return i + offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
offset += list.size
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addLast(key: K, items: List<T>) {
|
|
||||||
data.addLast(key to items.toList())
|
|
||||||
if (intSize < 0) {
|
|
||||||
computeSize()
|
|
||||||
} else {
|
|
||||||
intSize += items.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addFirst(key: K, items: List<T>) {
|
|
||||||
data.addFirst(key to items.toList())
|
|
||||||
if (lruGroupFirstIndex >= 0) {
|
|
||||||
lruGroupFirstIndex += items.size
|
|
||||||
}
|
|
||||||
if (intSize < 0) {
|
|
||||||
computeSize()
|
|
||||||
} else {
|
|
||||||
intSize += items.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeLast(): List<T> {
|
|
||||||
val item = data.removeLast()
|
|
||||||
if (intSize < 0) {
|
|
||||||
computeSize()
|
|
||||||
} else {
|
|
||||||
intSize -= item.second.size
|
|
||||||
}
|
|
||||||
return item.second
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeFirst(): List<T> {
|
|
||||||
val item = data.removeFirst()
|
|
||||||
if (intSize < 0) {
|
|
||||||
computeSize()
|
|
||||||
} else {
|
|
||||||
intSize -= item.second.size
|
|
||||||
}
|
|
||||||
if (lruGroupFirstIndex >= 0) {
|
|
||||||
lruGroupFirstIndex -= item.second.size
|
|
||||||
}
|
|
||||||
return item.second
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clear() {
|
|
||||||
data.clear()
|
|
||||||
intSize = 0
|
|
||||||
lruGroupFirstIndex = -1
|
|
||||||
lruGroup = null
|
|
||||||
lruGroupKey = null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun computeSize() {
|
|
||||||
intSize = data.sumBy { it.second.size }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.reader.base
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaPage
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class ReaderPage(
|
||||||
|
val id: Long,
|
||||||
|
val url: String,
|
||||||
|
val preview: String?,
|
||||||
|
val chapterId: Long,
|
||||||
|
val index: Int,
|
||||||
|
val source: MangaSource
|
||||||
|
) : Parcelable {
|
||||||
|
|
||||||
|
fun toMangaPage() = MangaPage(
|
||||||
|
id = id,
|
||||||
|
url = url,
|
||||||
|
preview = preview,
|
||||||
|
source = source
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun from(page: MangaPage, index: Int, chapterId: Long) = ReaderPage(
|
||||||
|
id = page.id,
|
||||||
|
url = page.url,
|
||||||
|
preview = page.preview,
|
||||||
|
chapterId = chapterId,
|
||||||
|
index = index,
|
||||||
|
source = page.source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue