Skip to content

Instantly share code, notes, and snippets.

@ToastShaman
Created October 15, 2021 06:21
Show Gist options
  • Save ToastShaman/7e0bbf0ba6de08a902bb62821c21a2bb to your computer and use it in GitHub Desktop.
Save ToastShaman/7e0bbf0ba6de08a902bb62821c21a2bb to your computer and use it in GitHub Desktop.
DynamoDB Pagination
// 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