mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-29 14:38:45 +03:00
Timeline : clean after PR reviews
This commit is contained in:
parent
1280687640
commit
12b775c26d
7 changed files with 19 additions and 106 deletions
1
changelog.d/4405.feature
Normal file
1
changelog.d/4405.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Change internal timeline management.
|
1
changelog.d/4405.removal
Normal file
1
changelog.d/4405.removal
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Introduce method onStateUpdated on Timeline.Callback
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.database
|
|
||||||
|
|
||||||
import io.realm.RealmConfiguration
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.matrix.android.sdk.api.session.Session
|
|
||||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomEntity
|
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
|
||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
private const val MAX_NUMBER_OF_EVENTS_IN_DB = 35_000L
|
|
||||||
private const val MIN_NUMBER_OF_EVENTS_BY_CHUNK = 300
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class makes sure to stay under a maximum number of events as it makes Realm to be unusable when listening to events
|
|
||||||
* when the database is getting too big. This will try incrementally to remove the biggest chunks until we get below the threshold.
|
|
||||||
* We make sure to still have a minimum number of events so it's not becoming unusable.
|
|
||||||
* So this won't work for users with a big number of very active rooms.
|
|
||||||
*/
|
|
||||||
internal class DatabaseCleaner @Inject constructor(@SessionDatabase private val realmConfiguration: RealmConfiguration,
|
|
||||||
private val taskExecutor: TaskExecutor) : SessionLifecycleObserver {
|
|
||||||
|
|
||||||
override fun onSessionStarted(session: Session) {
|
|
||||||
taskExecutor.executorScope.launch(Dispatchers.Default) {
|
|
||||||
awaitTransaction(realmConfiguration) { realm ->
|
|
||||||
val allRooms = realm.where(RoomEntity::class.java).findAll()
|
|
||||||
Timber.v("There are ${allRooms.size} rooms in this session")
|
|
||||||
// cleanUp(realm, MAX_NUMBER_OF_EVENTS_IN_DB / 2L)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
private fun cleanUp(realm: Realm, threshold: Long) {
|
|
||||||
val numberOfEvents = realm.where(EventEntity::class.java).findAll().size
|
|
||||||
val numberOfTimelineEvents = realm.where(TimelineEventEntity::class.java).findAll().size
|
|
||||||
Timber.v("Number of events in db: $numberOfEvents | Number of timeline events in db: $numberOfTimelineEvents")
|
|
||||||
if (threshold <= MIN_NUMBER_OF_EVENTS_BY_CHUNK || numberOfTimelineEvents < MAX_NUMBER_OF_EVENTS_IN_DB) {
|
|
||||||
Timber.v("Db is low enough")
|
|
||||||
} else {
|
|
||||||
val thresholdChunks = realm.where(ChunkEntity::class.java)
|
|
||||||
.greaterThan(ChunkEntityFields.NUMBER_OF_TIMELINE_EVENTS, threshold)
|
|
||||||
.findAll()
|
|
||||||
|
|
||||||
Timber.v("There are ${thresholdChunks.size} chunks to clean with more than $threshold events")
|
|
||||||
for (chunk in thresholdChunks) {
|
|
||||||
val maxDisplayIndex = chunk.nextDisplayIndex(PaginationDirection.FORWARDS)
|
|
||||||
val thresholdDisplayIndex = maxDisplayIndex - threshold
|
|
||||||
val eventsToRemove = chunk.timelineEvents.where().lessThan(TimelineEventEntityFields.DISPLAY_INDEX, thresholdDisplayIndex).findAll()
|
|
||||||
Timber.v("There are ${eventsToRemove.size} events to clean in chunk: ${chunk.identifier()} from room ${chunk.room?.first()?.roomId}")
|
|
||||||
//chunk.numberOfTimelineEvents = chunk.numberOfTimelineEvents - eventsToRemove.size
|
|
||||||
eventsToRemove.forEach {
|
|
||||||
val canDeleteRoot = it.root?.stateKey == null
|
|
||||||
it.deleteOnCascade(canDeleteRoot)
|
|
||||||
}
|
|
||||||
// We reset the prevToken so we will need to fetch again.
|
|
||||||
chunk.prevToken = null
|
|
||||||
}
|
|
||||||
cleanUp(realm, (threshold / 1.5).toLong())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
|
|
@ -31,7 +31,6 @@ internal open class ChunkEntity(@Index var prevToken: String? = null,
|
||||||
var nextChunk: ChunkEntity? = null,
|
var nextChunk: ChunkEntity? = null,
|
||||||
var stateEvents: RealmList<EventEntity> = RealmList(),
|
var stateEvents: RealmList<EventEntity> = RealmList(),
|
||||||
var timelineEvents: RealmList<TimelineEventEntity> = RealmList(),
|
var timelineEvents: RealmList<TimelineEventEntity> = RealmList(),
|
||||||
// var numberOfTimelineEvents: Long = 0,
|
|
||||||
// Only one chunk will have isLastForward == true
|
// Only one chunk will have isLastForward == true
|
||||||
@Index var isLastForward: Boolean = false,
|
@Index var isLastForward: Boolean = false,
|
||||||
@Index var isLastBackward: Boolean = false
|
@Index var isLastBackward: Boolean = false
|
||||||
|
|
|
@ -47,7 +47,6 @@ import org.matrix.android.sdk.internal.crypto.secrets.DefaultSharedSecretStorage
|
||||||
import org.matrix.android.sdk.internal.crypto.tasks.DefaultRedactEventTask
|
import org.matrix.android.sdk.internal.crypto.tasks.DefaultRedactEventTask
|
||||||
import org.matrix.android.sdk.internal.crypto.tasks.RedactEventTask
|
import org.matrix.android.sdk.internal.crypto.tasks.RedactEventTask
|
||||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationMessageProcessor
|
import org.matrix.android.sdk.internal.crypto.verification.VerificationMessageProcessor
|
||||||
import org.matrix.android.sdk.internal.database.DatabaseCleaner
|
|
||||||
import org.matrix.android.sdk.internal.database.EventInsertLiveObserver
|
import org.matrix.android.sdk.internal.database.EventInsertLiveObserver
|
||||||
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.SessionRealmConfigurationFactory
|
import org.matrix.android.sdk.internal.database.SessionRealmConfigurationFactory
|
||||||
|
@ -339,10 +338,6 @@ internal abstract class SessionModule {
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindIdentityService(service: DefaultIdentityService): SessionLifecycleObserver
|
abstract fun bindIdentityService(service: DefaultIdentityService): SessionLifecycleObserver
|
||||||
|
|
||||||
@Binds
|
|
||||||
@IntoSet
|
|
||||||
abstract fun bindDatabaseCleaner(cleaner: DatabaseCleaner): SessionLifecycleObserver
|
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindRealmSessionProvider(provider: RealmSessionProvider): SessionLifecycleObserver
|
abstract fun bindRealmSessionProvider(provider: RealmSessionProvider): SessionLifecycleObserver
|
||||||
|
|
|
@ -47,7 +47,7 @@ import java.util.concurrent.CopyOnWriteArrayList
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
internal class DefaultTimeline internal constructor(private val roomId: String,
|
internal class DefaultTimeline(private val roomId: String,
|
||||||
private val initialEventId: String?,
|
private val initialEventId: String?,
|
||||||
private val realmConfiguration: RealmConfiguration,
|
private val realmConfiguration: RealmConfiguration,
|
||||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||||
|
|
|
@ -48,9 +48,9 @@ internal class LoadTimelineStrategy(
|
||||||
private val mode: Mode,
|
private val mode: Mode,
|
||||||
private val dependencies: Dependencies) {
|
private val dependencies: Dependencies) {
|
||||||
|
|
||||||
sealed class Mode {
|
sealed interface Mode {
|
||||||
object Live : Mode()
|
object Live : Mode
|
||||||
data class Permalink(val originEventId: String) : Mode()
|
data class Permalink(val originEventId: String) : Mode
|
||||||
|
|
||||||
fun originEventId(): String? {
|
fun originEventId(): String? {
|
||||||
return if (this is Permalink) {
|
return if (this is Permalink) {
|
||||||
|
|
Loading…
Reference in a new issue