mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-18 11:30:04 +00:00
Merge branch 'master' of https://github.com/peter-iakovlev/Postbox
This commit is contained in:
commit
d294e15e16
@ -174,6 +174,10 @@
|
||||
D0BEAF701E54BC1E00BD963D /* AccountRecordsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BEAF6F1E54BC1E00BD963D /* AccountRecordsView.swift */; };
|
||||
D0BEAF711E54BC1E00BD963D /* AccountRecordsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BEAF6F1E54BC1E00BD963D /* AccountRecordsView.swift */; };
|
||||
D0C07F6A1B67DB4800966E43 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C07F691B67DB4800966E43 /* SwiftSignalKit.framework */; };
|
||||
D0C0B5AB1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */; };
|
||||
D0C0B5AC1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */; };
|
||||
D0C0B5AE1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AD1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift */; };
|
||||
D0C0B5AF1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5AD1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift */; };
|
||||
D0C674C81CBB11C600183765 /* MessageHistoryReadStateTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C674C71CBB11C600183765 /* MessageHistoryReadStateTable.swift */; };
|
||||
D0C674CC1CBB14A700183765 /* PeerReadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C674CB1CBB14A700183765 /* PeerReadState.swift */; };
|
||||
D0C735281C864DF300BB3149 /* PeerChatStateTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C735271C864DF300BB3149 /* PeerChatStateTable.swift */; };
|
||||
@ -376,6 +380,8 @@
|
||||
D0BEAF6C1E54B77900BD963D /* AccountManagerRecordTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountManagerRecordTable.swift; sourceTree = "<group>"; };
|
||||
D0BEAF6F1E54BC1E00BD963D /* AccountRecordsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountRecordsView.swift; sourceTree = "<group>"; };
|
||||
D0C07F691B67DB4800966E43 /* SwiftSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseAssociatedPeerTable.swift; sourceTree = "<group>"; };
|
||||
D0C0B5AD1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxUpgrade_13to14.swift; sourceTree = "<group>"; };
|
||||
D0C674C71CBB11C600183765 /* MessageHistoryReadStateTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryReadStateTable.swift; sourceTree = "<group>"; };
|
||||
D0C674CB1CBB14A700183765 /* PeerReadState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerReadState.swift; sourceTree = "<group>"; };
|
||||
D0C735271C864DF300BB3149 /* PeerChatStateTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerChatStateTable.swift; sourceTree = "<group>"; };
|
||||
@ -536,6 +542,7 @@
|
||||
children = (
|
||||
D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */,
|
||||
D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */,
|
||||
D0C0B5AD1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift */,
|
||||
);
|
||||
name = Upgrade;
|
||||
sourceTree = "<group>";
|
||||
@ -577,6 +584,7 @@
|
||||
D0F3CC711DDE1CDC008148FA /* ItemCacheTable.swift */,
|
||||
D07827C21E008F7300071108 /* ReverseIndexReferenceTable.swift */,
|
||||
D07827C41E00B23F00071108 /* PeerNameIndexTable.swift */,
|
||||
D0C0B5AA1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift */,
|
||||
D0AD23261E194D1C00A7089A /* PeerOperationLogTable.swift */,
|
||||
D010B6191E1E463900C3E282 /* PeerMergedOperationLogIndexTable.swift */,
|
||||
D0AD23281E196B6400A7089A /* PeerOperationLogMetadataTable.swift */,
|
||||
@ -978,6 +986,7 @@
|
||||
D0BEAF641E54B2FA00BD963D /* AccountManager.swift in Sources */,
|
||||
D073CE7F1DCBF3B4007511FD /* ItemCollection.swift in Sources */,
|
||||
D0F7B1D91E045C6A007EB8A5 /* OrderStatisticTable.swift in Sources */,
|
||||
D0C0B5AF1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift in Sources */,
|
||||
D073CEA01DCBF3C1007511FD /* ItemCollectionsView.swift in Sources */,
|
||||
D0BE383A1E7C1FD4000079AF /* ItemCollectionInfoView.swift in Sources */,
|
||||
D0B418491D7DFE20004562A4 /* ChatListView.swift in Sources */,
|
||||
@ -1027,6 +1036,7 @@
|
||||
D0B418311D7DFE16004562A4 /* ValueBox.swift in Sources */,
|
||||
D08775041E3E3E7400A97350 /* PreferencesEntry.swift in Sources */,
|
||||
D0B4184E1D7DFE20004562A4 /* MessageHistoryHolesView.swift in Sources */,
|
||||
D0C0B5AC1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift in Sources */,
|
||||
D0B844051DAB91B5005F29E1 /* MediaBox.swift in Sources */,
|
||||
D0B418321D7DFE16004562A4 /* SqliteValueBox.swift in Sources */,
|
||||
D073CE741DCBF3B4007511FD /* Peer.swift in Sources */,
|
||||
@ -1105,6 +1115,7 @@
|
||||
D0BEAF631E54B2FA00BD963D /* AccountManager.swift in Sources */,
|
||||
D0AD23271E194D1C00A7089A /* PeerOperationLogTable.swift in Sources */,
|
||||
D021E0D41DB4FAE100C6B04F /* ItemCollection.swift in Sources */,
|
||||
D0C0B5AE1EE1B3F4000F4D2C /* PostboxUpgrade_13to14.swift in Sources */,
|
||||
D0D510F91D63BCC200A97B8A /* IntermediateMessage.swift in Sources */,
|
||||
D0BE38391E7C1FD4000079AF /* ItemCollectionInfoView.swift in Sources */,
|
||||
D0F9E86B1C59719800037222 /* ChatListView.swift in Sources */,
|
||||
@ -1154,6 +1165,7 @@
|
||||
D03120FC1DA55427006A2A60 /* PeerNotificationSettings.swift in Sources */,
|
||||
D0F7AB321DCFAB18009AD9A1 /* PeerChatTopIndexableMessageIds.swift in Sources */,
|
||||
D03BCCF81C73561C0097A291 /* Table.swift in Sources */,
|
||||
D0C0B5AB1EE1AB08000F4D2C /* ReverseAssociatedPeerTable.swift in Sources */,
|
||||
D021E0DC1DB5237C00C6B04F /* ItemCollectionsView.swift in Sources */,
|
||||
D0C735281C864DF300BB3149 /* PeerChatStateTable.swift in Sources */,
|
||||
D0AAD1B31E3266B100D5B9DE /* TimestampBasedMessageAttributesTable.swift in Sources */,
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0900"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0900"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -444,11 +444,9 @@ final class MutableChatListView {
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
if let peer = getPeer(index.messageIndex.id.peerId) {
|
||||
peers[peer.id] = peer
|
||||
if let associatedPeerIds = peer.associatedPeerIds {
|
||||
for associatedPeerId in associatedPeerIds {
|
||||
if let associatedPeer = getPeer(associatedPeerId) {
|
||||
peers[associatedPeer.id] = associatedPeer
|
||||
}
|
||||
if let associatedPeerId = peer.associatedPeerId {
|
||||
if let associatedPeer = getPeer(associatedPeerId) {
|
||||
peers[associatedPeer.id] = associatedPeer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1625,11 +1625,9 @@ final class MessageHistoryTable: Table {
|
||||
if let chatPeer = peerTable.get(message.id.peerId) {
|
||||
peers[chatPeer.id] = chatPeer
|
||||
|
||||
if let associatedPeerIds = chatPeer.associatedPeerIds {
|
||||
for peerId in associatedPeerIds {
|
||||
if let peer = peerTable.get(peerId) {
|
||||
peers[peer.id] = peer
|
||||
}
|
||||
if let associatedPeerId = chatPeer.associatedPeerId {
|
||||
if let peer = peerTable.get(associatedPeerId) {
|
||||
peers[peer.id] = peer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public func <(lhs: PeerId, rhs: PeerId) -> Bool {
|
||||
public protocol Peer: class, Coding {
|
||||
var id: PeerId { get }
|
||||
var indexName: PeerIndexNameRepresentation { get }
|
||||
var associatedPeerIds: [PeerId]? { get }
|
||||
var associatedPeerId: PeerId? { get }
|
||||
var notificationSettingsPeerId: PeerId? { get }
|
||||
|
||||
func isEqual(_ other: Peer) -> Bool
|
||||
|
@ -257,7 +257,7 @@ final class PeerNameIndexTable: Table {
|
||||
}
|
||||
}
|
||||
|
||||
func matchingPeerIds(tokens: (regular: [ValueBoxKey], transliterated: [ValueBoxKey]?), categories: PeerNameIndexCategories, chatListIndexTable: ChatListIndexTable, contactTable: ContactTable) -> (chats: [PeerId], contacts: [PeerId]) {
|
||||
func matchingPeerIds(tokens: (regular: [ValueBoxKey], transliterated: [ValueBoxKey]?), categories: PeerNameIndexCategories, chatListIndexTable: ChatListIndexTable, contactTable: ContactTable, reverseAssociatedPeerTable: ReverseAssociatedPeerTable) -> (chats: [PeerId], contacts: [PeerId]) {
|
||||
if categories.isEmpty {
|
||||
return ([], [])
|
||||
} else {
|
||||
|
@ -5,11 +5,19 @@ final class PeerTable: Table {
|
||||
return ValueBoxTable(id: id, keyType: .int64)
|
||||
}
|
||||
|
||||
private let reverseAssociatedTable: ReverseAssociatedPeerTable
|
||||
|
||||
private let sharedEncoder = Encoder()
|
||||
private let sharedKey = ValueBoxKey(length: 8)
|
||||
|
||||
private var cachedPeers: [PeerId: Peer] = [:]
|
||||
private var updatedPeerIds = Set<PeerId>()
|
||||
private var updatedInitialPeers: [PeerId: Peer?] = [:]
|
||||
|
||||
init(valueBox: ValueBox, table: ValueBoxTable, reverseAssociatedTable: ReverseAssociatedPeerTable) {
|
||||
self.reverseAssociatedTable = reverseAssociatedTable
|
||||
|
||||
super.init(valueBox: valueBox, table: table)
|
||||
}
|
||||
|
||||
private func key(_ id: PeerId) -> ValueBoxKey {
|
||||
self.sharedKey.setInt64(0, value: id.toInt64())
|
||||
@ -17,8 +25,11 @@ final class PeerTable: Table {
|
||||
}
|
||||
|
||||
func set(_ peer: Peer) {
|
||||
let previous = self.get(peer.id)
|
||||
self.cachedPeers[peer.id] = peer
|
||||
self.updatedPeerIds.insert(peer.id)
|
||||
if self.updatedInitialPeers[peer.id] == nil {
|
||||
self.updatedInitialPeers[peer.id] = previous
|
||||
}
|
||||
}
|
||||
|
||||
func get(_ id: PeerId) -> Peer? {
|
||||
@ -36,19 +47,31 @@ final class PeerTable: Table {
|
||||
|
||||
override func clearMemoryCache() {
|
||||
self.cachedPeers.removeAll()
|
||||
self.updatedPeerIds.removeAll()
|
||||
assert(self.updatedInitialPeers.isEmpty)
|
||||
}
|
||||
|
||||
override func beforeCommit() {
|
||||
for peerId in self.updatedPeerIds {
|
||||
for (peerId, previousPeer) in self.updatedInitialPeers {
|
||||
if let peer = self.cachedPeers[peerId] {
|
||||
self.sharedEncoder.reset()
|
||||
self.sharedEncoder.encodeRootObject(peer)
|
||||
|
||||
self.valueBox.set(self.table, key: self.key(peerId), value: self.sharedEncoder.readBufferNoCopy())
|
||||
|
||||
let previousAssociation = previousPeer?.associatedPeerId
|
||||
if previousAssociation != peer.associatedPeerId {
|
||||
if let previousAssociation = previousAssociation {
|
||||
self.reverseAssociatedTable.removeReverseAssociation(target: previousAssociation, from: peerId)
|
||||
}
|
||||
if let associatedPeerId = peer.associatedPeerId {
|
||||
self.reverseAssociatedTable.addReverseAssociation(target: associatedPeerId, from: peerId)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
self.updatedPeerIds.removeAll()
|
||||
self.updatedInitialPeers.removeAll()
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
final class MutablePeerView {
|
||||
final class MutablePeerView: MutablePostboxView {
|
||||
let peerId: PeerId
|
||||
var notificationSettings: PeerNotificationSettings?
|
||||
var cachedData: CachedPeerData?
|
||||
@ -8,17 +8,27 @@ final class MutablePeerView {
|
||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||
var peerIsContact: Bool
|
||||
|
||||
init(peerId: PeerId, notificationSettings: PeerNotificationSettings?, cachedData: CachedPeerData?, peerIsContact: Bool, getPeer: (PeerId) -> Peer?, getPeerPresence: (PeerId) -> PeerPresence?) {
|
||||
init(postbox: Postbox, peerId: PeerId) {
|
||||
let notificationSettings = postbox.peerNotificationSettingsTable.get(peerId)
|
||||
let cachedData = postbox.cachedPeerDataTable.get(peerId)
|
||||
let peerIsContact = postbox.contactsTable.isContact(peerId: peerId)
|
||||
|
||||
let getPeer: (PeerId) -> Peer? = { peerId in
|
||||
return postbox.peerTable.get(peerId)
|
||||
}
|
||||
|
||||
let getPeerPresence: (PeerId) -> PeerPresence? = { peerId in
|
||||
return postbox.peerPresenceTable.get(peerId)
|
||||
}
|
||||
|
||||
self.peerId = peerId
|
||||
self.notificationSettings = notificationSettings
|
||||
self.cachedData = cachedData
|
||||
self.peerIsContact = peerIsContact
|
||||
var peerIds = Set<PeerId>()
|
||||
peerIds.insert(peerId)
|
||||
if let peer = getPeer(peerId), let associatedPeerIds = peer.associatedPeerIds {
|
||||
for peerId in associatedPeerIds {
|
||||
peerIds.insert(peerId)
|
||||
}
|
||||
if let peer = getPeer(peerId), let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
}
|
||||
if let cachedData = cachedData {
|
||||
peerIds.formUnion(cachedData.peerIds)
|
||||
@ -31,19 +41,35 @@ final class MutablePeerView {
|
||||
self.peerPresences[id] = presence
|
||||
}
|
||||
}
|
||||
if let peer = self.peers[peerId], let associatedPeerIds = peer.associatedPeerIds {
|
||||
for id in associatedPeerIds {
|
||||
if let peer = getPeer(id) {
|
||||
self.peers[id] = peer
|
||||
}
|
||||
if let presence = getPeerPresence(id) {
|
||||
self.peerPresences[id] = presence
|
||||
}
|
||||
if let peer = self.peers[peerId], let associatedPeerId = peer.associatedPeerId {
|
||||
if let peer = getPeer(associatedPeerId) {
|
||||
self.peers[associatedPeerId] = peer
|
||||
}
|
||||
if let presence = getPeerPresence(associatedPeerId) {
|
||||
self.peerPresences[associatedPeerId] = presence
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func replay(updatedPeers: [PeerId: Peer], updatedNotificationSettings: [PeerId: PeerNotificationSettings], updatedCachedPeerData: [PeerId: CachedPeerData], updatedPeerPresences: [PeerId: PeerPresence], replaceContactPeerIds: Set<PeerId>?, getPeer: (PeerId) -> Peer?, getPeerPresence: (PeerId) -> PeerPresence?) -> Bool {
|
||||
func reset(postbox: Postbox) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func replay(postbox: Postbox, transaction: PostboxTransaction) -> Bool {
|
||||
let updatedPeers = transaction.currentUpdatedPeers
|
||||
let updatedNotificationSettings = transaction.currentUpdatedPeerNotificationSettings
|
||||
let updatedCachedPeerData = transaction.currentUpdatedCachedPeerData
|
||||
let updatedPeerPresences = transaction.currentUpdatedPeerPresences
|
||||
let replaceContactPeerIds = transaction.replaceContactPeerIds
|
||||
|
||||
let getPeer: (PeerId) -> Peer? = { peerId in
|
||||
return postbox.peerTable.get(peerId)
|
||||
}
|
||||
|
||||
let getPeerPresence: (PeerId) -> PeerPresence? = { peerId in
|
||||
return postbox.peerPresenceTable.get(peerId)
|
||||
}
|
||||
|
||||
var updated = false
|
||||
|
||||
if let cachedData = updatedCachedPeerData[self.peerId], self.cachedData == nil || !self.cachedData!.isEqual(to: cachedData) {
|
||||
@ -52,10 +78,8 @@ final class MutablePeerView {
|
||||
|
||||
var peerIds = Set<PeerId>()
|
||||
peerIds.insert(self.peerId)
|
||||
if let peer = getPeer(self.peerId), let associatedPeerIds = peer.associatedPeerIds {
|
||||
for peerId in associatedPeerIds {
|
||||
peerIds.insert(peerId)
|
||||
}
|
||||
if let peer = getPeer(self.peerId), let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
}
|
||||
peerIds.formUnion(cachedData.peerIds)
|
||||
|
||||
@ -97,10 +121,8 @@ final class MutablePeerView {
|
||||
} else {
|
||||
var peerIds = Set<PeerId>()
|
||||
peerIds.insert(self.peerId)
|
||||
if let peer = getPeer(self.peerId), let associatedPeerIds = peer.associatedPeerIds {
|
||||
for peerId in associatedPeerIds {
|
||||
peerIds.insert(peerId)
|
||||
}
|
||||
if let peer = getPeer(self.peerId), let associatedPeerId = peer.associatedPeerId {
|
||||
peerIds.insert(associatedPeerId)
|
||||
}
|
||||
if let cachedData = self.cachedData {
|
||||
peerIds.formUnion(cachedData.peerIds)
|
||||
@ -139,9 +161,13 @@ final class MutablePeerView {
|
||||
|
||||
return updated
|
||||
}
|
||||
|
||||
func immutableView() -> PostboxView {
|
||||
return PeerView(self)
|
||||
}
|
||||
}
|
||||
|
||||
public final class PeerView {
|
||||
public final class PeerView: PostboxView {
|
||||
public let peerId: PeerId
|
||||
public let cachedData: CachedPeerData?
|
||||
public let notificationSettings: PeerNotificationSettings?
|
||||
|
@ -739,6 +739,7 @@ public final class Postbox {
|
||||
let itemCacheTable: ItemCacheTable
|
||||
let peerNameTokenIndexTable: ReverseIndexReferenceTable<PeerIdReverseIndexReference>
|
||||
let peerNameIndexTable: PeerNameIndexTable
|
||||
let reverseAssociatedPeerTable: ReverseAssociatedPeerTable
|
||||
let peerChatTopTaggedMessageIdsTable: PeerChatTopTaggedMessageIdsTable
|
||||
let peerOperationLogMetadataTable: PeerOperationLogMetadataTable
|
||||
let peerMergedOperationLogIndexTable: PeerMergedOperationLogIndexTable
|
||||
@ -782,7 +783,8 @@ public final class Postbox {
|
||||
self.metadataTable = MetadataTable(valueBox: self.valueBox, table: MetadataTable.tableSpec(0))
|
||||
|
||||
self.keychainTable = KeychainTable(valueBox: self.valueBox, table: KeychainTable.tableSpec(1))
|
||||
self.peerTable = PeerTable(valueBox: self.valueBox, table: PeerTable.tableSpec(2))
|
||||
self.reverseAssociatedPeerTable = ReverseAssociatedPeerTable(valueBox: self.valueBox, table:ReverseAssociatedPeerTable.tableSpec(40))
|
||||
self.peerTable = PeerTable(valueBox: self.valueBox, table: PeerTable.tableSpec(2), reverseAssociatedTable: self.reverseAssociatedPeerTable)
|
||||
self.globalMessageIdsTable = GlobalMessageIdsTable(valueBox: self.valueBox, table: GlobalMessageIdsTable.tableSpec(3), namespace: self.globalMessageIdsNamespace)
|
||||
self.globallyUniqueMessageIdsTable = MessageGloballyUniqueIdTable(valueBox: self.valueBox, table: MessageGloballyUniqueIdTable.tableSpec(32))
|
||||
self.messageHistoryMetadataTable = MessageHistoryMetadataTable(valueBox: self.valueBox, table: MessageHistoryMetadataTable.tableSpec(10))
|
||||
@ -850,6 +852,7 @@ public final class Postbox {
|
||||
tables.append(self.itemCacheMetaTable)
|
||||
tables.append(self.itemCacheTable)
|
||||
tables.append(self.peerNameIndexTable)
|
||||
tables.append(self.reverseAssociatedPeerTable)
|
||||
tables.append(self.peerNameTokenIndexTable)
|
||||
tables.append(self.peerChatTopTaggedMessageIdsTable)
|
||||
tables.append(self.peerOperationLogMetadataTable)
|
||||
@ -1257,7 +1260,7 @@ public final class Postbox {
|
||||
for table in self.tables {
|
||||
table.clearMemoryCache()
|
||||
}
|
||||
self.viewTracker.refreshViewsDueToExternalTransaction(fetchAroundChatEntries: self.fetchAroundChatEntries, fetchAroundHistoryEntries: self.fetchAroundHistoryEntries, fetchUnsentMessageIds: {
|
||||
self.viewTracker.refreshViewsDueToExternalTransaction(postbox: self, fetchAroundChatEntries: self.fetchAroundChatEntries, fetchAroundHistoryEntries: self.fetchAroundHistoryEntries, fetchUnsentMessageIds: {
|
||||
return self.messageHistoryUnsentTable.get()
|
||||
}, fetchSynchronizePeerReadStateOperations: {
|
||||
return self.synchronizeReadStateTable.get(getCombinedPeerReadState: { peerId in
|
||||
@ -1781,7 +1784,7 @@ public final class Postbox {
|
||||
|
||||
public func searchContacts(query: String) -> Signal<[Peer], NoError> {
|
||||
return self.modify { modifier -> Signal<[Peer], NoError> in
|
||||
let (_, contactPeerIds) = self.peerNameIndexTable.matchingPeerIds(tokens: (regular: stringIndexTokens(query, transliteration: .none), transliterated: stringIndexTokens(query, transliteration: .transliterated)), categories: [.contacts], chatListIndexTable: self.chatListIndexTable, contactTable: self.contactsTable)
|
||||
let (_, contactPeerIds) = self.peerNameIndexTable.matchingPeerIds(tokens: (regular: stringIndexTokens(query, transliteration: .none), transliterated: stringIndexTokens(query, transliteration: .transliterated)), categories: [.contacts], chatListIndexTable: self.chatListIndexTable, contactTable: self.contactsTable, reverseAssociatedPeerTable: self.reverseAssociatedPeerTable)
|
||||
|
||||
var contactPeers: [Peer] = []
|
||||
for peerId in contactPeerIds {
|
||||
@ -1800,7 +1803,7 @@ public final class Postbox {
|
||||
var peerIds = Set<PeerId>()
|
||||
var chatPeers: [Peer] = []
|
||||
|
||||
let (chatPeerIds, contactPeerIds) = self.peerNameIndexTable.matchingPeerIds(tokens: (regular: stringIndexTokens(query, transliteration: .none), transliterated: stringIndexTokens(query, transliteration: .transliterated)), categories: [.chats, .contacts], chatListIndexTable: self.chatListIndexTable, contactTable: self.contactsTable)
|
||||
let (chatPeerIds, contactPeerIds) = self.peerNameIndexTable.matchingPeerIds(tokens: (regular: stringIndexTokens(query, transliteration: .none), transliterated: stringIndexTokens(query, transliteration: .transliterated)), categories: [.chats, .contacts], chatListIndexTable: self.chatListIndexTable, contactTable: self.contactsTable, reverseAssociatedPeerTable: self.reverseAssociatedPeerTable)
|
||||
|
||||
for peerId in chatPeerIds {
|
||||
if let peer = self.peerTable.get(peerId) {
|
||||
@ -1825,7 +1828,7 @@ public final class Postbox {
|
||||
|
||||
public func peerView(id: PeerId) -> Signal<PeerView, NoError> {
|
||||
return self.modify { modifier -> Signal<PeerView, NoError> in
|
||||
let view = MutablePeerView(peerId: id, notificationSettings: self.peerNotificationSettingsTable.get(id), cachedData: self.cachedPeerDataTable.get(id), peerIsContact: self.contactsTable.isContact(peerId: id), getPeer: { self.peerTable.get($0) }, getPeerPresence: { self.peerPresenceTable.get($0) })
|
||||
let view = MutablePeerView(postbox: self, peerId: id)
|
||||
let (index, signal) = self.viewTracker.addPeerView(view)
|
||||
|
||||
return (.single(PeerView(view))
|
||||
|
41
Postbox/PostboxUpgrade_13to14.swift
Normal file
41
Postbox/PostboxUpgrade_13to14.swift
Normal file
@ -0,0 +1,41 @@
|
||||
import Foundation
|
||||
|
||||
private func writePeerIds(_ buffer: WriteBuffer, _ peerIds: Set<PeerId>) {
|
||||
for id in peerIds {
|
||||
var value: Int64 = id.toInt64()
|
||||
buffer.write(&value, offset: 0, length: 8)
|
||||
}
|
||||
}
|
||||
|
||||
func postboxUpgrade_13to14(metadataTable: MetadataTable, valueBox: ValueBox) {
|
||||
var reverseAssociations: [PeerId: Set<PeerId>] = [:]
|
||||
|
||||
let peerTable = ValueBoxTable(id: 2, keyType: .int64)
|
||||
valueBox.scan(peerTable, values: { _, value in
|
||||
if let peer = Decoder(buffer: value).decodeRootObject() as? Peer {
|
||||
if let association = peer.associatedPeerId {
|
||||
if reverseAssociations[association] == nil {
|
||||
reverseAssociations[association] = Set()
|
||||
}
|
||||
reverseAssociations[association]!.insert(peer.id)
|
||||
}
|
||||
} else {
|
||||
assertionFailure()
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
let reverseAssociatedPeerTable = ValueBoxTable(id: 40, keyType: .int64)
|
||||
|
||||
let sharedKey = ValueBoxKey(length: 8)
|
||||
let sharedBuffer = WriteBuffer()
|
||||
for (peerId, associations) in reverseAssociations {
|
||||
sharedBuffer.reset()
|
||||
writePeerIds(sharedBuffer, associations)
|
||||
|
||||
sharedKey.setInt64(0, value: peerId.toInt64())
|
||||
valueBox.set(reverseAssociatedPeerTable, key: sharedKey, value: sharedBuffer)
|
||||
}
|
||||
|
||||
metadataTable.setUserVersion(14)
|
||||
}
|
99
Postbox/ReverseAssociatedPeerTable.swift
Normal file
99
Postbox/ReverseAssociatedPeerTable.swift
Normal file
@ -0,0 +1,99 @@
|
||||
import Foundation
|
||||
|
||||
private func readPeerIds(_ buffer: ReadBuffer) -> Set<PeerId> {
|
||||
assert(buffer.length % 8 == 0)
|
||||
let count = buffer.length / 8
|
||||
var result = Set<PeerId>()
|
||||
for _ in 0 ..< count {
|
||||
var value: Int64 = 0
|
||||
buffer.read(&value, offset: 0, length: 8)
|
||||
result.insert(PeerId(value))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private func writePeerIds(_ buffer: WriteBuffer, _ peerIds: Set<PeerId>) {
|
||||
for id in peerIds {
|
||||
var value: Int64 = id.toInt64()
|
||||
buffer.write(&value, offset: 0, length: 8)
|
||||
}
|
||||
}
|
||||
|
||||
final class ReverseAssociatedPeerTable: Table {
|
||||
static func tableSpec(_ id: Int32) -> ValueBoxTable {
|
||||
return ValueBoxTable(id: id, keyType: .int64)
|
||||
}
|
||||
|
||||
private let sharedKey = ValueBoxKey(length: 8)
|
||||
|
||||
private var cachedAssociations: [PeerId: Set<PeerId>] = [:]
|
||||
private var updatedAssociations = Set<PeerId>()
|
||||
|
||||
private func key(_ peerId: PeerId) -> ValueBoxKey {
|
||||
self.sharedKey.setInt64(0, value: peerId.toInt64())
|
||||
return self.sharedKey
|
||||
}
|
||||
|
||||
func get(peerId: PeerId) -> Set<PeerId> {
|
||||
if let cached = self.cachedAssociations[peerId] {
|
||||
return cached
|
||||
} else {
|
||||
if let value = self.valueBox.get(self.table, key: self.key(peerId)) {
|
||||
let peerIds = readPeerIds(value)
|
||||
self.cachedAssociations[peerId] = peerIds
|
||||
return peerIds
|
||||
} else {
|
||||
self.cachedAssociations[peerId] = Set()
|
||||
return Set()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addReverseAssociation(target targetPeerId: PeerId, from sourcePeerId: PeerId) {
|
||||
var value = self.get(peerId: targetPeerId)
|
||||
if value.contains(sourcePeerId) {
|
||||
assertionFailure()
|
||||
} else {
|
||||
value.insert(sourcePeerId)
|
||||
self.cachedAssociations[targetPeerId] = value
|
||||
self.updatedAssociations.insert(targetPeerId)
|
||||
}
|
||||
}
|
||||
|
||||
func removeReverseAssociation(target targetPeerId: PeerId, from sourcePeerId: PeerId) {
|
||||
var value = self.get(peerId: targetPeerId)
|
||||
if !value.contains(sourcePeerId) {
|
||||
assertionFailure()
|
||||
} else {
|
||||
value.remove(sourcePeerId)
|
||||
self.cachedAssociations[targetPeerId] = value
|
||||
self.updatedAssociations.insert(targetPeerId)
|
||||
}
|
||||
}
|
||||
|
||||
override func clearMemoryCache() {
|
||||
self.cachedAssociations.removeAll()
|
||||
assert(self.updatedAssociations.isEmpty)
|
||||
}
|
||||
|
||||
override func beforeCommit() {
|
||||
if !self.updatedAssociations.isEmpty {
|
||||
let buffer = WriteBuffer()
|
||||
for peerId in self.updatedAssociations {
|
||||
if let peerIds = self.cachedAssociations[peerId] {
|
||||
if peerIds.isEmpty {
|
||||
self.valueBox.remove(self.table, key: self.key(peerId))
|
||||
} else {
|
||||
buffer.reset()
|
||||
writePeerIds(buffer, peerIds)
|
||||
self.valueBox.set(self.table, key: self.key(peerId), value: buffer)
|
||||
}
|
||||
} else {
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
self.updatedAssociations.removeAll()
|
||||
}
|
||||
}
|
||||
}
|
@ -7,5 +7,6 @@ enum PostboxUpgradeOperation {
|
||||
func registeredUpgrades() -> [Int32: PostboxUpgradeOperation] {
|
||||
var dict: [Int32: PostboxUpgradeOperation] = [:]
|
||||
dict[12] = .inplace(postboxUpgrade_12to13)
|
||||
dict[13] = .inplace(postboxUpgrade_13to14)
|
||||
return dict
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ final class ViewTracker {
|
||||
self.combinedViews.remove(index)
|
||||
}
|
||||
|
||||
func refreshViewsDueToExternalTransaction(fetchAroundChatEntries: (_ index: ChatListIndex, _ count: Int) -> (entries: [MutableChatListEntry], earlier: MutableChatListEntry?, later: MutableChatListEntry?), fetchAroundHistoryEntries: (_ index: MessageIndex, _ count: Int, _ tagMask: MessageTags?) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?), fetchUnsentMessageIds: () -> [MessageId], fetchSynchronizePeerReadStateOperations: () -> [PeerId: PeerReadStateSynchronizationOperation]) {
|
||||
func refreshViewsDueToExternalTransaction(postbox: Postbox, fetchAroundChatEntries: (_ index: ChatListIndex, _ count: Int) -> (entries: [MutableChatListEntry], earlier: MutableChatListEntry?, later: MutableChatListEntry?), fetchAroundHistoryEntries: (_ index: MessageIndex, _ count: Int, _ tagMask: MessageTags?) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?), fetchUnsentMessageIds: () -> [MessageId], fetchSynchronizePeerReadStateOperations: () -> [PeerId: PeerReadStateSynchronizationOperation]) {
|
||||
var updateTrackedHolesPeerIds: [PeerId] = []
|
||||
|
||||
for (peerId, bag) in self.messageHistoryViews {
|
||||
@ -327,35 +327,7 @@ final class ViewTracker {
|
||||
}
|
||||
|
||||
for (mutableView, pipe) in self.peerViews.copyItems() {
|
||||
var updatedPeers: [PeerId: Peer] = [:]
|
||||
var updatedPeerPresences: [PeerId: PeerPresence] = [:]
|
||||
var updatedNotificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
||||
var updatedCachedPeerData: [PeerId: CachedPeerData] = [:]
|
||||
|
||||
let peerId = mutableView.peerId
|
||||
|
||||
if let peer = self.getPeer(peerId) {
|
||||
updatedPeers[peerId] = peer
|
||||
}
|
||||
if let presence = self.getPeerPresence(peerId) {
|
||||
updatedPeerPresences[peerId] = presence
|
||||
}
|
||||
if let notificationSettings = self.getPeerNotificationSettings(peerId) {
|
||||
updatedNotificationSettings[peerId] = notificationSettings
|
||||
}
|
||||
if let cachedPeerData = self.getCachedPeerData(peerId) {
|
||||
updatedCachedPeerData[peerId] = cachedPeerData
|
||||
for cachedPeerId in cachedPeerData.peerIds {
|
||||
if let peer = self.getPeer(cachedPeerId) {
|
||||
updatedPeers[cachedPeerId] = peer
|
||||
}
|
||||
if let presence = self.getPeerPresence(cachedPeerId) {
|
||||
updatedPeerPresences[cachedPeerId] = presence
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if mutableView.replay(updatedPeers: updatedPeers, updatedNotificationSettings: updatedNotificationSettings, updatedCachedPeerData: updatedCachedPeerData, updatedPeerPresences: updatedPeerPresences, replaceContactPeerIds: nil, getPeer: self.getPeer, getPeerPresence: self.getPeerPresence) {
|
||||
if mutableView.reset(postbox: postbox) {
|
||||
pipe.putNext(PeerView(mutableView))
|
||||
}
|
||||
}
|
||||
@ -483,7 +455,7 @@ final class ViewTracker {
|
||||
}
|
||||
|
||||
for (mutableView, pipe) in self.peerViews.copyItems() {
|
||||
if mutableView.replay(updatedPeers: transaction.currentUpdatedPeers, updatedNotificationSettings: transaction.currentUpdatedPeerNotificationSettings, updatedCachedPeerData: transaction.currentUpdatedCachedPeerData, updatedPeerPresences: transaction.currentUpdatedPeerPresences, replaceContactPeerIds: transaction.replaceContactPeerIds, getPeer: self.getPeer, getPeerPresence: self.getPeerPresence) {
|
||||
if mutableView.replay(postbox: postbox, transaction: transaction) {
|
||||
pipe.putNext(PeerView(mutableView))
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ public enum PostboxViewKey: Hashable {
|
||||
case accessChallengeData
|
||||
case preferences(keys: Set<ValueBoxKey>)
|
||||
case globalMessageTags(globalTag: GlobalMessageTags, position: MessageIndex, count: Int, groupingPredicate: ((Message, Message) -> Bool)?)
|
||||
case peer(peerId: PeerId)
|
||||
|
||||
public var hashValue: Int {
|
||||
switch self {
|
||||
@ -28,6 +29,8 @@ public enum PostboxViewKey: Hashable {
|
||||
return 3
|
||||
case .globalMessageTags:
|
||||
return 4
|
||||
case let .peer(peerId):
|
||||
return peerId.hashValue
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,6 +84,12 @@ public enum PostboxViewKey: Hashable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .peer(peerId):
|
||||
if case .peer(peerId) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,5 +112,7 @@ func postboxViewForKey(postbox: Postbox, key: PostboxViewKey) -> MutablePostboxV
|
||||
return MutablePreferencesView(postbox: postbox, keys: keys)
|
||||
case let .globalMessageTags(globalTag, position, count, groupingPredicate):
|
||||
return MutableGlobalMessageTagsView(postbox: postbox, globalTag: globalTag, position: position, count: count, groupingPredicate: groupingPredicate)
|
||||
case let .peer(peerId):
|
||||
return MutablePeerView(postbox: postbox, peerId: peerId)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user