From e30e4dd22ff5d8742de5f86f8cc259c19fcfcc53 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Fri, 26 Mar 2021 23:01:16 +0400 Subject: [PATCH] Fix message index ordering --- .../Postbox/Sources/ChatListViewState.swift | 5 +- submodules/Postbox/Sources/Message.swift | 19 ++++-- submodules/Postbox/Sources/Peer.swift | 64 +++++++++++++++++++ 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/submodules/Postbox/Sources/ChatListViewState.swift b/submodules/Postbox/Sources/ChatListViewState.swift index ef08231ff7..7e8d365f44 100644 --- a/submodules/Postbox/Sources/ChatListViewState.swift +++ b/submodules/Postbox/Sources/ChatListViewState.swift @@ -242,11 +242,13 @@ private final class ChatListViewSpaceState { let allIndices = (lowerOrAtAnchorMessages + higherThanAnchorMessages).map { $0.entryIndex } let allEntityIds = (lowerOrAtAnchorMessages + higherThanAnchorMessages).map { $0.entityId } if Set(allIndices).count != allIndices.count { + var debugRepeatedIndices = Set() var existingIndices = Set() for i in (0 ..< lowerOrAtAnchorMessages.count).reversed() { if !existingIndices.contains(lowerOrAtAnchorMessages[i].entryIndex) { existingIndices.insert(lowerOrAtAnchorMessages[i].entryIndex) } else { + debugRepeatedIndices.insert(lowerOrAtAnchorMessages[i].entryIndex) lowerOrAtAnchorMessages.remove(at: i) } } @@ -254,10 +256,11 @@ private final class ChatListViewSpaceState { if !existingIndices.contains(higherThanAnchorMessages[i].entryIndex) { existingIndices.insert(higherThanAnchorMessages[i].entryIndex) } else { + debugRepeatedIndices.insert(higherThanAnchorMessages[i].entryIndex) higherThanAnchorMessages.remove(at: i) } } - postboxLog("allIndices not unique: \(allIndices)") + postboxLog("allIndices not unique, repeated: \(debugRepeatedIndices)") assert(false) //preconditionFailure() diff --git a/submodules/Postbox/Sources/Message.swift b/submodules/Postbox/Sources/Message.swift index d3bac69065..76c0d2348a 100644 --- a/submodules/Postbox/Sources/Message.swift +++ b/submodules/Postbox/Sources/Message.swift @@ -10,7 +10,7 @@ public struct MessageId: Hashable, Comparable, CustomStringConvertible, PostboxC public var description: String { get { - return "\(namespace)_\(id)" + return "\(peerId):\(namespace)_\(id)" } } @@ -18,6 +18,9 @@ public struct MessageId: Hashable, Comparable, CustomStringConvertible, PostboxC self.peerId = peerId self.namespace = namespace self.id = id + if namespace == 0 && id == 0 { + assert(true) + } } public init(_ buffer: ReadBuffer) { @@ -103,8 +106,11 @@ public struct MessageIndex: Comparable, Hashable { } public func predecessor() -> MessageIndex { - if self.id.id != 0 { - return MessageIndex(id: MessageId(peerId: self.id.peerId, namespace: self.id.namespace, id: self.id.id - 1), timestamp: self.timestamp) + let previousPeerId = self.id.peerId.predecessor + if previousPeerId != self.id.peerId { + return MessageIndex(id: MessageId(peerId: previousPeerId, namespace: self.id.namespace, id: self.id.id), timestamp: self.timestamp) + } else if self.id.id != 0 { + return MessageIndex(id: MessageId(peerId: self.id.peerId, namespace: self.id.namespace, id: self.id.id), timestamp: self.timestamp) } else if self.id.namespace != 0 { return MessageIndex(id: MessageId(peerId: self.id.peerId, namespace: self.id.namespace - 1, id: Int32.max - 1), timestamp: self.timestamp) } else if self.timestamp != 0 { @@ -115,7 +121,12 @@ public struct MessageIndex: Comparable, Hashable { } public func successor() -> MessageIndex { - return MessageIndex(id: MessageId(peerId: self.id.peerId, namespace: self.id.namespace, id: self.id.id == Int32.max ? self.id.id : (self.id.id + 1)), timestamp: self.timestamp) + let nextPeerId = self.id.peerId.successor + if nextPeerId != self.id.peerId { + return MessageIndex(id: MessageId(peerId: nextPeerId, namespace: self.id.namespace, id: self.id.id), timestamp: self.timestamp) + } else { + return MessageIndex(id: MessageId(peerId: self.id.peerId, namespace: self.id.namespace, id: self.id.id == Int32.max ? self.id.id : (self.id.id + 1)), timestamp: self.timestamp) + } } public static func absoluteUpperBound() -> MessageIndex { diff --git a/submodules/Postbox/Sources/Peer.swift b/submodules/Postbox/Sources/Peer.swift index 67053e3b42..70a1862e51 100644 --- a/submodules/Postbox/Sources/Peer.swift +++ b/submodules/Postbox/Sources/Peer.swift @@ -8,6 +8,22 @@ public struct PeerId: Hashable, CustomStringConvertible, Comparable, Codable { fileprivate var rawValue: UInt32 + var predecessor: Namespace { + if self.rawValue != 0 { + return Namespace(rawValue: self.rawValue - 1) + } else { + return self + } + } + + var successor: Namespace { + if self.rawValue != Namespace.max.rawValue { + return Namespace(rawValue: self.rawValue + 1) + } else { + return self + } + } + fileprivate init(rawValue: UInt32) { precondition((rawValue | 0x7) == 0x7) @@ -28,12 +44,32 @@ public struct PeerId: Hashable, CustomStringConvertible, Comparable, Codable { } public struct Id: Comparable, Hashable, Codable { + public static var min: Id { + return Id(rawValue: 0) + } + public static var max: Id { return Id(rawValue: 0x000000007fffffff) } fileprivate var rawValue: UInt64 + var predecessor: Id { + if self.rawValue != 0 { + return Id(rawValue: self.rawValue - 1) + } else { + return self + } + } + + var successor: Id { + if self.rawValue != Id.max.rawValue { + return Id(rawValue: self.rawValue + 1) + } else { + return self + } + } + fileprivate init(rawValue: UInt64) { precondition((rawValue | 0x000FFFFFFFFFFFFF) == 0x000FFFFFFFFFFFFF) @@ -59,6 +95,34 @@ public struct PeerId: Hashable, CustomStringConvertible, Comparable, Codable { public let namespace: Namespace public let id: Id + + var predecessor: PeerId { + let previousId = self.id.predecessor + if previousId != self.id { + return PeerId(namespace: self.namespace, id: previousId) + } else { + let previousNamespace = self.namespace.predecessor + if previousNamespace != self.namespace { + return PeerId(namespace: previousNamespace, id: .max) + } else { + return self + } + } + } + + var successor: PeerId { + let nextId = self.id.successor + if nextId != self.id { + return PeerId(namespace: self.namespace, id: nextId) + } else { + let nextNamespace = self.namespace.successor + if nextNamespace != self.namespace { + return PeerId(namespace: nextNamespace, id: .min) + } else { + return self + } + } + } public init(namespace: Namespace, id: Id) { self.namespace = namespace