Support refreshDueToExternalTransaction in more views

This commit is contained in:
Ali 2021-11-04 21:09:34 +04:00
parent 9290df840d
commit ddb0999af0
36 changed files with 407 additions and 15 deletions

View File

@ -14,6 +14,10 @@ final class MutableAdditionalChatListItemsView: MutablePostboxView {
}
return false
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return AdditionalChatListItemsView(self)

View File

@ -48,6 +48,10 @@ final class MutableAllChatListHolesView: MutablePostboxView {
return false
}
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return AllChatListHolesView(self)

View File

@ -16,6 +16,10 @@ final class MutableCachedItemView: MutablePostboxView {
}
return false
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return CachedItemView(self)

View File

@ -17,6 +17,10 @@ final class MutableCachedPeerDataView: MutablePostboxView {
return false
}
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return CachedPeerDataView(self)

View File

@ -70,6 +70,10 @@ final class MutableContactPeersView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return ContactPeersView(self)
}

View File

@ -33,6 +33,10 @@ final class MutableDeletedMessagesView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return DeletedMessagesView(self)
}

View File

@ -202,6 +202,25 @@ final class MutableGlobalMessageTagsView: MutablePostboxView {
return hasChanges
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
let (entries, lower, upper) = postbox.messageHistoryTable.entriesAround(globalTagMask: globalTag, index: position, count: count)
self.entries = entries.map { entry -> InternalGlobalMessageTagsEntry in
switch entry {
case let .message(message):
return .intermediateMessage(message)
case let .hole(index):
return .hole(index)
}
}
self.earlier = lower
self.later = upper
self.render(postbox: postbox)
return true
}
private func add(_ entry: InternalGlobalMessageTagsEntry) -> Bool {
if self.entries.count == 0 {

View File

@ -61,6 +61,22 @@ final class MutableHistoryTagInfoView: MutablePostboxView {
return false
}
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var currentIndex: MessageIndex?
for namespace in postbox.messageHistoryIndexTable.existingNamespaces(peerId: self.peerId) {
if let index = postbox.messageHistoryTagsTable.latestIndex(tag: self.tag, peerId: self.peerId, namespace: namespace) {
currentIndex = index
break
}
}
if self.currentIndex != currentIndex {
self.currentIndex = currentIndex
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return HistoryTagInfoView(self)

View File

@ -37,6 +37,19 @@ final class MutableInvalidatedMessageHistoryTagSummariesView: MutablePostboxView
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var entries = Set<InvalidatedMessageHistoryTagsSummaryEntry>()
for entry in postbox.invalidatedMessageHistoryTagsSummaryTable.get(tagMask: tagMask, namespace: namespace) {
entries.insert(entry)
}
if self.entries != entries {
self.entries = entries
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return InvalidatedMessageHistoryTagSummariesView(self)

View File

@ -40,6 +40,20 @@ final class MutableItemCollectionIdsView: MutablePostboxView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var idsByNamespace: [ItemCollectionId.Namespace: Set<ItemCollectionId>] = [:]
for namespace in namespaces {
let ids = postbox.itemCollectionInfoTable.getIds(namespace: namespace)
idsByNamespace[namespace] = Set(ids)
}
if self.idsByNamespace != idsByNamespace {
self.idsByNamespace = idsByNamespace
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return ItemCollectionIdsView(self)

View File

@ -48,6 +48,10 @@ final class MutableItemCollectionInfoView: MutablePostboxView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return ItemCollectionInfoView(self)

View File

@ -90,12 +90,14 @@ final class MutableItemCollectionInfosView: MutablePostboxView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return ItemCollectionInfosView(self)
}
}
public final class ItemCollectionInfosView: PostboxView {

View File

@ -50,6 +50,10 @@ final class MutableLocalMessageTagsView: MutablePostboxView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return LocalMessageTagsView(self)

View File

@ -25,6 +25,16 @@ final class MutableMessageHistoryTagSummaryView: MutablePostboxView {
return hasChanges
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
let count = postbox.messageHistoryTagsSummaryTable.get(MessageHistoryTagsSummaryKey(tag: self.tag, peerId: self.peerId, namespace: self.namespace))?.count
if self.count != count {
self.count = count
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return MessageHistoryTagSummaryView(self)

View File

@ -739,7 +739,7 @@ final class MutableMessageHistoryView {
}
case let .peerChatState(peerId, _):
if transaction.currentUpdatedPeerChatStates.contains(peerId) {
updated[i] = .peerChatState(peerId, postbox.peerChatStateTable.get(peerId) as? PeerChatState)
updated[i] = .peerChatState(peerId, postbox.peerChatStateTable.get(peerId)?.getLegacy() as? PeerChatState)
hasChanges = true
}
case .totalUnreadState:

View File

@ -171,6 +171,10 @@ final class MutableMessageOfInterestHolesView: MutablePostboxView {
return false
}
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return MessageOfInterestHolesView(self)

View File

@ -51,6 +51,10 @@ final class MutableMessagesView: MutablePostboxView {
return false
}
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return MessagesView(self)

View File

@ -42,6 +42,10 @@ final class MutableBasicPeerView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return BasicPeerView(self)

View File

@ -22,6 +22,10 @@ final class MutablePeerChatInclusionView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return PeerChatInclusionView(self)

View File

@ -51,6 +51,10 @@ final class MutableOrderedItemListView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return OrderedItemListView(self)

View File

@ -5,7 +5,7 @@ final class PeerChatStateTable: Table {
return ValueBoxTable(id: id, keyType: .int64, compactValuesOnCreation: false)
}
private var cachedPeerChatStates: [PeerId: PostboxCoding?] = [:]
private var cachedPeerChatStates: [PeerId: CodableEntry?] = [:]
private var updatedPeerIds = Set<PeerId>()
private let sharedKey = ValueBoxKey(length: 8)
@ -15,11 +15,12 @@ final class PeerChatStateTable: Table {
return self.sharedKey
}
func get(_ id: PeerId) -> PostboxCoding? {
func get(_ id: PeerId) -> CodableEntry? {
if let state = self.cachedPeerChatStates[id] {
return state
} else {
if let value = self.valueBox.get(self.table, key: self.key(id)), let state = PostboxDecoder(buffer: value).decodeRootObject() {
if let value = self.valueBox.get(self.table, key: self.key(id)) {
let state = CodableEntry(data: value.makeData())
self.cachedPeerChatStates[id] = state
return state
} else {
@ -29,7 +30,7 @@ final class PeerChatStateTable: Table {
}
}
func set(_ id: PeerId, state: PostboxCoding?) {
func set(_ id: PeerId, state: CodableEntry?) {
self.cachedPeerChatStates[id] = state
self.updatedPeerIds.insert(id)
}
@ -41,12 +42,9 @@ final class PeerChatStateTable: Table {
override func beforeCommit() {
if !self.updatedPeerIds.isEmpty {
let sharedEncoder = PostboxEncoder()
for id in self.updatedPeerIds {
if let wrappedState = self.cachedPeerChatStates[id], let state = wrappedState {
sharedEncoder.reset()
sharedEncoder.encodeRootObject(state)
self.valueBox.set(self.table, key: self.key(id), value: sharedEncoder.readBufferNoCopy())
self.valueBox.set(self.table, key: self.key(id), value: ReadBuffer(data: state.data))
} else {
self.valueBox.remove(self.table, key: self.key(id), secure: false)
}

View File

@ -2,7 +2,7 @@ import Foundation
final class MutablePeerChatStateView: MutablePostboxView {
let peerId: PeerId
var chatState: PostboxCoding?
var chatState: CodableEntry?
init(postbox: PostboxImpl, peerId: PeerId) {
self.peerId = peerId
@ -17,6 +17,16 @@ final class MutablePeerChatStateView: MutablePostboxView {
return false
}
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
let chatState = postbox.peerChatStateTable.get(self.peerId)
if self.chatState != chatState {
self.chatState = chatState
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return PeerChatStateView(self)
@ -25,7 +35,7 @@ final class MutablePeerChatStateView: MutablePostboxView {
public final class PeerChatStateView: PostboxView {
public let peerId: PeerId
public let chatState: PostboxCoding?
public let chatState: CodableEntry?
init(_ view: MutablePeerChatStateView) {
self.peerId = view.peerId

View File

@ -19,6 +19,16 @@ final class MutablePeerNotificationSettingsBehaviorTimestampView: MutablePostbox
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
let earliestTimestamp = postbox.peerNotificationSettingsBehaviorTable.getEarliest()?.1
if self.earliestTimestamp != earliestTimestamp {
self.earliestTimestamp = earliestTimestamp
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return PeerNotificationSettingsBehaviorTimestampView(self)

View File

@ -36,6 +36,43 @@ final class MutablePeerNotificationSettingsView: MutablePostboxView {
return false
}
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
for peerId in self.peerIds {
var notificationPeerId = peerId
if let peer = postbox.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId {
notificationPeerId = associatedPeerId
}
if let settings = postbox.peerNotificationSettingsTable.getEffective(notificationPeerId) {
notificationSettings[peerId] = settings
}
}
var updated = false
if self.notificationSettings.count != notificationSettings.count {
updated = true
} else {
for (key, value) in self.notificationSettings {
if let other = notificationSettings[key] {
if !other.isEqual(to: value) {
updated = true
break
}
} else {
updated = true
break
}
}
}
if updated {
self.notificationSettings = notificationSettings
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return PeerNotificationSettingsView(self)

View File

@ -26,6 +26,40 @@ final class MutablePeerPresencesView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var presences: [PeerId: PeerPresence] = [:]
for id in self.ids {
if let presence = postbox.peerPresenceTable.get(id) {
presences[id] = presence
}
}
var updated = false
if self.presences.count != presences.count {
updated = true
} else {
for (key, value) in self.presences {
if let other = presences[key] {
if !other.isEqual(to: value) {
updated = true
break
}
} else {
updated = true
break
}
}
}
if updated {
self.presences = presences
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return PeerPresencesView(self)

View File

@ -253,6 +253,10 @@ final class MutablePeerView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return PeerView(self)

View File

@ -16,6 +16,10 @@ final class MutablePendingMessageActionsSummaryView: MutablePostboxView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return PendingMessageActionsSummaryView(self)

View File

@ -38,6 +38,10 @@ final class MutablePendingMessageActionsView: MutablePostboxView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return PendingMessageActionsView(self)

View File

@ -25,6 +25,10 @@ final class MutablePendingPeerNotificationSettingsView: MutablePostboxView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
return false
}
func immutableView() -> PostboxView {
return PendingPeerNotificationSettingsView(self)

View File

@ -2212,7 +2212,7 @@ final class PostboxImpl {
}
fileprivate func setPeerChatState(_ id: PeerId, state: PeerChatState) {
self.peerChatStateTable.set(id, state: state)
self.peerChatStateTable.set(id, state: CodableEntry(legacyValue: state))
self.currentUpdatedPeerChatStates.insert(id)
}

View File

@ -5,6 +5,7 @@ public protocol PostboxView {
protocol MutablePostboxView {
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool
func immutableView() -> PostboxView
}
@ -24,6 +25,16 @@ final class CombinedMutableView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var updated = false
for (_, view) in self.views {
if view.refreshDueToExternalTransaction(postbox: postbox) {
updated = true
}
}
return updated
}
func immutableView() -> CombinedView {
var result: [PostboxViewKey: PostboxView] = [:]

View File

@ -13,11 +13,37 @@ public final class CodableEntry: Equatable {
self.data = encoder.makeData()
}
public init(legacyValue: PostboxCoding) {
let encoder = PostboxEncoder()
encoder.encodeRootObject(legacyValue)
self.data = encoder.makeData()
}
public func get<T: Decodable>(_ type: T.Type) -> T? {
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data))
return decoder.decode(T.self, forKey: "_")
}
public func getLegacy<T: PostboxCoding>(_ type: T.Type) -> T? {
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data))
let object = decoder.decodeRootObject()
if let object = object as? T {
return object
} else {
return nil
}
}
public func getLegacy() -> PostboxCoding? {
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data))
let object = decoder.decodeRootObject()
if let object = object {
return object
} else {
return nil
}
}
public static func ==(lhs: CodableEntry, rhs: CodableEntry) -> Bool {
return lhs.data == rhs.data
}

View File

@ -44,6 +44,21 @@ final class MutablePreferencesView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var values: [ValueBoxKey: PreferencesEntry] = [:]
for key in self.keys {
if let value = postbox.preferencesTable.get(key: key) {
values[key] = value
}
}
if self.values != values {
self.values = values
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return PreferencesView(self)

View File

@ -26,6 +26,16 @@ final class MutableSynchronizeGroupMessageStatsView: MutablePostboxView {
}
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
let groupsAndNamespaces = postbox.synchronizeGroupMessageStatsTable.get()
if self.groupsAndNamespaces != groupsAndNamespaces {
self.groupsAndNamespaces = groupsAndNamespaces
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return SynchronizeGroupMessageStatsView(self)

View File

@ -29,6 +29,41 @@ final class MutableTopChatMessageView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var messages: [PeerId: Message] = [:]
for peerId in self.peerIds {
if let index = postbox.chatListIndexTable.get(peerId: peerId).topMessageIndex {
messages[peerId] = postbox.getMessage(index.id)
}
}
var updated = false
if self.messages.count != messages.count {
updated = true
} else {
for (key, value) in self.messages {
if let other = messages[key] {
if other.stableId != value.stableId || other.stableVersion != value.stableVersion {
updated = true
break
}
} else {
updated = true
break
}
}
}
if updated {
self.messages = messages
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return TopChatMessageView(self)

View File

@ -6,10 +6,42 @@ public enum UnreadMessageCountsItem: Equatable {
case peer(PeerId)
}
private enum MutableUnreadMessageCountsItemEntry {
private enum MutableUnreadMessageCountsItemEntry: Equatable {
case total((ValueBoxKey, PreferencesEntry?)?, ChatListTotalUnreadState)
case totalInGroup(PeerGroupId, ChatListTotalUnreadState)
case peer(PeerId, CombinedPeerReadState?)
static func ==(lhs: MutableUnreadMessageCountsItemEntry, rhs: MutableUnreadMessageCountsItemEntry) -> Bool {
switch lhs {
case let .total(lhsKeyAndEntry, lhsUnreadState):
if case let .total(rhsKeyAndEntry, rhsUnreadState) = rhs {
if lhsKeyAndEntry?.0 != rhsKeyAndEntry?.0 {
return false
}
if lhsKeyAndEntry?.1 != rhsKeyAndEntry?.1 {
return false
}
if lhsUnreadState != rhsUnreadState {
return false
}
return true
} else {
return false
}
case let .totalInGroup(groupId, state):
if case .totalInGroup(groupId, state) = rhs {
return true
} else {
return false
}
case let .peer(peerId, readState):
if case .peer(peerId, readState) = rhs {
return true
} else {
return false
}
}
}
}
public enum UnreadMessageCountsItemEntry {
@ -19,9 +51,12 @@ public enum UnreadMessageCountsItemEntry {
}
final class MutableUnreadMessageCountsView: MutablePostboxView {
private let items: [UnreadMessageCountsItem]
fileprivate var entries: [MutableUnreadMessageCountsItemEntry]
init(postbox: PostboxImpl, items: [UnreadMessageCountsItem]) {
self.items = items
self.entries = items.map { item in
switch item {
case let .total(preferencesKey):
@ -80,6 +115,25 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
let entries: [MutableUnreadMessageCountsItemEntry] = self.items.map { item -> MutableUnreadMessageCountsItemEntry in
switch item {
case let .total(preferencesKey):
return .total(preferencesKey.flatMap({ ($0, postbox.preferencesTable.get(key: $0)) }), postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: .root))
case let .totalInGroup(groupId):
return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId))
case let .peer(peerId):
return .peer(peerId, postbox.readStateTable.getCombinedState(peerId))
}
}
if self.entries != entries {
self.entries = entries
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return UnreadMessageCountsView(self)
@ -151,6 +205,16 @@ final class MutableCombinedReadStateView: MutablePostboxView {
return updated
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
let state = postbox.readStateTable.getCombinedState(self.peerId)
if state != self.state {
self.state = state
return true
} else {
return false
}
}
func immutableView() -> PostboxView {
return CombinedReadStateView(self)