mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-18 11:30:04 +00:00
157 lines
6.3 KiB
Swift
157 lines
6.3 KiB
Swift
import Foundation
|
|
|
|
enum ChatListOperation {
|
|
case InsertMessage(IntermediateMessage)
|
|
case InsertNothing(MessageIndex)
|
|
case Remove([MessageIndex])
|
|
}
|
|
|
|
enum ChatListIntermediateEntry {
|
|
case Message(IntermediateMessage)
|
|
case Nothing(MessageIndex)
|
|
}
|
|
|
|
final class ChatListTable {
|
|
let valueBox: ValueBox
|
|
let tableId: Int32
|
|
let indexTable: ChatListIndexTable
|
|
|
|
init(valueBox: ValueBox, tableId: Int32, indexTable: ChatListIndexTable) {
|
|
self.valueBox = valueBox
|
|
self.tableId = tableId
|
|
self.indexTable = indexTable
|
|
}
|
|
|
|
private func key(index: MessageIndex) -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4 + 4 + 4 + 8)
|
|
key.setInt32(0, value: index.timestamp)
|
|
key.setInt32(4, value: index.id.namespace)
|
|
key.setInt32(4 + 4, value: index.id.id)
|
|
key.setInt64(4 + 4 + 4, value: index.id.peerId.toInt64())
|
|
return key
|
|
}
|
|
|
|
private func lowerBound() -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4)
|
|
key.setInt32(0, value: 0)
|
|
return key
|
|
}
|
|
|
|
private func upperBound() -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4)
|
|
key.setInt32(0, value: Int32.max)
|
|
return key
|
|
}
|
|
|
|
func replay(historyOperationsByPeerId: [PeerId : [MessageHistoryOperation]], messageHistoryTable: MessageHistoryTable, inout operations: [ChatListOperation]) {
|
|
for (peerId, _) in historyOperationsByPeerId {
|
|
let currentIndex: MessageIndex? = self.indexTable.get(peerId)
|
|
if let topMessage = messageHistoryTable.topMessage(peerId) {
|
|
let index = MessageIndex(id: topMessage.id, timestamp: topMessage.timestamp)
|
|
|
|
if let currentIndex = currentIndex where currentIndex != index {
|
|
self.justRemove(currentIndex)
|
|
}
|
|
if let currentIndex = currentIndex {
|
|
operations.append(.Remove([currentIndex]))
|
|
}
|
|
self.indexTable.set(index)
|
|
self.justInsert(index)
|
|
operations.append(.InsertMessage(topMessage))
|
|
} else {
|
|
if let currentIndex = currentIndex {
|
|
operations.append(.Remove([currentIndex]))
|
|
operations.append(.InsertNothing(currentIndex))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func justInsert(index: MessageIndex) {
|
|
self.valueBox.set(self.tableId, key: self.key(index), value: MemoryBuffer(memory: nil, capacity: 0, length: 0, freeWhenDone: false))
|
|
}
|
|
|
|
func justRemove(index: MessageIndex) {
|
|
self.valueBox.remove(self.tableId, key: self.key(index))
|
|
}
|
|
|
|
func entriesAround(index: MessageIndex, messageHistoryTable: MessageHistoryTable, count: Int) -> [ChatListIntermediateEntry] {
|
|
var lowerEntries: [ChatListIntermediateEntry] = []
|
|
|
|
self.valueBox.range(self.tableId, start: self.key(index).successor, end: self.lowerBound(), keys: { key in
|
|
let index = MessageIndex(id: MessageId(peerId: PeerId(key.getInt64(4 + 4 + 4)), namespace: key.getInt32(4), id: key.getInt32(4 + 4)), timestamp: key.getInt32(0))
|
|
if let message = messageHistoryTable.getMessage(index) {
|
|
lowerEntries.append(.Message(message))
|
|
} else {
|
|
lowerEntries.append(.Nothing(index))
|
|
}
|
|
return true
|
|
}, limit: count)
|
|
|
|
var upperEntries: [ChatListIntermediateEntry] = []
|
|
self.valueBox.range(self.tableId, start: self.key(index), end: self.upperBound(), keys: { key in
|
|
let index = MessageIndex(id: MessageId(peerId: PeerId(key.getInt64(4 + 4 + 4)), namespace: key.getInt32(4), id: key.getInt32(4 + 4)), timestamp: key.getInt32(0))
|
|
if let message = messageHistoryTable.getMessage(index) {
|
|
upperEntries.append(.Message(message))
|
|
} else {
|
|
upperEntries.append(.Nothing(index))
|
|
}
|
|
return true
|
|
}, limit: count)
|
|
|
|
var entries: [ChatListIntermediateEntry] = []
|
|
for entry in lowerEntries.reverse() {
|
|
entries.append(entry)
|
|
}
|
|
entries.appendContentsOf(upperEntries)
|
|
|
|
return entries
|
|
}
|
|
|
|
func earlierEntries(index: MessageIndex?, messageHistoryTable: MessageHistoryTable, count: Int) -> [ChatListIntermediateEntry] {
|
|
var entries: [ChatListIntermediateEntry] = []
|
|
let key: ValueBoxKey
|
|
if let index = index {
|
|
key = self.key(index)
|
|
} else {
|
|
key = self.upperBound()
|
|
}
|
|
|
|
self.valueBox.range(self.tableId, start: key, end: self.lowerBound(), keys: { key in
|
|
let index = MessageIndex(id: MessageId(peerId: PeerId(key.getInt64(4 + 4 + 4)), namespace: key.getInt32(4), id: key.getInt32(4 + 4)), timestamp: key.getInt32(0))
|
|
if let message = messageHistoryTable.getMessage(index) {
|
|
entries.append(.Message(message))
|
|
} else {
|
|
entries.append(.Nothing(index))
|
|
}
|
|
return true
|
|
}, limit: count)
|
|
return entries
|
|
}
|
|
|
|
func laterEntries(index: MessageIndex?, messageHistoryTable: MessageHistoryTable, count: Int) -> [ChatListIntermediateEntry] {
|
|
var entries: [ChatListIntermediateEntry] = []
|
|
let key: ValueBoxKey
|
|
if let index = index {
|
|
key = self.key(index)
|
|
} else {
|
|
key = self.lowerBound()
|
|
}
|
|
|
|
self.valueBox.range(self.tableId, start: key, end: self.upperBound(), keys: { key in
|
|
let index = MessageIndex(id: MessageId(peerId: PeerId(key.getInt64(4 + 4 + 4)), namespace: key.getInt32(4), id: key.getInt32(4 + 4)), timestamp: key.getInt32(0))
|
|
if let message = messageHistoryTable.getMessage(index) {
|
|
entries.append(.Message(message))
|
|
} else {
|
|
entries.append(.Nothing(index))
|
|
}
|
|
return true
|
|
}, limit: count)
|
|
return entries
|
|
}
|
|
|
|
func debugList(messageHistoryTable: MessageHistoryTable) -> [ChatListIntermediateEntry] {
|
|
return self.entriesAround(MessageIndex(id: MessageId(peerId: PeerId(0), namespace: 0, id: 0), timestamp: 0), messageHistoryTable: messageHistoryTable, count: 1000)
|
|
}
|
|
}
|