All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mvysny.vokdataloader.ChunkFetchingLoader.kt Maven / Gradle / Ivy

There is a newer version: 0.9.1
Show newest version
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