
com.github.mvysny.vokdataloader.ChunkFetchingLoader.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vok-dataloader Show documentation
Show all versions of vok-dataloader Show documentation
VOK-DataLoader: The Paged/Filtered/Sorted DataLoader API
package com.github.mvysny.vokdataloader
/**
* Overcomes a natural limit of the number of items which [delegate] can fetch (via [DataLoader.fetch]). If more items are requested,
* this data loader polls the delegate in chunks and reconstructs the result. Ideal for REST endpoints which are often
* limited in how many items they can fetch.
* @property delegate the data loader which imposes limit on the number of data fetched
* @property delegateFetchLimit the known limit of items which the delegate can fetch, 1 or more.
*/
class ChunkFetchingLoader(val delegate: DataLoader, val delegateFetchLimit: Long) : DataLoader {
init {
require(delegateFetchLimit >= 1) { "delegateFetchLimit should be 1 or more but was $delegateFetchLimit" }
}
override fun toString() = "ChunkFetchingLoader(delegateFetchLimit=$delegateFetchLimit, delegate=$delegate)"
override fun fetch(filter: Filter?, sortBy: List, range: LongRange): List {
if (range.isEmpty()) return listOf()
require(range.start >= 0) { "range $range contains negative indices" }
val result = mutableListOf()
while(result.size < range.length) {
val itemsToFetch = (range.length - result.size).coerceAtMost(delegateFetchLimit)
val offset = range.start + result.size
val fetchRange = offset until (offset + itemsToFetch)
val fetched = delegate.fetch(filter, sortBy, fetchRange)
result.addAll(fetched)
if (fetched.size < itemsToFetch) {
// we probably hit an end of this data loader, bail out
break
}
}
return result
}
override fun getCount(filter: Filter?): Long = delegate.getCount(filter)
}
/**
* Overcomes a natural limit of the number of items which [this] can fetch (via [DataLoader.fetch]). If more items are requested,
* the returned data loader polls [this] in chunks and reconstructs the result. Ideal for REST endpoints which are often
* limited in how many items they can fetch.
* @param delegateFetchLimit the known limit of items which the delegate can fetch, 1 or more.
*/
fun DataLoader.limitChunkSize(delegateFetchLimit: Long): DataLoader =
ChunkFetchingLoader(this, delegateFetchLimit)
© 2015 - 2025 Weber Informatics LLC | Privacy Policy