mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
Fix message index ordering
This commit is contained in:
@@ -242,11 +242,13 @@ private final class ChatListViewSpaceState {
|
|||||||
let allIndices = (lowerOrAtAnchorMessages + higherThanAnchorMessages).map { $0.entryIndex }
|
let allIndices = (lowerOrAtAnchorMessages + higherThanAnchorMessages).map { $0.entryIndex }
|
||||||
let allEntityIds = (lowerOrAtAnchorMessages + higherThanAnchorMessages).map { $0.entityId }
|
let allEntityIds = (lowerOrAtAnchorMessages + higherThanAnchorMessages).map { $0.entityId }
|
||||||
if Set(allIndices).count != allIndices.count {
|
if Set(allIndices).count != allIndices.count {
|
||||||
|
var debugRepeatedIndices = Set<MutableChatListEntryIndex>()
|
||||||
var existingIndices = Set<MutableChatListEntryIndex>()
|
var existingIndices = Set<MutableChatListEntryIndex>()
|
||||||
for i in (0 ..< lowerOrAtAnchorMessages.count).reversed() {
|
for i in (0 ..< lowerOrAtAnchorMessages.count).reversed() {
|
||||||
if !existingIndices.contains(lowerOrAtAnchorMessages[i].entryIndex) {
|
if !existingIndices.contains(lowerOrAtAnchorMessages[i].entryIndex) {
|
||||||
existingIndices.insert(lowerOrAtAnchorMessages[i].entryIndex)
|
existingIndices.insert(lowerOrAtAnchorMessages[i].entryIndex)
|
||||||
} else {
|
} else {
|
||||||
|
debugRepeatedIndices.insert(lowerOrAtAnchorMessages[i].entryIndex)
|
||||||
lowerOrAtAnchorMessages.remove(at: i)
|
lowerOrAtAnchorMessages.remove(at: i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,10 +256,11 @@ private final class ChatListViewSpaceState {
|
|||||||
if !existingIndices.contains(higherThanAnchorMessages[i].entryIndex) {
|
if !existingIndices.contains(higherThanAnchorMessages[i].entryIndex) {
|
||||||
existingIndices.insert(higherThanAnchorMessages[i].entryIndex)
|
existingIndices.insert(higherThanAnchorMessages[i].entryIndex)
|
||||||
} else {
|
} else {
|
||||||
|
debugRepeatedIndices.insert(higherThanAnchorMessages[i].entryIndex)
|
||||||
higherThanAnchorMessages.remove(at: i)
|
higherThanAnchorMessages.remove(at: i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
postboxLog("allIndices not unique: \(allIndices)")
|
postboxLog("allIndices not unique, repeated: \(debugRepeatedIndices)")
|
||||||
|
|
||||||
assert(false)
|
assert(false)
|
||||||
//preconditionFailure()
|
//preconditionFailure()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public struct MessageId: Hashable, Comparable, CustomStringConvertible, PostboxC
|
|||||||
|
|
||||||
public var description: String {
|
public var description: String {
|
||||||
get {
|
get {
|
||||||
return "\(namespace)_\(id)"
|
return "\(peerId):\(namespace)_\(id)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,6 +18,9 @@ public struct MessageId: Hashable, Comparable, CustomStringConvertible, PostboxC
|
|||||||
self.peerId = peerId
|
self.peerId = peerId
|
||||||
self.namespace = namespace
|
self.namespace = namespace
|
||||||
self.id = id
|
self.id = id
|
||||||
|
if namespace == 0 && id == 0 {
|
||||||
|
assert(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(_ buffer: ReadBuffer) {
|
public init(_ buffer: ReadBuffer) {
|
||||||
@@ -103,8 +106,11 @@ public struct MessageIndex: Comparable, Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func predecessor() -> MessageIndex {
|
public func predecessor() -> MessageIndex {
|
||||||
if self.id.id != 0 {
|
let previousPeerId = self.id.peerId.predecessor
|
||||||
return MessageIndex(id: MessageId(peerId: self.id.peerId, namespace: self.id.namespace, id: self.id.id - 1), timestamp: self.timestamp)
|
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 {
|
} 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)
|
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 {
|
} else if self.timestamp != 0 {
|
||||||
@@ -115,8 +121,13 @@ public struct MessageIndex: Comparable, Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func successor() -> MessageIndex {
|
public func successor() -> MessageIndex {
|
||||||
|
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)
|
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 {
|
public static func absoluteUpperBound() -> MessageIndex {
|
||||||
return MessageIndex(id: MessageId(peerId: PeerId.max, namespace: Int32(Int8.max), id: Int32.max), timestamp: Int32.max)
|
return MessageIndex(id: MessageId(peerId: PeerId.max, namespace: Int32(Int8.max), id: Int32.max), timestamp: Int32.max)
|
||||||
|
|||||||
@@ -8,6 +8,22 @@ public struct PeerId: Hashable, CustomStringConvertible, Comparable, Codable {
|
|||||||
|
|
||||||
fileprivate var rawValue: UInt32
|
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) {
|
fileprivate init(rawValue: UInt32) {
|
||||||
precondition((rawValue | 0x7) == 0x7)
|
precondition((rawValue | 0x7) == 0x7)
|
||||||
|
|
||||||
@@ -28,12 +44,32 @@ public struct PeerId: Hashable, CustomStringConvertible, Comparable, Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct Id: Comparable, Hashable, Codable {
|
public struct Id: Comparable, Hashable, Codable {
|
||||||
|
public static var min: Id {
|
||||||
|
return Id(rawValue: 0)
|
||||||
|
}
|
||||||
|
|
||||||
public static var max: Id {
|
public static var max: Id {
|
||||||
return Id(rawValue: 0x000000007fffffff)
|
return Id(rawValue: 0x000000007fffffff)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate var rawValue: UInt64
|
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) {
|
fileprivate init(rawValue: UInt64) {
|
||||||
precondition((rawValue | 0x000FFFFFFFFFFFFF) == 0x000FFFFFFFFFFFFF)
|
precondition((rawValue | 0x000FFFFFFFFFFFFF) == 0x000FFFFFFFFFFFFF)
|
||||||
|
|
||||||
@@ -60,6 +96,34 @@ public struct PeerId: Hashable, CustomStringConvertible, Comparable, Codable {
|
|||||||
public let namespace: Namespace
|
public let namespace: Namespace
|
||||||
public let id: Id
|
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) {
|
public init(namespace: Namespace, id: Id) {
|
||||||
self.namespace = namespace
|
self.namespace = namespace
|
||||||
self.id = id
|
self.id = id
|
||||||
|
|||||||
Reference in New Issue
Block a user