MicroUtils/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt

106 lines
3.9 KiB
Kotlin
Raw Normal View History

2020-10-14 13:37:25 +00:00
package dev.inmo.micro_utils.repos
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.pagination.utils.paginate
2020-10-22 09:47:28 +00:00
import dev.inmo.micro_utils.pagination.utils.reverse
2020-11-08 18:51:08 +00:00
import kotlinx.coroutines.flow.*
2020-10-14 13:37:25 +00:00
2020-10-14 16:02:10 +00:00
class MapReadOneToManyKeyValueRepo<Key, Value>(
2020-10-14 13:37:25 +00:00
private val map: Map<Key, List<Value>> = emptyMap()
2020-10-14 16:02:10 +00:00
) : ReadOneToManyKeyValueRepo<Key, Value> {
2020-10-14 13:37:25 +00:00
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> {
val list = map[k] ?: return emptyPaginationResult()
return list.paginate(
if (reversed) {
2020-10-22 09:47:28 +00:00
pagination.reverse(list.size)
2020-10-14 13:37:25 +00:00
} else {
pagination
}
)
}
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
2020-10-22 09:47:28 +00:00
val keys = map.keys
val actualPagination = if (reversed) pagination.reverse(keys.size) else pagination
return keys.paginate(actualPagination).let {
if (reversed) {
it.copy(results = it.results.reversed())
} else {
it
}
2020-10-14 13:37:25 +00:00
}
}
2020-11-14 10:44:28 +00:00
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
val keys = map.keys.filter { map[it] ?.contains(v) == true }
val actualPagination = if (reversed) pagination.reverse(keys.size) else pagination
return keys.paginate(actualPagination).let {
if (reversed) {
it.copy(results = it.results.reversed())
} else {
it
}
}
}
2020-10-14 13:37:25 +00:00
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()
}
2020-10-14 16:02:10 +00:00
class MapWriteOneToManyKeyValueRepo<Key, Value>(
2020-10-14 13:37:25 +00:00
private val map: MutableMap<Key, MutableList<Value>> = mutableMapOf()
2020-10-14 16:02:10 +00:00
) : WriteOneToManyKeyValueRepo<Key, Value> {
2020-11-08 18:46:26 +00:00
private val _onNewValue: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
2020-11-08 18:51:08 +00:00
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
2020-11-08 18:46:26 +00:00
private val _onValueRemoved: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
2020-11-08 18:51:08 +00:00
override val onValueRemoved: Flow<Pair<Key, Value>> = _onValueRemoved.asSharedFlow()
2020-11-08 18:46:26 +00:00
private val _onDataCleared: MutableSharedFlow<Key> = MutableSharedFlow()
2020-11-08 18:51:08 +00:00
override val onDataCleared: Flow<Key> = _onDataCleared.asSharedFlow()
2020-10-14 13:37:25 +00:00
2020-11-06 20:25:50 +00:00
override suspend fun add(toAdd: Map<Key, List<Value>>) {
2020-11-08 18:46:26 +00:00
toAdd.keys.forEach { k ->
if (map.getOrPut(k) { mutableListOf() }.addAll(toAdd[k] ?: return@forEach)) {
toAdd[k] ?.forEach { v ->
_onNewValue.emit(k to v)
}
}
2020-11-06 20:25:50 +00:00
}
2020-10-14 13:37:25 +00:00
}
2020-11-06 20:25:50 +00:00
override suspend fun remove(toRemove: Map<Key, List<Value>>) {
2020-11-08 18:46:26 +00:00
toRemove.keys.forEach { k ->
if (map[k] ?.removeAll(toRemove[k] ?: return@forEach) == true) {
toRemove[k] ?.forEach { v ->
_onValueRemoved.emit(k to v)
}
}
2020-11-06 20:25:50 +00:00
}
2020-10-14 13:37:25 +00:00
}
override suspend fun clear(k: Key) {
2020-11-08 18:46:26 +00:00
map.remove(k) ?.also { _onDataCleared.emit(k) }
2020-10-14 13:37:25 +00:00
}
2021-06-15 08:24:00 +00:00
override suspend fun clearWithValue(v: Value) {
map.forEach { (k, values) ->
if (values.remove(v)) _onValueRemoved.emit(k to v)
}
}
2020-10-14 13:37:25 +00:00
}
class MapOneToManyKeyValueRepo<Key, Value>(
private val map: MutableMap<Key, MutableList<Value>> = mutableMapOf()
) : OneToManyKeyValueRepo<Key, Value>,
2020-10-14 16:02:10 +00:00
ReadOneToManyKeyValueRepo<Key, Value> by MapReadOneToManyKeyValueRepo(map),
WriteOneToManyKeyValueRepo<Key, Value> by MapWriteOneToManyKeyValueRepo(map)
2020-10-14 13:37:25 +00:00
fun <K, V> MutableMap<K, List<V>>.asOneToManyKeyValueRepo(): OneToManyKeyValueRepo<K, V> = MapOneToManyKeyValueRepo(
map { (k, v) -> k to v.toMutableList() }.toMap().toMutableMap()
)