mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
104 lines
3.3 KiB
Swift
104 lines
3.3 KiB
Swift
import Foundation
|
|
|
|
final class PeerTimeoutPropertiesTable: Table {
|
|
private struct Key: Hashable {
|
|
var peerId: PeerId
|
|
var timestamp: UInt32
|
|
}
|
|
|
|
static func tableSpec(_ id: Int32) -> ValueBoxTable {
|
|
return ValueBoxTable(id: id, keyType: .binary, compactValuesOnCreation: false)
|
|
}
|
|
|
|
private let sharedKey = ValueBoxKey(length: 4 + 8)
|
|
|
|
private var cache: [Key: Bool] = [:]
|
|
private var updated = Set<Key>()
|
|
|
|
var hasUpdates: Bool {
|
|
return !self.updated.isEmpty
|
|
}
|
|
|
|
private func key(_ key: Key) -> ValueBoxKey {
|
|
self.sharedKey.setInt32(0, value: Int32(bitPattern: key.timestamp))
|
|
self.sharedKey.setInt64(4, value: key.peerId.toInt64())
|
|
return self.sharedKey
|
|
}
|
|
|
|
private func lowerBound() -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4 + 8)
|
|
key.setInt32(0, value: 0)
|
|
key.setInt64(4, value: 0)
|
|
return key
|
|
}
|
|
|
|
private func upperBound() -> ValueBoxKey {
|
|
let key = ValueBoxKey(length: 4 + 8)
|
|
key.setInt32(0, value: Int32(bitPattern: UInt32.max))
|
|
key.setInt64(4, value: Int64(bitPattern: UInt64.max))
|
|
return key
|
|
}
|
|
|
|
func min() -> (peerId: PeerId, timestamp: UInt32)? {
|
|
var result: Key?
|
|
self.valueBox.range(self.table, start: self.lowerBound(), end: self.upperBound(), keys: { key in
|
|
result = Key(peerId: PeerId(key.getInt64(4)), timestamp: UInt32(bitPattern: key.getInt32(0)))
|
|
return false
|
|
}, limit: 1)
|
|
return result.flatMap { result -> (peerId: PeerId, timestamp: UInt32) in
|
|
return (result.peerId, result.timestamp)
|
|
}
|
|
}
|
|
|
|
private func get(peerId: PeerId, timestamp: UInt32) -> Bool {
|
|
let key = Key(peerId: peerId, timestamp: timestamp)
|
|
if let cachedValue = self.cache[key] {
|
|
return cachedValue
|
|
} else {
|
|
let value = self.valueBox.exists(self.table, key: self.key(Key(peerId: peerId, timestamp: timestamp)))
|
|
self.cache[key] = value
|
|
return value
|
|
}
|
|
}
|
|
|
|
func remove(peerId: PeerId, timestamp: UInt32) {
|
|
let key = Key(peerId: peerId, timestamp: timestamp)
|
|
if self.get(peerId: peerId, timestamp: timestamp) {
|
|
self.cache[key] = false
|
|
self.updated.insert(key)
|
|
}
|
|
}
|
|
|
|
func add(peerId: PeerId, timestamp: UInt32) {
|
|
let key = Key(peerId: peerId, timestamp: timestamp)
|
|
if !self.get(peerId: peerId, timestamp: timestamp) {
|
|
self.cache[key] = true
|
|
self.updated.insert(key)
|
|
}
|
|
}
|
|
|
|
override func clearMemoryCache() {
|
|
self.cache.removeAll()
|
|
}
|
|
|
|
override func beforeCommit() {
|
|
if !self.updated.isEmpty {
|
|
for key in self.updated {
|
|
if let value = self.cache[key] {
|
|
if value {
|
|
self.valueBox.set(self.table, key: self.key(key), value: MemoryBuffer())
|
|
} else {
|
|
self.valueBox.remove(self.table, key: self.key(key), secure: false)
|
|
}
|
|
}
|
|
}
|
|
|
|
self.updated.removeAll()
|
|
|
|
if !self.useCaches {
|
|
self.cache.removeAll()
|
|
}
|
|
}
|
|
}
|
|
}
|