-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement RealMutablePagingBuffer (#623)
Signed-off-by: mramotar <mramotar@dropbox.com>
- Loading branch information
1 parent
f6df164
commit 4c190a2
Showing
2 changed files
with
100 additions
and
0 deletions.
There are no files selected for viewing
93 changes: 93 additions & 0 deletions
93
.../commonMain/kotlin/org/mobilenativefoundation/paging/core/impl/RealMutablePagingBuffer.kt
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package org.mobilenativefoundation.paging.core.impl | ||
|
||
import org.mobilenativefoundation.paging.core.MutablePagingBuffer | ||
import org.mobilenativefoundation.paging.core.PagingKey | ||
import org.mobilenativefoundation.paging.core.PagingSource | ||
|
||
/** | ||
* A concrete implementation of [MutablePagingBuffer], a custom data structure for efficiently storing and retrieving paging data. | ||
* | ||
* @param Id The type of the unique identifier for each item in the paged data. | ||
* @param K The type of the key used for paging. | ||
* @param P The type of the parameters associated with each page of data. | ||
* @param D The type of the data items. | ||
* @param E The type of errors that can occur during the paging process. | ||
* @param A The type of custom actions that can be dispatched to modify the paging state. | ||
* @property maxSize The maximum size of the buffer. | ||
*/ | ||
class RealMutablePagingBuffer<Id : Comparable<Id>, K : Any, P : Any, D : Any, E : Any, A : Any>( | ||
private val maxSize: Int | ||
) : MutablePagingBuffer<Id, K, P, D> { | ||
|
||
private val buffer: Array<PagingSource.LoadResult.Data<Id, K, P, D>?> = arrayOfNulls(maxSize) | ||
private val paramsToIndex: MutableMap<PagingSource.LoadParams<K, P>, Int> = mutableMapOf() | ||
private val keyToIndex: MutableMap<PagingKey<K, P>, Int> = mutableMapOf() | ||
private var head = 0 | ||
private var tail = 0 | ||
private var size = 0 | ||
|
||
override fun get(params: PagingSource.LoadParams<K, P>): PagingSource.LoadResult.Data<Id, K, P, D>? { | ||
val index = paramsToIndex[params] | ||
return if (index != null) buffer[index] else null | ||
} | ||
|
||
|
||
override fun get(key: PagingKey<K, P>): PagingSource.LoadResult.Data<Id, K, P, D>? { | ||
val index = keyToIndex[key] | ||
return if (index != null) buffer[index] else null | ||
} | ||
|
||
|
||
override fun put(params: PagingSource.LoadParams<K, P>, page: PagingSource.LoadResult.Data<Id, K, P, D>) { | ||
// Check if the buffer is full | ||
if (size == maxSize) { | ||
// Get the index of the oldest entry in the buffer | ||
val oldestIndex = head | ||
// Find the params associated with the oldest entry | ||
val oldestParams = paramsToIndex.entries.first { it.value == oldestIndex }.key | ||
// Remove the oldest entry from the maps | ||
paramsToIndex.remove(oldestParams) | ||
keyToIndex.remove(oldestParams.key) | ||
// Remove the oldest entry from the buffer | ||
buffer[oldestIndex] = null | ||
// Update the head index to point to the next entry | ||
head = (head + 1) % maxSize | ||
} | ||
// Get the index to insert the new page | ||
val index = tail | ||
// Insert the new page at the tail index | ||
buffer[index] = page | ||
// Update the maps with the new entry | ||
paramsToIndex[params] = index | ||
keyToIndex[params.key] = index | ||
// Update the tail index to point to the next empty slot | ||
tail = (tail + 1) % maxSize | ||
// Update the size of the buffer | ||
size = minOf(size + 1, maxSize) | ||
} | ||
|
||
override fun head(): PagingSource.LoadResult.Data<Id, K, P, D>? { | ||
return buffer[head] | ||
} | ||
|
||
override fun getAll(): List<PagingSource.LoadResult.Data<Id, K, P, D>> { | ||
val pages = mutableListOf<PagingSource.LoadResult.Data<Id, K, P, D>>() | ||
var index = head | ||
var count = 0 | ||
while (count < size) { | ||
val page = buffer[index] | ||
if (page != null) { | ||
pages.add(page) | ||
} | ||
index = (index + 1) % maxSize | ||
count++ | ||
} | ||
return pages | ||
} | ||
|
||
override fun isEmpty(): Boolean = size == 0 | ||
|
||
override fun indexOf(key: PagingKey<K, P>): Int { | ||
return keyToIndex[key] ?: -1 | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
...ore/src/commonMain/kotlin/org/mobilenativefoundation/paging/core/mutablePagingBufferOf.kt
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.mobilenativefoundation.paging.core | ||
|
||
import org.mobilenativefoundation.paging.core.impl.RealMutablePagingBuffer | ||
|
||
inline fun <Id : Comparable<Id>, K : Any, P : Any, D : Any, E : Any, A : Any> mutablePagingBufferOf(maxSize: Int): MutablePagingBuffer<Id, K, P, D> { | ||
return RealMutablePagingBuffer<Id, K, P, D, E, A>(maxSize) | ||
} |