diff --git a/Postbox/ContactTable.swift b/Postbox/ContactTable.swift index f9b8d05fab..38c65d5747 100644 --- a/Postbox/ContactTable.swift +++ b/Postbox/ContactTable.swift @@ -5,11 +5,16 @@ final class ContactTable: Table { return ValueBoxTable(id: id, keyType: .binary) } - private var originalPeerIds: Set? + private let peerNameIndexTable: PeerNameIndexTable + + private var peerIdsBeforeModification: Set? private var peerIds: Set? - private var addedPeerIds = Set() - private var removedPeerIds = Set() + init(valueBox: ValueBox, table: ValueBoxTable, peerNameIndexTable: PeerNameIndexTable) { + self.peerNameIndexTable = peerNameIndexTable + + super.init(valueBox: valueBox, table: table) + } private func key(_ id: PeerId, sharedKey: ValueBoxKey = ValueBoxKey(length: 8)) -> ValueBoxKey { sharedKey.setInt64(0, value: id.toInt64()) @@ -25,18 +30,7 @@ final class ContactTable: Table { } func isContact(peerId: PeerId) -> Bool { - if let peerIds = self.peerIds { - return peerIds.contains(peerId) - } else { - var peerIds = Set() - self.valueBox.range(self.table, start: self.lowerBound(), end: self.upperBound(), keys: { key in - peerIds.insert(PeerId(key.getInt64(0))) - return true - }, limit: 0) - self.peerIds = peerIds - self.originalPeerIds = peerIds - return peerIds.contains(peerId) - } + return self.get().contains(peerId) } func get() -> Set { @@ -49,49 +43,45 @@ final class ContactTable: Table { return true }, limit: 0) self.peerIds = peerIds - self.originalPeerIds = peerIds return peerIds } } func replace(_ ids: Set) { - let currentPeerIds = self.get() - - let previousPeerIds: Set - if let originalPeerIds = self.originalPeerIds { - previousPeerIds = originalPeerIds - } else { - previousPeerIds = currentPeerIds - self.originalPeerIds = currentPeerIds + if self.peerIdsBeforeModification == nil { + self.peerIdsBeforeModification = self.get() } - self.removedPeerIds = previousPeerIds.subtracting(ids) - self.addedPeerIds = ids.subtracting(previousPeerIds) - self.peerIds = ids } override func clearMemoryCache() { - self.originalPeerIds = nil + assert(self.peerIdsBeforeModification == nil) self.peerIds = nil - self.addedPeerIds.removeAll() - self.removedPeerIds.removeAll() } override func beforeCommit() { - let sharedKey = self.key(PeerId(namespace: 0, id: 0)) - - for peerId in self.removedPeerIds { - self.valueBox.remove(self.table, key: self.key(peerId, sharedKey: sharedKey)) + if let peerIdsBeforeModification = self.peerIdsBeforeModification { + if let peerIds = self.peerIds { + let removedPeerIds = peerIdsBeforeModification.subtracting(peerIds) + let addedPeerIds = peerIds.subtracting(peerIdsBeforeModification) + + let sharedKey = self.key(PeerId(namespace: 0, id: 0)) + + for peerId in removedPeerIds { + self.valueBox.remove(self.table, key: self.key(peerId, sharedKey: sharedKey)) + self.peerNameIndexTable.setPeerCategoryState(peerId: peerId, category: [.contacts], includes: false) + } + + for peerId in addedPeerIds { + self.valueBox.set(self.table, key: self.key(peerId, sharedKey: sharedKey), value: MemoryBuffer()) + self.peerNameIndexTable.setPeerCategoryState(peerId: peerId, category: [.contacts], includes: true) + } + } else { + assertionFailure() + } + + self.peerIdsBeforeModification = nil } - - for peerId in self.addedPeerIds { - self.valueBox.set(self.table, key: self.key(peerId, sharedKey: sharedKey), value: MemoryBuffer()) - } - - self.originalPeerIds = self.peerIds - - self.addedPeerIds.removeAll() - self.removedPeerIds.removeAll() } } diff --git a/Postbox/Postbox.swift b/Postbox/Postbox.swift index 18b4eeed62..ba3841ab83 100644 --- a/Postbox/Postbox.swift +++ b/Postbox/Postbox.swift @@ -574,7 +574,9 @@ public final class Postbox { self.timestampBasedMessageAttributesTable = TimestampBasedMessageAttributesTable(valueBox: self.valueBox!, table: TimestampBasedMessageAttributesTable.tableSpec(34), indexTable: self.timestampBasedMessageAttributesIndexTable) self.messageHistoryTable = MessageHistoryTable(valueBox: self.valueBox, table: MessageHistoryTable.tableSpec(7), messageHistoryIndexTable: self.messageHistoryIndexTable, messageMediaTable: self.mediaTable, historyMetadataTable: self.messageHistoryMetadataTable, globallyUniqueMessageIdsTable: self.globallyUniqueMessageIdsTable!, unsentTable: self.messageHistoryUnsentTable!, tagsTable: self.messageHistoryTagsTable, readStateTable: self.readStateTable, synchronizeReadStateTable: self.synchronizeReadStateTable!) self.peerChatStateTable = PeerChatStateTable(valueBox: self.valueBox, table: PeerChatStateTable.tableSpec(13)) - self.contactsTable = ContactTable(valueBox: self.valueBox, table: ContactTable.tableSpec(16)) + self.peerNameTokenIndexTable = ReverseIndexReferenceTable(valueBox: self.valueBox, table: ReverseIndexReferenceTable.tableSpec(26)) + self.peerNameIndexTable = PeerNameIndexTable(valueBox: self.valueBox, table: PeerNameIndexTable.tableSpec(27), peerTable: self.peerTable, peerNameTokenIndexTable: self.peerNameTokenIndexTable) + self.contactsTable = ContactTable(valueBox: self.valueBox, table: ContactTable.tableSpec(16), peerNameIndexTable: self.peerNameIndexTable) self.peerRatingTable = RatingTable(valueBox: self.valueBox, table: RatingTable.tableSpec(17)) self.cachedPeerDataTable = CachedPeerDataTable(valueBox: self.valueBox, table: CachedPeerDataTable.tableSpec(18)) self.peerNotificationSettingsTable = PeerNotificationSettingsTable(valueBox: self.valueBox, table: PeerNotificationSettingsTable.tableSpec(19)) @@ -585,8 +587,6 @@ public final class Postbox { self.peerChatInterfaceStateTable = PeerChatInterfaceStateTable(valueBox: self.valueBox, table: PeerChatInterfaceStateTable.tableSpec(23)) self.itemCacheMetaTable = ItemCacheMetaTable(valueBox: self.valueBox, table: ItemCacheMetaTable.tableSpec(24)) self.itemCacheTable = ItemCacheTable(valueBox: self.valueBox, table: ItemCacheTable.tableSpec(25)) - self.peerNameTokenIndexTable = ReverseIndexReferenceTable(valueBox: self.valueBox, table: ReverseIndexReferenceTable.tableSpec(26)) - self.peerNameIndexTable = PeerNameIndexTable(valueBox: self.valueBox, table: PeerNameIndexTable.tableSpec(27), peerTable: self.peerTable, peerNameTokenIndexTable: self.peerNameTokenIndexTable) self.chatListIndexTable = ChatListIndexTable(valueBox: self.valueBox, table: ChatListIndexTable.tableSpec(8), peerNameIndexTable: self.peerNameIndexTable, metadataTable: self.messageHistoryMetadataTable, readStateTable: self.readStateTable, notificationSettingsTable: self.peerNotificationSettingsTable) self.chatListTable = ChatListTable(valueBox: self.valueBox, table: ChatListTable.tableSpec(9), indexTable: self.chatListIndexTable, metadataTable: self.messageHistoryMetadataTable, seedConfiguration: self.seedConfiguration) self.peerChatTopTaggedMessageIdsTable = PeerChatTopTaggedMessageIdsTable(valueBox: self.valueBox, table: PeerChatTopTaggedMessageIdsTable.tableSpec(28))