Swiftgram/submodules/Postbox/Sources/PeerMergedOperationLogIndexTable.swift
2021-09-13 20:40:09 +04:00

65 lines
2.7 KiB
Swift

import Foundation
final class PeerMergedOperationLogIndexTable: Table {
static func tableSpec(_ id: Int32) -> ValueBoxTable {
return ValueBoxTable(id: id, keyType: .binary, compactValuesOnCreation: true)
}
private let metadataTable: PeerOperationLogMetadataTable
init(valueBox: ValueBox, table: ValueBoxTable, useCaches: Bool, metadataTable: PeerOperationLogMetadataTable) {
self.metadataTable = metadataTable
super.init(valueBox: valueBox, table: table, useCaches: useCaches)
}
private func key(tag: PeerOperationLogTag, index: Int32) -> ValueBoxKey {
let key = ValueBoxKey(length: 5)
key.setUInt8(0, value: tag.rawValue)
key.setInt32(1, value: index)
return key
}
func add(peerId: PeerId, tag: PeerOperationLogTag, tagLocalIndex: Int32) -> Int32 {
let index = self.metadataTable.takeNextMergedIndex()
let buffer = WriteBuffer()
var peerIdValue: Int64 = peerId.toInt64()
var tagLocalIndexValue: Int32 = tagLocalIndex
buffer.write(&peerIdValue, offset: 0, length: 8)
buffer.write(&tagLocalIndexValue, offset: 0, length: 4)
self.valueBox.set(self.table, key: self.key(tag: tag, index: index), value: buffer)
return index
}
func remove(tag: PeerOperationLogTag, mergedIndices: [Int32]) {
for index in mergedIndices {
assert(self.valueBox.exists(self.table, key: self.key(tag: tag, index: index)))
self.valueBox.remove(self.table, key: self.key(tag: tag, index: index), secure: false)
}
}
func getTagLocalIndices(tag: PeerOperationLogTag, fromMergedIndex: Int32, limit: Int) -> [(PeerId, Int32, Int32)] {
var result: [(PeerId, Int32, Int32)] = []
self.valueBox.range(self.table, start: self.key(tag: tag, index: fromMergedIndex == 0 ? 0 : fromMergedIndex - 1), end: self.key(tag: tag, index: Int32.max), values: { key, value in
assert(key.getUInt8(0) == tag.rawValue)
var peerIdValue: Int64 = 0
var tagLocalIndexValue: Int32 = 0
value.read(&peerIdValue, offset: 0, length: 8)
value.read(&tagLocalIndexValue, offset: 0, length: 4)
result.append((PeerId(peerIdValue), tagLocalIndexValue, key.getInt32(1)))
return true
}, limit: limit)
return result
}
func tailIndex(tag: PeerOperationLogTag) -> Int32? {
var result: Int32?
self.valueBox.range(self.table, start: self.key(tag: tag, index: Int32.max), end: self.key(tag: tag, index: 0), keys: {
key in
result = key.getInt32(1)
return false
}, limit: 1)
return result
}
}