import Foundation public final class ItemCollectionInfoEntry { public let id: ItemCollectionId public let info: ItemCollectionInfo public let count: Int32 public let firstItem: ItemCollectionItem? init(id: ItemCollectionId, info: ItemCollectionInfo, count: Int32, firstItem: ItemCollectionItem?) { self.id = id self.info = info self.count = count self.firstItem = firstItem } } final class MutableItemCollectionInfosView: MutablePostboxView { let namespaces: [ItemCollectionId.Namespace] var entriesByNamespace: [ItemCollectionId.Namespace: [ItemCollectionInfoEntry]] init(postbox: PostboxImpl, namespaces: [ItemCollectionId.Namespace]) { self.namespaces = namespaces var entriesByNamespace: [ItemCollectionId.Namespace: [ItemCollectionInfoEntry]] = [:] for namespace in namespaces { let infos = postbox.itemCollectionInfoTable.getInfos(namespace: namespace) var entries: [ItemCollectionInfoEntry] = [] for (_, id, info) in infos { let firstItem = postbox.itemCollectionItemTable.higherItems(collectionId: id, itemIndex: ItemCollectionItemIndex.lowerBound, count: 1).first entries.append(ItemCollectionInfoEntry(id: id, info: info, count: postbox.itemCollectionItemTable.itemCount(collectionId: id), firstItem: firstItem)) } entriesByNamespace[namespace] = entries } self.entriesByNamespace = entriesByNamespace } func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool { if transaction.currentItemCollectionInfosOperations.isEmpty && transaction.currentItemCollectionItemsOperations.isEmpty { return false } var updated = false var reloadInfosNamespaces = Set() var reloadTopItemCollectionIds = Set() for operation in transaction.currentItemCollectionInfosOperations { switch operation { case let .replaceInfos(namespace): reloadInfosNamespaces.insert(namespace) } } for (id, operations) in transaction.currentItemCollectionItemsOperations { for operation in operations { switch operation { case .replaceItems: reloadTopItemCollectionIds.insert(id) } } } if !reloadInfosNamespaces.isEmpty { updated = true var entriesByNamespace: [ItemCollectionId.Namespace: [ItemCollectionInfoEntry]] = [:] for namespace in self.namespaces { let infos = postbox.itemCollectionInfoTable.getInfos(namespace: namespace) var entries: [ItemCollectionInfoEntry] = [] for (_, id, info) in infos { let firstItem = postbox.itemCollectionItemTable.higherItems(collectionId: id, itemIndex: ItemCollectionItemIndex.lowerBound, count: 1).first entries.append(ItemCollectionInfoEntry(id: id, info: info, count: postbox.itemCollectionItemTable.itemCount(collectionId: id), firstItem: firstItem)) } entriesByNamespace[namespace] = entries } self.entriesByNamespace = entriesByNamespace } else if !reloadTopItemCollectionIds.isEmpty { var entriesByNamespace = self.entriesByNamespace for (namespace, entries) in self.entriesByNamespace { var items: [ItemCollectionInfoEntry] = [] for i in 0 ..< entries.count { if reloadTopItemCollectionIds.contains(entries[i].id) { updated = true let firstItem = postbox.itemCollectionItemTable.higherItems(collectionId: entries[i].id, itemIndex: ItemCollectionItemIndex.lowerBound, count: 1).first items.append(ItemCollectionInfoEntry(id: entries[i].id, info: entries[i].info, count: postbox.itemCollectionItemTable.itemCount(collectionId: entries[i].id), firstItem: firstItem)) } else { items.append(entriesByNamespace[namespace]![i]) } } entriesByNamespace[namespace] = items } self.entriesByNamespace = entriesByNamespace } return updated } func immutableView() -> PostboxView { return ItemCollectionInfosView(self) } } public final class ItemCollectionInfosView: PostboxView { public let entriesByNamespace: [ItemCollectionId.Namespace: [ItemCollectionInfoEntry]] init(_ view: MutableItemCollectionInfosView) { self.entriesByNamespace = view.entriesByNamespace } }