Pagination: remove the live chunk when merging
This commit is contained in:
parent
f8db684ed2
commit
56e15cf054
@ -51,36 +51,6 @@ internal fun ChunkEntity.deleteOnCascade() {
|
||||
this.deleteFromRealm()
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.merge(roomId: String,
|
||||
chunkToMerge: ChunkEntity,
|
||||
direction: PaginationDirection) {
|
||||
assertIsManaged()
|
||||
val isChunkToMergeUnlinked = chunkToMerge.isUnlinked()
|
||||
val isCurrentChunkUnlinked = this.isUnlinked()
|
||||
val isUnlinked = isCurrentChunkUnlinked && isChunkToMergeUnlinked
|
||||
|
||||
if (isCurrentChunkUnlinked && !isChunkToMergeUnlinked) {
|
||||
this.timelineEvents.forEach { it.root?.isUnlinked = false }
|
||||
}
|
||||
val eventsToMerge: List<TimelineEventEntity>
|
||||
if (direction == PaginationDirection.FORWARDS) {
|
||||
this.nextToken = chunkToMerge.nextToken
|
||||
this.isLastForward = chunkToMerge.isLastForward
|
||||
eventsToMerge = chunkToMerge.timelineEvents.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.ASCENDING)
|
||||
} else {
|
||||
this.prevToken = chunkToMerge.prevToken
|
||||
this.isLastBackward = chunkToMerge.isLastBackward
|
||||
eventsToMerge = chunkToMerge.timelineEvents.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
}
|
||||
val events = eventsToMerge.mapNotNull { it.root?.asDomain() }
|
||||
val eventIds = ArrayList<String>()
|
||||
events.forEach { event ->
|
||||
add(realm, roomId, event, direction, isUnlinked = isUnlinked)
|
||||
if (event.eventId != null) {
|
||||
eventIds.add(event.eventId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.add(localRealm: Realm,
|
||||
roomId: String,
|
||||
@ -115,7 +85,7 @@ internal fun ChunkEntity.add(localRealm: Realm,
|
||||
val senderId = event.senderId ?: ""
|
||||
|
||||
val readReceiptsSummaryEntity = ReadReceiptsSummaryEntity.where(localRealm, eventId).findFirst()
|
||||
?: ReadReceiptsSummaryEntity(eventId, roomId)
|
||||
?: ReadReceiptsSummaryEntity(eventId, roomId)
|
||||
|
||||
// Update RR for the sender of a new message with a dummy one
|
||||
|
||||
@ -152,14 +122,14 @@ internal fun ChunkEntity.add(localRealm: Realm,
|
||||
|
||||
internal fun ChunkEntity.lastDisplayIndex(direction: PaginationDirection, defaultValue: Int = 0): Int {
|
||||
return when (direction) {
|
||||
PaginationDirection.FORWARDS -> forwardsDisplayIndex
|
||||
PaginationDirection.BACKWARDS -> backwardsDisplayIndex
|
||||
} ?: defaultValue
|
||||
PaginationDirection.FORWARDS -> forwardsDisplayIndex
|
||||
PaginationDirection.BACKWARDS -> backwardsDisplayIndex
|
||||
} ?: defaultValue
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.lastStateIndex(direction: PaginationDirection, defaultValue: Int = 0): Int {
|
||||
return when (direction) {
|
||||
PaginationDirection.FORWARDS -> forwardsStateIndex
|
||||
PaginationDirection.BACKWARDS -> backwardsStateIndex
|
||||
} ?: defaultValue
|
||||
PaginationDirection.FORWARDS -> forwardsStateIndex
|
||||
PaginationDirection.BACKWARDS -> backwardsStateIndex
|
||||
} ?: defaultValue
|
||||
}
|
||||
|
@ -26,11 +26,6 @@ import im.vector.matrix.android.internal.database.query.fastContains
|
||||
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
|
||||
internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
|
||||
chunks.remove(chunkEntity)
|
||||
chunkEntity.deleteOnCascade()
|
||||
}
|
||||
|
||||
internal fun RoomEntity.addOrUpdate(chunkEntity: ChunkEntity) {
|
||||
if (!chunks.contains(chunkEntity)) {
|
||||
chunks.add(chunkEntity)
|
||||
|
@ -57,7 +57,7 @@ internal fun ChunkEntity.Companion.findIncludingEvent(realm: Realm, eventId: Str
|
||||
return findAllIncludingEvents(realm, listOf(eventId)).firstOrNull()
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.Companion.create(realm: Realm, roomId: String, prevToken: String?, nextToken: String?): ChunkEntity {
|
||||
internal fun ChunkEntity.Companion.create(realm: Realm, roomId: String, prevToken: String? = null, nextToken: String? = null): ChunkEntity {
|
||||
return realm.createObject<ChunkEntity>().apply {
|
||||
this.roomId = roomId
|
||||
this.prevToken = prevToken
|
||||
|
@ -470,13 +470,13 @@ internal class DefaultTimeline(
|
||||
Pair(filteredEvents[range.startIndex]!!.root!!.displayIndex, Timeline.Direction.BACKWARDS)
|
||||
}
|
||||
val state = getState(direction)
|
||||
if (state.isPaginating) {
|
||||
postSnapshot = if (state.isPaginating) {
|
||||
// We are getting new items from pagination
|
||||
postSnapshot = paginateInternal(startDisplayIndex, direction, state.requestedPaginationCount)
|
||||
paginateInternal(startDisplayIndex, direction, state.requestedPaginationCount)
|
||||
} else {
|
||||
// We are getting new items from sync
|
||||
buildTimelineEvents(startDisplayIndex, direction, range.length.toLong())
|
||||
postSnapshot = true
|
||||
true
|
||||
}
|
||||
}
|
||||
changeSet.changes.forEach { index ->
|
||||
|
@ -23,7 +23,9 @@ import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
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.findAllIncludingEvents
|
||||
import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
|
||||
import im.vector.matrix.android.internal.session.user.UserEntityFactory
|
||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||
import io.realm.kotlin.createObject
|
||||
@ -33,7 +35,8 @@ import javax.inject.Inject
|
||||
/**
|
||||
* Insert Chunk in DB, and eventually merge with existing chunk event
|
||||
*/
|
||||
internal class TokenChunkEventPersistor @Inject constructor(private val monarchy: Monarchy) {
|
||||
internal class TokenChunkEventPersistor @Inject constructor(private val monarchy: Monarchy,
|
||||
private val roomSummaryUpdater: RoomSummaryUpdater) {
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
@ -112,7 +115,7 @@ internal class TokenChunkEventPersistor @Inject constructor(private val monarchy
|
||||
Timber.v("Start persisting ${receivedChunk.events.size} events in $roomId towards $direction")
|
||||
|
||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
?: realm.createObject(roomId)
|
||||
|
||||
val nextToken: String?
|
||||
val prevToken: String?
|
||||
@ -127,7 +130,6 @@ internal class TokenChunkEventPersistor @Inject constructor(private val monarchy
|
||||
val prevChunk = ChunkEntity.find(realm, roomId, nextToken = prevToken)
|
||||
val nextChunk = ChunkEntity.find(realm, roomId, prevToken = nextToken)
|
||||
|
||||
// The current chunk is the one we will keep all along the merge processChanges.
|
||||
// We try to look for a chunk next to the token,
|
||||
// otherwise we create a whole new one
|
||||
|
||||
@ -136,22 +138,34 @@ internal class TokenChunkEventPersistor @Inject constructor(private val monarchy
|
||||
} else {
|
||||
nextChunk?.apply { this.prevToken = prevToken }
|
||||
}
|
||||
?: ChunkEntity().apply {
|
||||
this.roomId = roomId
|
||||
this.prevToken = prevToken
|
||||
this.nextToken = nextToken
|
||||
}
|
||||
?: realm.createObject<ChunkEntity>().apply {
|
||||
this.roomId = roomId
|
||||
this.prevToken = prevToken
|
||||
this.nextToken = nextToken
|
||||
}
|
||||
|
||||
if (receivedChunk.events.isEmpty() && receivedChunk.end == receivedChunk.start) {
|
||||
Timber.v("Reach end of $roomId")
|
||||
currentChunk.isLastBackward = true
|
||||
if (direction == PaginationDirection.FORWARDS) {
|
||||
Timber.v("Reach live state of $roomId")
|
||||
// We make sure we only have one live chunk
|
||||
ChunkEntity.findLastLiveChunkFromRoom(realm, roomId)?.deleteOnCascade()
|
||||
currentChunk.isLastForward = true
|
||||
currentChunk.nextToken = null
|
||||
currentChunk.timelineEvents.forEach {
|
||||
it.root?.isUnlinked = false
|
||||
}
|
||||
roomSummaryUpdater.update(realm, roomId, updateMembers = false)
|
||||
} else {
|
||||
Timber.v("Reach end of $roomId")
|
||||
currentChunk.isLastBackward = true
|
||||
}
|
||||
} else {
|
||||
Timber.v("Add ${receivedChunk.events.size} events in chunk(${currentChunk.nextToken} | ${currentChunk.prevToken}")
|
||||
for (event in receivedChunk.events) {
|
||||
currentChunk.add(realm, roomId, event, direction, isUnlinked = !currentChunk.isLastForward)
|
||||
}
|
||||
roomEntity.addOrUpdate(currentChunk)
|
||||
}
|
||||
roomEntity.addOrUpdate(currentChunk)
|
||||
}
|
||||
return if (receivedChunk.events.isEmpty()) {
|
||||
if (receivedChunk.start != receivedChunk.end) {
|
||||
|
@ -20,9 +20,11 @@ package im.vector.matrix.android.internal.session.sync
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.internal.crypto.DefaultCryptoService
|
||||
import im.vector.matrix.android.internal.database.helper.add
|
||||
import im.vector.matrix.android.internal.database.helper.deleteOnCascade
|
||||
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.RoomEntity
|
||||
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.findLastLiveChunkFromRoom
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
@ -52,10 +54,8 @@ internal class ChunkEntityFactory @Inject constructor(private val cryptoService:
|
||||
roomId: String,
|
||||
eventList: List<Event>,
|
||||
prevToken: String?): ChunkEntity {
|
||||
val chunkEntity = realm.createObject<ChunkEntity>().apply {
|
||||
this.roomId = roomId
|
||||
this.prevToken = prevToken
|
||||
this.isLastForward = true
|
||||
val chunkEntity = ChunkEntity.create(realm, roomId, prevToken = prevToken).apply {
|
||||
isLastForward = true
|
||||
}
|
||||
for (event in eventList) {
|
||||
chunkEntity.add(realm, roomId, event, PaginationDirection.FORWARDS)
|
||||
@ -76,14 +76,15 @@ internal class ChunkEntityFactory @Inject constructor(private val cryptoService:
|
||||
val lastChunk = ChunkEntity.findLastLiveChunkFromRoom(realm, roomId)
|
||||
val stateIndexOffset = lastChunk?.lastStateIndex(PaginationDirection.FORWARDS) ?: 0
|
||||
val chunkEntity = if (isLimited || lastChunk == null) {
|
||||
realm.createObject<ChunkEntity>().apply {
|
||||
this.roomId = roomId
|
||||
this.prevToken = prevToken
|
||||
this.isLastForward = true
|
||||
ChunkEntity.create(realm, roomId, prevToken = prevToken).apply {
|
||||
isLastForward = true
|
||||
}
|
||||
} else {
|
||||
lastChunk
|
||||
}
|
||||
if (lastChunk != chunkEntity) {
|
||||
lastChunk?.deleteOnCascade()
|
||||
}
|
||||
for (event in eventList) {
|
||||
chunkEntity.add(realm, roomId, event, PaginationDirection.FORWARDS, stateIndexOffset)
|
||||
// Give info to crypto module
|
||||
|
Loading…
x
Reference in New Issue
Block a user