forked from GitHub-Mirror/riotX-android
RoomMembers/User : get a better and faster handling (still need to fix one small issue)
This commit is contained in:
parent
10e4d0190f
commit
9182f2ce4e
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.internal.database.helper
|
package im.vector.matrix.android.internal.database.helper
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting
|
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.room.send.SendState
|
import im.vector.matrix.android.api.session.room.send.SendState
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.internal.database.helper
|
package im.vector.matrix.android.internal.database.helper
|
||||||
|
|
||||||
import com.squareup.moshi.JsonReader
|
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.api.session.room.send.SendState
|
import im.vector.matrix.android.api.session.room.send.SendState
|
||||||
import im.vector.matrix.android.internal.database.mapper.toEntity
|
import im.vector.matrix.android.internal.database.mapper.toEntity
|
||||||
@ -25,10 +24,7 @@ import im.vector.matrix.android.internal.database.model.RoomEntity
|
|||||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||||
import im.vector.matrix.android.internal.database.query.fastContains
|
import im.vector.matrix.android.internal.database.query.fastContains
|
||||||
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
||||||
import im.vector.matrix.android.internal.network.parsing.GetRoomMembersResponseHandler
|
|
||||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||||
import okhttp3.ResponseBody
|
|
||||||
import okio.Okio
|
|
||||||
|
|
||||||
internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
|
internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
|
||||||
chunks.remove(chunkEntity)
|
chunks.remove(chunkEntity)
|
||||||
@ -57,26 +53,6 @@ internal fun RoomEntity.addStateEvent(stateEvent: Event,
|
|||||||
untimelinedStateEvents.add(entity)
|
untimelinedStateEvents.add(entity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun RoomEntity.addStateEvents(stateEvents: List<Event>,
|
|
||||||
stateIndex: Int = Int.MIN_VALUE,
|
|
||||||
filterDuplicates: Boolean = false,
|
|
||||||
isUnlinked: Boolean = false) {
|
|
||||||
stateEvents.forEach { event ->
|
|
||||||
addStateEvent(event, stateIndex, filterDuplicates, isUnlinked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun RoomEntity.addStateEvents(response: ResponseBody,
|
|
||||||
stateIndex: Int = Int.MIN_VALUE,
|
|
||||||
isUnlinked: Boolean = false) {
|
|
||||||
val manualParser = GetRoomMembersResponseHandler()
|
|
||||||
val bufferedSource = Okio.buffer(Okio.source(response.byteStream()))
|
|
||||||
val inputReader = JsonReader.of(bufferedSource)
|
|
||||||
manualParser.handle(inputReader, this, stateIndex, isUnlinked)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal fun RoomEntity.addSendingEvent(event: Event) {
|
internal fun RoomEntity.addSendingEvent(event: Event) {
|
||||||
assertIsManaged()
|
assertIsManaged()
|
||||||
val senderId = event.senderId ?: return
|
val senderId = event.senderId ?: return
|
||||||
|
@ -20,8 +20,6 @@ import io.realm.RealmObject
|
|||||||
import io.realm.RealmResults
|
import io.realm.RealmResults
|
||||||
import io.realm.annotations.Index
|
import io.realm.annotations.Index
|
||||||
import io.realm.annotations.LinkingObjects
|
import io.realm.annotations.LinkingObjects
|
||||||
import io.realm.annotations.PrimaryKey
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
internal open class TimelineEventEntity(var localId: Long = 0,
|
internal open class TimelineEventEntity(var localId: Long = 0,
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 New Vector Ltd
|
|
||||||
*
|
|
||||||
* 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 im.vector.matrix.android.internal.network.parsing
|
|
||||||
|
|
||||||
import com.squareup.moshi.JsonReader
|
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
|
||||||
import im.vector.matrix.android.api.session.room.send.SendState
|
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
|
||||||
|
|
||||||
internal class GetRoomMembersResponseHandler {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val NAMES = JsonReader.Options.of("event_id", "content", "prev_content", "origin_server_ts", "sender", "state_key")
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun handle(reader: JsonReader, roomEntity: RoomEntity, stateIndex: Int = Int.MIN_VALUE, isUnlinked: Boolean = false) {
|
|
||||||
reader.readObject {
|
|
||||||
reader.nextName()
|
|
||||||
val eventEntity = EventEntity().apply {
|
|
||||||
this.roomId = roomEntity.roomId
|
|
||||||
this.stateIndex = stateIndex
|
|
||||||
this.isUnlinked = isUnlinked
|
|
||||||
this.sendState = SendState.SYNCED
|
|
||||||
this.type = EventType.STATE_ROOM_MEMBER
|
|
||||||
}
|
|
||||||
reader.readArray {
|
|
||||||
reader.readObject {
|
|
||||||
when
|
|
||||||
(reader.selectName(NAMES)) {
|
|
||||||
0 -> eventEntity.eventId = reader.nextString()
|
|
||||||
1 -> eventEntity.content = reader.readJsonValue()?.toString()
|
|
||||||
2 -> eventEntity.prevContent = reader.readJsonValue()?.toString()
|
|
||||||
3 -> eventEntity.originServerTs = reader.nextLong()
|
|
||||||
4 -> eventEntity.sender = reader.nextString()
|
|
||||||
5 -> eventEntity.stateKey = reader.nextString()
|
|
||||||
else -> reader.skipNameAndValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
roomEntity.untimelinedStateEvents.add(eventEntity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 New Vector Ltd
|
|
||||||
*
|
|
||||||
* 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 im.vector.matrix.android.internal.network.parsing
|
|
||||||
|
|
||||||
import com.squareup.moshi.JsonReader
|
|
||||||
|
|
||||||
fun JsonReader.skipNameAndValue() {
|
|
||||||
skipName()
|
|
||||||
skipValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun JsonReader.readObject(body: () -> Unit) {
|
|
||||||
beginObject()
|
|
||||||
while (hasNext()) {
|
|
||||||
body()
|
|
||||||
}
|
|
||||||
endObject()
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun JsonReader.readArray(body: () -> Unit) {
|
|
||||||
beginArray()
|
|
||||||
while (hasNext()) {
|
|
||||||
body()
|
|
||||||
}
|
|
||||||
endArray()
|
|
||||||
}
|
|
@ -17,15 +17,12 @@
|
|||||||
package im.vector.matrix.android.internal.session.room.membership
|
package im.vector.matrix.android.internal.session.room.membership
|
||||||
|
|
||||||
import arrow.core.Try
|
import arrow.core.Try
|
||||||
|
import com.squareup.moshi.JsonReader
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
|
||||||
import im.vector.matrix.android.internal.database.helper.addStateEvent
|
import im.vector.matrix.android.internal.database.helper.addStateEvent
|
||||||
import im.vector.matrix.android.internal.database.helper.addStateEvents
|
|
||||||
import im.vector.matrix.android.internal.database.helper.updateSenderData
|
import im.vector.matrix.android.internal.database.helper.updateSenderData
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
import im.vector.matrix.android.internal.database.model.UserEntity
|
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.network.executeRequest
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||||
@ -37,6 +34,7 @@ import im.vector.matrix.android.internal.util.tryTransactionSync
|
|||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.kotlin.createObject
|
import io.realm.kotlin.createObject
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
|
import okio.Okio
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal interface LoadRoomMembersTask : Task<LoadRoomMembersTask.Params, Boolean> {
|
internal interface LoadRoomMembersTask : Task<LoadRoomMembersTask.Params, Boolean> {
|
||||||
@ -73,14 +71,13 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(private val roomAP
|
|||||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||||
?: realm.createObject(roomId)
|
?: realm.createObject(roomId)
|
||||||
|
|
||||||
val userEntities = ArrayList<UserEntity>(response.roomMemberEvents.size)
|
|
||||||
for (roomMemberEvent in response.roomMemberEvents) {
|
for (roomMemberEvent in response.roomMemberEvents) {
|
||||||
roomEntity.addStateEvent(roomMemberEvent)
|
roomEntity.addStateEvent(roomMemberEvent)
|
||||||
UserEntityFactory.create(roomMemberEvent)?.also {
|
UserEntityFactory.create(roomMemberEvent)?.also {
|
||||||
userEntities.add(it)
|
realm.insertOrUpdate(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
realm.insertOrUpdate(userEntities)
|
|
||||||
roomEntity.chunks.flatMap { it.timelineEvents }.forEach {
|
roomEntity.chunks.flatMap { it.timelineEvents }.forEach {
|
||||||
it.updateSenderData()
|
it.updateSenderData()
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,9 @@ package im.vector.matrix.android.internal.session.room.timeline
|
|||||||
|
|
||||||
import arrow.core.Try
|
import arrow.core.Try
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import im.vector.matrix.android.internal.database.helper.addAll
|
import im.vector.matrix.android.internal.database.helper.*
|
||||||
import im.vector.matrix.android.internal.database.helper.addOrUpdate
|
|
||||||
import im.vector.matrix.android.internal.database.helper.addStateEvent
|
|
||||||
import im.vector.matrix.android.internal.database.helper.addStateEvents
|
|
||||||
import im.vector.matrix.android.internal.database.helper.deleteOnCascade
|
|
||||||
import im.vector.matrix.android.internal.database.helper.isUnlinked
|
|
||||||
import im.vector.matrix.android.internal.database.helper.merge
|
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
import im.vector.matrix.android.internal.database.model.UserEntity
|
|
||||||
import im.vector.matrix.android.internal.database.query.create
|
import im.vector.matrix.android.internal.database.query.create
|
||||||
import im.vector.matrix.android.internal.database.query.find
|
import im.vector.matrix.android.internal.database.query.find
|
||||||
import im.vector.matrix.android.internal.database.query.findAllIncludingEvents
|
import im.vector.matrix.android.internal.database.query.findAllIncludingEvents
|
||||||
@ -156,11 +149,12 @@ internal class TokenChunkEventPersistor @Inject constructor(private val monarchy
|
|||||||
currentChunk.isLastBackward = true
|
currentChunk.isLastBackward = true
|
||||||
} else {
|
} else {
|
||||||
Timber.v("Add ${receivedChunk.events.size} events in chunk(${currentChunk.nextToken} | ${currentChunk.prevToken}")
|
Timber.v("Add ${receivedChunk.events.size} events in chunk(${currentChunk.nextToken} | ${currentChunk.prevToken}")
|
||||||
val userEntities = ArrayList<UserEntity>(receivedChunk.events.size + receivedChunk.stateEvents.size)
|
val eventIds = ArrayList<String>(receivedChunk.events.size)
|
||||||
for (event in receivedChunk.events) {
|
for (event in receivedChunk.events) {
|
||||||
currentChunk.addAll(roomId, receivedChunk.events, direction, isUnlinked = currentChunk.isUnlinked())
|
event.eventId?.also { eventIds.add(it) }
|
||||||
|
currentChunk.add(roomId, event, direction, isUnlinked = currentChunk.isUnlinked())
|
||||||
UserEntityFactory.create(event)?.also {
|
UserEntityFactory.create(event)?.also {
|
||||||
userEntities.add(it)
|
realm.insertOrUpdate(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Then we merge chunks if needed
|
// Then we merge chunks if needed
|
||||||
@ -181,10 +175,10 @@ internal class TokenChunkEventPersistor @Inject constructor(private val monarchy
|
|||||||
for (stateEvent in receivedChunk.stateEvents) {
|
for (stateEvent in receivedChunk.stateEvents) {
|
||||||
roomEntity.addStateEvent(stateEvent, isUnlinked = currentChunk.isUnlinked())
|
roomEntity.addStateEvent(stateEvent, isUnlinked = currentChunk.isUnlinked())
|
||||||
UserEntityFactory.create(stateEvent)?.also {
|
UserEntityFactory.create(stateEvent)?.also {
|
||||||
userEntities.add(it)
|
realm.insertOrUpdate(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
realm.insertOrUpdate(userEntities)
|
currentChunk.updateSenderDataFor(eventIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map {
|
.map {
|
||||||
|
@ -22,15 +22,9 @@ import im.vector.matrix.android.api.session.events.model.Event
|
|||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
|
||||||
import im.vector.matrix.android.api.session.room.model.tag.RoomTagContent
|
import im.vector.matrix.android.api.session.room.model.tag.RoomTagContent
|
||||||
import im.vector.matrix.android.internal.crypto.CryptoManager
|
import im.vector.matrix.android.internal.crypto.CryptoManager
|
||||||
import im.vector.matrix.android.internal.database.helper.add
|
import im.vector.matrix.android.internal.database.helper.*
|
||||||
import im.vector.matrix.android.internal.database.helper.addAll
|
|
||||||
import im.vector.matrix.android.internal.database.helper.addOrUpdate
|
|
||||||
import im.vector.matrix.android.internal.database.helper.addStateEvent
|
|
||||||
import im.vector.matrix.android.internal.database.helper.addStateEvents
|
|
||||||
import im.vector.matrix.android.internal.database.helper.lastStateIndex
|
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
import im.vector.matrix.android.internal.database.model.UserEntity
|
import im.vector.matrix.android.internal.database.model.UserEntity
|
||||||
@ -138,17 +132,15 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
|
|||||||
|
|
||||||
// State event
|
// State event
|
||||||
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
|
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
|
||||||
val userEntities = ArrayList<UserEntity>(roomSync.state.events.size)
|
|
||||||
val untimelinedStateIndex = if (isInitialSync) Int.MIN_VALUE else stateIndexOffset
|
val untimelinedStateIndex = if (isInitialSync) Int.MIN_VALUE else stateIndexOffset
|
||||||
roomSync.state.events.forEach { event ->
|
roomSync.state.events.forEach { event ->
|
||||||
roomEntity.addStateEvent(event, filterDuplicates = true, stateIndex = untimelinedStateIndex)
|
roomEntity.addStateEvent(event, filterDuplicates = true, stateIndex = untimelinedStateIndex)
|
||||||
// Give info to crypto module
|
// Give info to crypto module
|
||||||
cryptoManager.onStateEvent(roomId, event)
|
cryptoManager.onStateEvent(roomId, event)
|
||||||
UserEntityFactory.create(event)?.also {
|
UserEntityFactory.create(event)?.also {
|
||||||
userEntities.add(it)
|
realm.insertOrUpdate(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
realm.insertOrUpdate(userEntities)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roomSync.timeline != null && roomSync.timeline.events.isNotEmpty()) {
|
if (roomSync.timeline != null && roomSync.timeline.events.isNotEmpty()) {
|
||||||
@ -219,8 +211,9 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
|
|||||||
lastChunk?.isLastForward = false
|
lastChunk?.isLastForward = false
|
||||||
chunkEntity.isLastForward = true
|
chunkEntity.isLastForward = true
|
||||||
|
|
||||||
val userEntities = ArrayList<UserEntity>(eventList.size)
|
val eventIds = ArrayList<String>(eventList.size)
|
||||||
for (event in eventList) {
|
for (event in eventList) {
|
||||||
|
event.eventId?.also { eventIds.add(it) }
|
||||||
chunkEntity.add(roomEntity.roomId, event, PaginationDirection.FORWARDS, stateIndexOffset)
|
chunkEntity.add(roomEntity.roomId, event, PaginationDirection.FORWARDS, stateIndexOffset)
|
||||||
// Give info to crypto module
|
// Give info to crypto module
|
||||||
cryptoManager.onLiveEvent(roomEntity.roomId, event)
|
cryptoManager.onLiveEvent(roomEntity.roomId, event)
|
||||||
@ -235,10 +228,10 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
UserEntityFactory.create(event)?.also {
|
UserEntityFactory.create(event)?.also {
|
||||||
userEntities.add(it)
|
realm.insertOrUpdate(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
realm.insertOrUpdate(userEntities)
|
chunkEntity.updateSenderDataFor(eventIds)
|
||||||
return chunkEntity
|
return chunkEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user