mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-17 19:58:57 +03:00
Create getBetsChunkSize to avoid code duplication
This commit is contained in:
parent
9946ba8aa4
commit
103ba463c3
4 changed files with 129 additions and 14 deletions
|
@ -29,12 +29,12 @@ import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo
|
|||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||
import org.matrix.android.sdk.internal.network.executeRequest
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import org.matrix.android.sdk.internal.util.getBetsChunkSize
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.ceil
|
||||
|
||||
internal interface DownloadKeysForUsersTask : Task<DownloadKeysForUsersTask.Params, KeysQueryResponse> {
|
||||
data class Params(
|
||||
// the list of users to get keys for.
|
||||
// the list of users to get keys for. The list MUST NOT be empty
|
||||
val userIds: List<String>,
|
||||
// the up-to token
|
||||
val token: String?
|
||||
|
@ -47,8 +47,7 @@ internal class DefaultDownloadKeysForUsers @Inject constructor(
|
|||
) : DownloadKeysForUsersTask {
|
||||
|
||||
override suspend fun execute(params: DownloadKeysForUsersTask.Params): KeysQueryResponse {
|
||||
val numberOfChunks = ceil(params.userIds.size / LIMIT.toDouble()).toInt().coerceAtLeast(1)
|
||||
val chunkSize = params.userIds.size / numberOfChunks
|
||||
val bestChunkSize = getBetsChunkSize(params.userIds.size, LIMIT)
|
||||
|
||||
// Store server results in these mutable maps
|
||||
val deviceKeys = mutableMapOf<String, Map<String, DeviceKeysWithUnsigned>>()
|
||||
|
@ -62,7 +61,7 @@ internal class DefaultDownloadKeysForUsers @Inject constructor(
|
|||
// Split network request into smaller request (#2925)
|
||||
coroutineScope {
|
||||
params.userIds
|
||||
.chunked(chunkSize)
|
||||
.chunked(bestChunkSize.chunkSize)
|
||||
.map {
|
||||
KeysQueryBody(
|
||||
deviceKeys = it.associateWith { emptyList() },
|
||||
|
|
|
@ -64,9 +64,9 @@ import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral
|
|||
import org.matrix.android.sdk.internal.session.sync.model.RoomSync
|
||||
import org.matrix.android.sdk.internal.session.sync.model.RoomSyncAccountData
|
||||
import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse
|
||||
import org.matrix.android.sdk.internal.util.getBetsChunkSize
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.ceil
|
||||
|
||||
internal class RoomSyncHandler @Inject constructor(private val readReceiptHandler: ReadReceiptHandler,
|
||||
private val roomSummaryUpdater: RoomSummaryUpdater,
|
||||
|
@ -140,17 +140,17 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
|||
syncLocalTimeStampMillis: Long,
|
||||
aggregator: SyncResponsePostTreatmentAggregator,
|
||||
reporter: ProgressReporter?) {
|
||||
val maxSize = (initialSyncStrategy as? InitialSyncStrategy.Optimized)?.maxRoomsToInsert ?: Int.MAX_VALUE
|
||||
val listSize = handlingStrategy.data.keys.size
|
||||
val numberOfChunks = ceil(listSize / maxSize.toDouble()).toInt()
|
||||
val bestChunkSize = getBetsChunkSize(
|
||||
listSize = handlingStrategy.data.keys.size,
|
||||
limit = (initialSyncStrategy as? InitialSyncStrategy.Optimized)?.maxRoomsToInsert ?: Int.MAX_VALUE
|
||||
)
|
||||
|
||||
if (numberOfChunks > 1) {
|
||||
reportSubtask(reporter, InitSyncStep.ImportingAccountJoinedRooms, numberOfChunks, 0.6f) {
|
||||
val chunkSize = listSize / numberOfChunks
|
||||
Timber.d("INIT_SYNC $listSize rooms to insert, split into $numberOfChunks sublists of $chunkSize items")
|
||||
if (bestChunkSize.shouldSplit()) {
|
||||
reportSubtask(reporter, InitSyncStep.ImportingAccountJoinedRooms, bestChunkSize.numberOfChunks, 0.6f) {
|
||||
Timber.d("INIT_SYNC ${handlingStrategy.data.keys.size} rooms to insert, split with $bestChunkSize")
|
||||
// I cannot find a better way to chunk a map, so chunk the keys and then create new maps
|
||||
handlingStrategy.data.keys
|
||||
.chunked(chunkSize)
|
||||
.chunked(bestChunkSize.chunkSize)
|
||||
.forEachIndexed { index, roomIds ->
|
||||
val roomEntities = roomIds
|
||||
.also { Timber.d("INIT_SYNC insert ${roomIds.size} rooms") }
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2021 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.util
|
||||
|
||||
import kotlin.math.ceil
|
||||
|
||||
internal data class BestChunkSize(
|
||||
val numberOfChunks: Int,
|
||||
val chunkSize: Int
|
||||
) {
|
||||
fun shouldSplit() = numberOfChunks > 1
|
||||
}
|
||||
|
||||
internal fun getBetsChunkSize(listSize: Int, limit: Int): BestChunkSize {
|
||||
return if (listSize <= limit) {
|
||||
BestChunkSize(
|
||||
numberOfChunks = 1,
|
||||
chunkSize = listSize
|
||||
)
|
||||
} else {
|
||||
val numberOfChunks = ceil(listSize / limit.toDouble()).toInt()
|
||||
val chunkSize = listSize / numberOfChunks
|
||||
|
||||
BestChunkSize(
|
||||
numberOfChunks = numberOfChunks,
|
||||
chunkSize = chunkSize
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.util
|
||||
|
||||
import org.amshove.kluent.shouldBeEqualTo
|
||||
import org.amshove.kluent.shouldHaveSize
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Test
|
||||
import org.junit.runners.MethodSorters
|
||||
import org.matrix.android.sdk.MatrixTest
|
||||
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
class MathUtilTest : MatrixTest {
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize0() = doTest(0, 100, 1, 0)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize1() = doTest(1, 100, 1, 1)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize5() = doTest(5, 100, 1, 5)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize99() = doTest(99, 100, 1, 99)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize100() = doTest(100, 100, 1, 100)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize101() = doTest(101, 100, 2, 50)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize199() = doTest(199, 100, 2, 99)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize200() = doTest(200, 100, 2, 100)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize201() = doTest(201, 100, 3, 67)
|
||||
|
||||
@Test
|
||||
fun testGetBestChunkSize240() = doTest(240, 100, 3, 80)
|
||||
|
||||
private fun doTest(listSize: Int, limit: Int, expectedNumberOfChunks: Int, expectedChunkSize: Int) {
|
||||
val result = getBetsChunkSize(listSize, limit)
|
||||
|
||||
result.numberOfChunks shouldBeEqualTo expectedNumberOfChunks
|
||||
result.chunkSize shouldBeEqualTo expectedChunkSize
|
||||
|
||||
// Test that the result make sense, when we use chunked()
|
||||
if (result.chunkSize > 0) {
|
||||
generateSequence { "a" }
|
||||
.take(listSize)
|
||||
.chunked(result.chunkSize)
|
||||
.shouldHaveSize(result.numberOfChunks)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue