Created
October 15, 2021 06:21
-
-
Save ToastShaman/7e0bbf0ba6de08a902bb62821c21a2bb to your computer and use it in GitHub Desktop.
DynamoDB Pagination
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// uses value4k: https://github.com/fork-handles/forkhandles/tree/trunk/values4k | |
class PaginationToken private constructor(value: String) : StringValue(value) { | |
companion object : NonBlankStringValueFactory<PaginationToken>(::PaginationToken) | |
} | |
data class PagedResult<T>( | |
private val result: List<T> = emptyList(), | |
val token: PaginationToken? = null | |
) : List<T> by result { | |
companion object | |
} | |
/** | |
* Eagerly fetches additional results from DynamoDB until: | |
* - we retrieved more records than the configured limit | |
* - there aren't any more records available (pagination token is null) | |
*/ | |
fun <T> PagedResults( | |
limit: Long, | |
initialValue: PaginationToken? = null, | |
nextValue: (PaginationToken?) -> PagedResult<T> | |
): PagedResult<T> { | |
val runningTotal = AtomicInteger(0) | |
return generateSequence(nextValue(initialValue)) { | |
val total = runningTotal.addAndGet(it.size) | |
when { | |
total >= limit -> null | |
it.token == null -> null | |
else -> nextValue(it.token) | |
} | |
}.reduce { acc, b -> PagedResult(acc + b, b.token) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment