Created
April 8, 2025 02:47
-
-
Save mrenouf/3bd802e06e7b5fb10594c5e96018669e to your computer and use it in GitHub Desktop.
Flow window function for log event flows -> lazy list UI
This file contains hidden or 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
package com.android.atool.ui | |
import kotlinx.coroutines.channels.BufferOverflow.DROP_LATEST | |
import kotlinx.coroutines.flow.buffer | |
import kotlinx.coroutines.flow.channelFlow | |
import kotlinx.coroutines.flow.Flow | |
/** | |
* Creates a [Flow] that emits sliding windows of the elements from the original [Flow]. | |
* Each emitted list represents a window of the specified [length]. The window starts with | |
* the first emitted value, emitting a list of size 1, and grows until it reaches [length]. | |
* | |
* The window slides by one element at a time. For example, if the original flow | |
* emits `[1, 2, 3, 4, 5]` and `length` is 3, the resulting flow will emit: | |
* `[1]`, `[1, 2]`, `[1, 2, 3]`, `[2, 3, 4]`, `[3, 4, 5]`. | |
* | |
* The latest result is buffered and replaced as needed to avoid overwhelming | |
* downstream collectors when the source flow produces rapidly. | |
* | |
* @param length The size of each window. Must be greater than 0. | |
* @return A [Flow] emitting lists of size [length], representing the sliding windows. | |
* @throws IllegalArgumentException if [length] is not greater than 0. | |
*/ | |
fun <T> Flow<T>.window(length: Int): Flow<List<T>> { | |
require(length > 0) { "length must be greater than 0, but was $length" } | |
return channelFlow { | |
val buffer = ArrayDeque<T>(maxOf(length + 1, 16)) | |
this@window.collect { value -> | |
buffer.addLast(value) | |
if (buffer.size > length) { | |
buffer.removeFirst() | |
} | |
send(buffer.toList()) | |
} | |
} | |
.buffer(capacity = 1, onBufferOverflow = DROP_LATEST) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment