mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-11-22 16:23:50 +00:00
add MapOneToManyKeyValueRepo
This commit is contained in:
parent
8461ff4d38
commit
e22595339e
@ -10,6 +10,8 @@ data class PaginationResult<T>(
|
|||||||
override val size: Int
|
override val size: Int
|
||||||
) : Pagination
|
) : Pagination
|
||||||
|
|
||||||
|
fun <T> emptyPaginationResult() = PaginationResult<T>(0, 0, emptyList(), 0)
|
||||||
|
|
||||||
fun <T> List<T>.createPaginationResult(
|
fun <T> List<T>.createPaginationResult(
|
||||||
pagination: Pagination,
|
pagination: Pagination,
|
||||||
commonObjectsNumber: Long
|
commonObjectsNumber: Long
|
||||||
|
@ -2,6 +2,7 @@ package dev.inmo.micro_utils.repos
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.Pagination
|
import dev.inmo.micro_utils.pagination.Pagination
|
||||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface OneToManyReadKeyValueRepo<Key, Value> : Repo {
|
interface OneToManyReadKeyValueRepo<Key, Value> : Repo {
|
||||||
suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
|
suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
|
||||||
@ -13,6 +14,10 @@ interface OneToManyReadKeyValueRepo<Key, Value> : Repo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface OneToManyWriteKeyValueRepo<Key, Value> : Repo {
|
interface OneToManyWriteKeyValueRepo<Key, Value> : Repo {
|
||||||
|
val onNewValue: Flow<Pair<Key, Value>>
|
||||||
|
val onValueRemoved: Flow<Pair<Key, Value>>
|
||||||
|
val onDataCleared: Flow<Key>
|
||||||
|
|
||||||
suspend fun add(k: Key, v: Value)
|
suspend fun add(k: Key, v: Value)
|
||||||
suspend fun remove(k: Key, v: Value)
|
suspend fun remove(k: Key, v: Value)
|
||||||
suspend fun clear(k: Key)
|
suspend fun clear(k: Key)
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package dev.inmo.micro_utils.repos
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.BroadcastFlow
|
||||||
|
import dev.inmo.micro_utils.pagination.*
|
||||||
|
import dev.inmo.micro_utils.pagination.utils.paginate
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class ReadOneToManyKeyValueRepo<Key, Value>(
|
||||||
|
private val map: Map<Key, List<Value>> = emptyMap()
|
||||||
|
) : OneToManyReadKeyValueRepo<Key, Value> {
|
||||||
|
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> {
|
||||||
|
val list = map[k] ?: return emptyPaginationResult()
|
||||||
|
|
||||||
|
return list.paginate(
|
||||||
|
if (reversed) {
|
||||||
|
val firstIndex = (map.size - pagination.lastIndex).let { if (it < 0) 0 else it }
|
||||||
|
SimplePagination(firstIndex, pagination.size)
|
||||||
|
} else {
|
||||||
|
pagination
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
|
||||||
|
val firstIndex: Int = if (reversed) {
|
||||||
|
val size = map.size
|
||||||
|
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
|
||||||
|
} else {
|
||||||
|
pagination.firstIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
return map.keys.drop(firstIndex).take(pagination.size).createPaginationResult(
|
||||||
|
firstIndex,
|
||||||
|
count()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun contains(k: Key): Boolean = map.containsKey(k)
|
||||||
|
|
||||||
|
override suspend fun contains(k: Key, v: Value): Boolean = map[k] ?.contains(v) == true
|
||||||
|
|
||||||
|
override suspend fun count(k: Key): Long = map[k] ?.size ?.toLong() ?: 0L
|
||||||
|
|
||||||
|
override suspend fun count(): Long = map.size.toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
class WriteOneToManyKeyValueRepo<Key, Value>(
|
||||||
|
private val map: MutableMap<Key, MutableList<Value>> = mutableMapOf()
|
||||||
|
) : OneToManyWriteKeyValueRepo<Key, Value> {
|
||||||
|
private val _onNewValue: BroadcastFlow<Pair<Key, Value>> = BroadcastFlow()
|
||||||
|
override val onNewValue: Flow<Pair<Key, Value>>
|
||||||
|
get() = _onNewValue
|
||||||
|
private val _onValueRemoved: BroadcastFlow<Pair<Key, Value>> = BroadcastFlow()
|
||||||
|
override val onValueRemoved: Flow<Pair<Key, Value>>
|
||||||
|
get() = _onValueRemoved
|
||||||
|
private val _onDataCleared: BroadcastFlow<Key> = BroadcastFlow()
|
||||||
|
override val onDataCleared: Flow<Key>
|
||||||
|
get() = _onDataCleared
|
||||||
|
|
||||||
|
override suspend fun add(k: Key, v: Value) {
|
||||||
|
map.getOrPut(k) { mutableListOf() }.add(v)
|
||||||
|
_onNewValue.send(k to v)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun remove(k: Key, v: Value) {
|
||||||
|
map[k] ?.remove(v) ?.also { _onValueRemoved.send(k to v) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun clear(k: Key) {
|
||||||
|
map.remove(k) ?.also { _onDataCleared.send(k) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MapOneToManyKeyValueRepo<Key, Value>(
|
||||||
|
private val map: MutableMap<Key, MutableList<Value>> = mutableMapOf()
|
||||||
|
) : OneToManyKeyValueRepo<Key, Value>,
|
||||||
|
OneToManyReadKeyValueRepo<Key, Value> by ReadOneToManyKeyValueRepo(map),
|
||||||
|
OneToManyWriteKeyValueRepo<Key, Value> by WriteOneToManyKeyValueRepo(map)
|
||||||
|
|
||||||
|
fun <K, V> MutableMap<K, List<V>>.asOneToManyKeyValueRepo(): OneToManyKeyValueRepo<K, V> = MapOneToManyKeyValueRepo(
|
||||||
|
map { (k, v) -> k to v.toMutableList() }.toMap().toMutableMap()
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user