From e22595339e1c5eeffceee8c2ee2d6173e0d5cc1c Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 14 Oct 2020 19:37:25 +0600 Subject: [PATCH] add MapOneToManyKeyValueRepo --- .../pagination/PaginationResult.kt | 2 + .../repos/OneToManyKeyValueRepo.kt | 5 ++ .../repos/MapOneToManyKeyValueRepo.kt | 82 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt diff --git a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/PaginationResult.kt b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/PaginationResult.kt index 608f0aaf750..35c3f3939a8 100644 --- a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/PaginationResult.kt +++ b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/PaginationResult.kt @@ -10,6 +10,8 @@ data class PaginationResult( override val size: Int ) : Pagination +fun emptyPaginationResult() = PaginationResult(0, 0, emptyList(), 0) + fun List.createPaginationResult( pagination: Pagination, commonObjectsNumber: Long diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/OneToManyKeyValueRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/OneToManyKeyValueRepo.kt index 8cd84aa7bb8..71d34a5b5ef 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/OneToManyKeyValueRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/OneToManyKeyValueRepo.kt @@ -2,6 +2,7 @@ package dev.inmo.micro_utils.repos import dev.inmo.micro_utils.pagination.Pagination import dev.inmo.micro_utils.pagination.PaginationResult +import kotlinx.coroutines.flow.Flow interface OneToManyReadKeyValueRepo : Repo { suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult @@ -13,6 +14,10 @@ interface OneToManyReadKeyValueRepo : Repo { } interface OneToManyWriteKeyValueRepo : Repo { + val onNewValue: Flow> + val onValueRemoved: Flow> + val onDataCleared: Flow + suspend fun add(k: Key, v: Value) suspend fun remove(k: Key, v: Value) suspend fun clear(k: Key) diff --git a/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt b/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt new file mode 100644 index 00000000000..2b182615901 --- /dev/null +++ b/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt @@ -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( + private val map: Map> = emptyMap() +) : OneToManyReadKeyValueRepo { + override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult { + 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 { + 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( + private val map: MutableMap> = mutableMapOf() +) : OneToManyWriteKeyValueRepo { + private val _onNewValue: BroadcastFlow> = BroadcastFlow() + override val onNewValue: Flow> + get() = _onNewValue + private val _onValueRemoved: BroadcastFlow> = BroadcastFlow() + override val onValueRemoved: Flow> + get() = _onValueRemoved + private val _onDataCleared: BroadcastFlow = BroadcastFlow() + override val onDataCleared: Flow + 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( + private val map: MutableMap> = mutableMapOf() +) : OneToManyKeyValueRepo, + OneToManyReadKeyValueRepo by ReadOneToManyKeyValueRepo(map), + OneToManyWriteKeyValueRepo by WriteOneToManyKeyValueRepo(map) + +fun MutableMap>.asOneToManyKeyValueRepo(): OneToManyKeyValueRepo = MapOneToManyKeyValueRepo( + map { (k, v) -> k to v.toMutableList() }.toMap().toMutableMap() +)