session-ios/SignalMessaging/utils/LRUCache.swift
2018-04-03 16:28:33 -04:00

65 lines
1.6 KiB
Swift

//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
@objc
public class AnyLRUCache: NSObject {
let backingCache: LRUCache<NSObject, NSObject>
public init(maxSize: Int) {
backingCache = LRUCache(maxSize: maxSize)
}
public func get(key: NSObject) -> NSObject? {
return self.backingCache.get(key: key)
}
public func set(key: NSObject, value: NSObject) {
self.backingCache.set(key: key, value: value)
}
}
// A simple LRU cache bounded by the number of entries.
//
// TODO: We might want to observe memory pressure notifications.
public class LRUCache<KeyType: Hashable & Equatable, ValueType> {
private var cacheMap: [KeyType: ValueType] = [:]
private var cacheOrder: [KeyType] = []
private let maxSize: Int
public init(maxSize: Int) {
self.maxSize = maxSize
}
public func get(key: KeyType) -> ValueType? {
guard let value = cacheMap[key] else {
return nil
}
// Update cache order.
cacheOrder = cacheOrder.filter { $0 != key }
cacheOrder.append(key)
return value
}
public func set(key: KeyType, value: ValueType) {
cacheMap[key] = value
// Update cache order.
cacheOrder = cacheOrder.filter { $0 != key }
cacheOrder.append(key)
while cacheOrder.count > maxSize {
guard let staleKey = cacheOrder.first else {
owsFail("Cache ordering unexpectedly empty")
return
}
cacheOrder.removeFirst()
cacheMap.removeValue(forKey: staleKey)
}
}
}