mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-18 19:40:19 +00:00
141 lines
6.0 KiB
Swift
141 lines
6.0 KiB
Swift
import Foundation
|
|
|
|
enum ItemCollectionOperation {
|
|
case insertItem(ItemCollectionId, ItemCollectionItem)
|
|
case removeItem(ItemCollectionId, ItemCollectionItemIndex.Id)
|
|
}
|
|
|
|
final class ItemCollectionItemTable: Table {
|
|
static func tableSpec(_ id: Int32) -> ValueBoxTable {
|
|
return ValueBoxTable(id: id, keyType: .binary)
|
|
}
|
|
|
|
private let sharedKey = ValueBoxKey(length: 4 + 8 + 4 + 8)
|
|
|
|
private func key(collectionId: ItemCollectionId, index: ItemCollectionItemIndex) -> ValueBoxKey {
|
|
self.sharedKey.setInt32(0, value: collectionId.namespace)
|
|
self.sharedKey.setInt64(4, value: collectionId.id)
|
|
self.sharedKey.setInt32(4 + 8, value: index.index)
|
|
self.sharedKey.setInt64(4 + 8 + 4, value: index.id)
|
|
return self.sharedKey
|
|
}
|
|
|
|
private func lowerBound(namespace: ItemCollectionId.Namespace) -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4)
|
|
key.setInt32(0, value: namespace)
|
|
return key
|
|
}
|
|
|
|
private func upperBound(namespace: ItemCollectionId.Namespace) -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4)
|
|
key.setInt32(0, value: namespace)
|
|
return key.successor
|
|
}
|
|
|
|
private func lowerBound(collectionId: ItemCollectionId) -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4 + 8)
|
|
key.setInt32(0, value: collectionId.namespace)
|
|
key.setInt64(4, value: collectionId.id)
|
|
return key
|
|
}
|
|
|
|
private func upperBound(collectionId: ItemCollectionId) -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4 + 8)
|
|
key.setInt32(0, value: collectionId.namespace)
|
|
key.setInt64(4, value: collectionId.id)
|
|
return key.successor
|
|
}
|
|
|
|
func lowerItems(collectionId: ItemCollectionId, itemIndex: ItemCollectionItemIndex, count: Int) -> [ItemCollectionItem] {
|
|
var items: [ItemCollectionItem] = []
|
|
self.valueBox.range(self.table, start: self.key(collectionId: collectionId, index: itemIndex), end: self.lowerBound(collectionId: collectionId), values: { _, value in
|
|
if let item = Decoder(buffer: value).decodeRootObject() as? ItemCollectionItem {
|
|
items.append(item)
|
|
}
|
|
return true
|
|
}, limit: count)
|
|
return items
|
|
}
|
|
|
|
func higherItems(collectionId: ItemCollectionId, itemIndex: ItemCollectionItemIndex, count: Int) -> [ItemCollectionItem] {
|
|
var items: [ItemCollectionItem] = []
|
|
self.valueBox.range(self.table, start: self.key(collectionId: collectionId, index: itemIndex), end: self.upperBound(collectionId: collectionId), values: { _, value in
|
|
if let item = Decoder(buffer: value).decodeRootObject() as? ItemCollectionItem {
|
|
items.append(item)
|
|
}
|
|
return true
|
|
}, limit: count)
|
|
return items
|
|
}
|
|
|
|
func getSummaryIndices(namespace: ItemCollectionId.Namespace) -> [ItemCollectionId: [ItemCollectionItemIndex]] {
|
|
var summaryIndices: [ItemCollectionId: [ItemCollectionItemIndex]] = [:]
|
|
self.valueBox.range(self.table, start: self.lowerBound(namespace: namespace), end: self.upperBound(namespace: namespace), keys: { key in
|
|
let collectionId = ItemCollectionId(namespace: namespace, id: key.getInt64(4))
|
|
let itemIndex = ItemCollectionItemIndex(index: key.getInt32(4 + 8), id: key.getInt64(4 + 8 + 4))
|
|
if summaryIndices[collectionId] != nil {
|
|
summaryIndices[collectionId]!.append(itemIndex)
|
|
} else {
|
|
summaryIndices[collectionId] = [itemIndex]
|
|
}
|
|
return true
|
|
}, limit: 0)
|
|
return summaryIndices
|
|
}
|
|
|
|
func getItems(namespace: ItemCollectionId.Namespace) -> [ItemCollectionId: [ItemCollectionItem]] {
|
|
var items: [ItemCollectionId: [ItemCollectionItem]] = [:]
|
|
self.valueBox.range(self.table, start: self.lowerBound(namespace: namespace), end: self.upperBound(namespace: namespace), values: { key, value in
|
|
let collectionId = ItemCollectionId(namespace: namespace, id: key.getInt64(4))
|
|
//let itemIndex = ItemCollectionItemIndex(index: key.getInt32(4 + 8), id: key.getInt64(4 + 8 + 4))
|
|
if let item = Decoder(buffer: value).decodeRootObject() as? ItemCollectionItem {
|
|
if items[collectionId] != nil {
|
|
items[collectionId]!.append(item)
|
|
} else {
|
|
items[collectionId] = [item]
|
|
}
|
|
}
|
|
return true
|
|
}, limit: 0)
|
|
return items
|
|
}
|
|
|
|
func replaceItems(collectionId: ItemCollectionId, items: [ItemCollectionItem]) {
|
|
var currentIndices = Set<ItemCollectionItemIndex>()
|
|
self.valueBox.range(self.table, start: self.lowerBound(collectionId: collectionId), end: self.upperBound(collectionId: collectionId), keys: { key in
|
|
let itemIndex = ItemCollectionItemIndex(index: key.getInt32(4 + 8), id: key.getInt64(4 + 8 + 4))
|
|
currentIndices.insert(itemIndex)
|
|
return true
|
|
}, limit: 0)
|
|
|
|
var updatedIndices = Set(items.map({ $0.index }))
|
|
var itemByIndex: [ItemCollectionItemIndex: ItemCollectionItem] = [:]
|
|
for item in items {
|
|
itemByIndex[item.index] = item
|
|
}
|
|
|
|
let addedIndices = updatedIndices.subtracting(currentIndices)
|
|
let removedIndices = currentIndices.subtracting(updatedIndices)
|
|
|
|
for index in removedIndices {
|
|
self.valueBox.remove(self.table, key: self.key(collectionId: collectionId, index: index))
|
|
}
|
|
|
|
let sharedEncoder = Encoder()
|
|
for index in addedIndices {
|
|
let item = itemByIndex[index]!
|
|
sharedEncoder.reset()
|
|
sharedEncoder.encodeRootObject(item)
|
|
self.valueBox.set(self.table, key: self.key(collectionId: collectionId, index: index), value: sharedEncoder.readBufferNoCopy())
|
|
}
|
|
}
|
|
|
|
override func clearMemoryCache() {
|
|
|
|
}
|
|
|
|
override func beforeCommit() {
|
|
|
|
}
|
|
}
|