RealmLiveEntity: passes the results and changeSet instead of filtering as it's more efficient

This commit is contained in:
ganfra 2019-07-11 15:30:01 +02:00
parent 1b95336ad3
commit f493ce44f2
5 changed files with 47 additions and 44 deletions

View file

@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.database
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.OrderedCollectionChangeSet
import io.realm.OrderedRealmCollectionChangeListener
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.RealmObject
@ -33,7 +34,7 @@ internal interface LiveEntityObserver {
}
internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val realmConfiguration: RealmConfiguration)
: LiveEntityObserver {
: LiveEntityObserver, OrderedRealmCollectionChangeListener<RealmResults<T>> {
private companion object {
val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND")
@ -50,9 +51,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
val realm = Realm.getInstance(realmConfiguration)
backgroundRealm.set(realm)
val queryResults = query.createQuery(realm).findAll()
queryResults.addChangeListener { t, changeSet ->
onChanged(t, changeSet)
}
queryResults.addChangeListener(this)
results = AtomicReference(queryResults)
}
}
@ -73,19 +72,4 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
return isStarted.get()
}
private fun onChanged(realmResults: RealmResults<T>, changeSet: OrderedCollectionChangeSet) {
val insertionIndexes = changeSet.insertions
val updateIndexes = changeSet.changes
val deletionIndexes = changeSet.deletions
val inserted = realmResults.filterIndexed { index, _ -> insertionIndexes.contains(index) }
val updated = realmResults.filterIndexed { index, _ -> updateIndexes.contains(index) }
val deleted = realmResults.filterIndexed { index, _ -> deletionIndexes.contains(index) }
processChanges(inserted, updated, deleted)
}
/**
* Do quick treatment or delegate on a task
*/
protected abstract fun processChanges(inserted: List<T>, updated: List<T>, deleted: List<T>)
}

View file

@ -22,13 +22,20 @@ import androidx.work.WorkManager
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.model.GroupEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.room.prune.PruneEventTask
import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.worker.WorkManagerUtil
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import io.realm.OrderedCollectionChangeSet
import io.realm.RealmConfiguration
import io.realm.RealmResults
import timber.log.Timber
import javax.inject.Inject
private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
@ -40,8 +47,12 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
override val query = Monarchy.Query<GroupEntity> { GroupEntity.where(it) }
override fun processChanges(inserted: List<GroupEntity>, updated: List<GroupEntity>, deleted: List<GroupEntity>) {
val newGroupIds = inserted.map { it.groupId }
override fun onChange(results: RealmResults<GroupEntity>, changeSet: OrderedCollectionChangeSet) {
val newGroupIds = changeSet.insertions
.asSequence()
.mapNotNull { results[it]?.groupId}
.toList()
val getGroupDataWorkerParams = GetGroupDataWorker.Params(credentials.userId, newGroupIds)
val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams)
@ -55,5 +66,4 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
.enqueue()
}
}

View file

@ -25,7 +25,9 @@ import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import io.realm.OrderedCollectionChangeSet
import io.realm.RealmConfiguration
import io.realm.RealmResults
import timber.log.Timber
import javax.inject.Inject
@ -50,19 +52,18 @@ internal class EventRelationsAggregationUpdater @Inject constructor(@SessionData
)
}
override fun processChanges(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
Timber.v("EventRelationsAggregationUpdater called with ${inserted.size} insertions")
val domainInserted = inserted
.map { it.asDomain() }
override fun onChange(results: RealmResults<EventEntity>, changeSet: OrderedCollectionChangeSet) {
Timber.v("EventRelationsAggregationUpdater called with ${changeSet.insertions.size} insertions")
val insertedDomains = changeSet.insertions
.asSequence()
.mapNotNull { results[it]?.asDomain() }
.toList()
val params = EventRelationsAggregationTask.Params(
domainInserted,
insertedDomains,
credentials.userId
)
task.configureWith(params)
.executeBy(taskExecutor)
task.configureWith(params).executeBy(taskExecutor)
}
}

View file

@ -26,9 +26,12 @@ import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.room.EventRelationsAggregationTask
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import io.realm.OrderedCollectionChangeSet
import io.realm.RealmConfiguration
import io.realm.RealmResults
import timber.log.Timber
import javax.inject.Inject
@ -44,18 +47,19 @@ internal class EventsPruner @Inject constructor(@SessionDatabase realmConfigurat
override val query = Monarchy.Query<EventEntity> { EventEntity.types(it, listOf(EventType.REDACTION)) }
override fun processChanges(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
Timber.v("Event pruner called with ${inserted.size} insertions")
val redactionEvents = inserted.map { it.asDomain() }
override fun onChange(results: RealmResults<EventEntity>, changeSet: OrderedCollectionChangeSet) {
Timber.v("Event pruner called with ${changeSet.insertions.size} insertions")
val insertedDomains = changeSet.insertions
.asSequence()
.mapNotNull { results[it]?.asDomain() }
.toList()
val params = PruneEventTask.Params(
redactionEvents,
insertedDomains,
credentials.userId
)
pruneEventTask.configureWith(params)
.executeBy(taskExecutor)
pruneEventTask.configureWith(params).executeBy(taskExecutor)
}
}

View file

@ -22,13 +22,13 @@ import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.model.EventEntityFields
import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.TaskThread
import im.vector.matrix.android.internal.task.configureWith
import io.realm.OrderedCollectionChangeSet
import io.realm.RealmConfiguration
import io.realm.RealmResults
import io.realm.Sort
import javax.inject.Inject
@ -42,15 +42,19 @@ internal class UserEntityUpdater @Inject constructor(@SessionDatabase realmConfi
.types(it, listOf(EventType.STATE_ROOM_MEMBER))
.sort(EventEntityFields.STATE_INDEX, Sort.DESCENDING)
.distinct(EventEntityFields.STATE_KEY)
}
override fun processChanges(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
val roomMembersEvents = inserted.map { it.eventId }
override fun onChange(results: RealmResults<EventEntity>, changeSet: OrderedCollectionChangeSet) {
val roomMembersEvents = changeSet.insertions
.asSequence()
.mapNotNull { results[it]?.eventId }
.toList()
val taskParams = UpdateUserTask.Params(roomMembersEvents)
updateUserTask
.configureWith(taskParams)
.executeOn(TaskThread.IO)
.executeBy(taskExecutor)
}
}