final class UnfairLock: NSLocking {
let unfairLock: NSLocking
init() {
if #available(iOS 16.0, *) {
unfairLock = AllocatedUnfairLock()
} else {
unfairLock = OSUnfairLock()
}
}
func lock() {
unfairLock.lock()
}
func unlock() {
unfairLock.unlock()
}
@available(iOS 16.0, *)
private final class AllocatedUnfairLock: NSLocking {
private let allocUnfairLock = OSAllocatedUnfairLock()
func lock() {
allocUnfairLock.lock()
}
func unlock() {
allocUnfairLock.unlock()
}
}
private final class OSUnfairLock: NSLocking {
private let osUnfairLock: os_unfair_lock_t
init() {
osUnfairLock = .allocate(capacity: 1)
osUnfairLock.initialize(to: os_unfair_lock())
}
deinit {
osUnfairLock.deinitialize(count: 1)
osUnfairLock.deallocate()
}
func lock() {
os_unfair_lock_lock(osUnfairLock)
}
func tryLock() -> Bool {
return os_unfair_lock_trylock(osUnfairLock)
}
func unlock() {
os_unfair_lock_unlock(osUnfairLock)
}
}
}
class DoublyLinkedList<K, V>{
var key: K
var value: V
var previous: DoublyLinkedList?
var next: DoublyLinkedList?
init(_ key: K, _ value: V) {
self.key = key
self.value = value
}
}
final class LRUCache<K: Hashable, V> {
private var maxCapacity: Int
private var head: DoublyLinkedList<K, V>
private var tail: DoublyLinkedList<K, V>
private var cache: [K: DoublyLinkedList<K, V>]
private let lock = UnfairLock()
init(key: K, value: V, maxCapacity: Int) {
self.maxCapacity = maxCapacity
self.cache = [K: DoublyLinkedList<K, V>]()
self.head = DoublyLinkedList<K, V>(key, value)
self.tail = DoublyLinkedList<K, V>(key, value)
self.head.next = self.tail
self.tail.previous = self.head
NotificationCenter.default.addObserver(self, selector: #selector(receiveMemoryWarning), name: UIApplication.didReceiveMemoryWarningNotification, object: nil)
}
deinit {
removeAll()
NotificationCenter.default.removeObserver(self)
}
@objc private func receiveMemoryWarning() {
removeAll()
}
private func add(_ node: DoublyLinkedList<K, V>){
let next = head.next
head.next = node
node.previous = head
node.next = next
next?.previous = node
}
func removeAll() {
lock.lock()
defer { lock.unlock() }
for (key, node) in cache {
remove(node)
cache.removeValue(forKey: key)
}
self.head.next = nil
self.tail.previous = nil
}
func remove(_ key: K) {
lock.lock()
defer { lock.unlock() }
if let node = cache[key] {
remove(node)
cache.removeValue(forKey: key)
}
}
private func remove(_ node: DoublyLinkedList<K, V>){
let previous = node.previous
let next = node.next
previous?.next = next
next?.previous = previous
}
func get(_ key: K) -> V?{
lock.lock()
defer { lock.unlock() }
if let node = cache[key]{
remove(node)
add(node)
return node.value
}
return nil
}
func put(key: K, value: V){
lock.lock()
defer { lock.unlock() }
if let node = cache[key]{
remove(node)
cache.removeValue(forKey: key)
}else if cache.keys.count >= maxCapacity{
if let leastNode = tail.previous{
remove(leastNode)
cache.removeValue(forKey: leastNode.key)
}
}
let newNode = DoublyLinkedList(key, value)
cache[key] = newNode
add(newNode)
}
subscript(index: K) -> V? {
get {
return get(index)
}
set {
guard let newValue = newValue else {
return
}
put(key: index, value: newValue)
}
}
}
Swift 實現(xiàn)線程安全的LRU
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門咬像,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人生宛,你說我怎么就攤上這事县昂。” “怎么了陷舅?”我有些...
- 文/不壞的土叔 我叫張陵倒彰,是天一觀的道長。 經(jīng)常有香客問我莱睁,道長待讳,這世上最難降的妖魔是什么? 我笑而不...
- 正文 為了忘掉前任仰剿,我火速辦了婚禮创淡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酥馍。我一直安慰自己辩昆,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開白布旨袒。 她就那樣靜靜地躺著,像睡著了一般术辐。 火紅的嫁衣襯著肌膚如雪砚尽。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼赡勘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捞镰?” 一聲冷哼從身側(cè)響起闸与,我...
- 正文 年R本政府宣布,位于F島的核電站廷臼,受9級特大地震影響苍在,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荠商,卻給世界環(huán)境...
- 文/蒙蒙 一寂恬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧莱没,春花似錦初肉、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘹裂,卻和暖如春妄壶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寄狼。 一陣腳步聲響...
推薦閱讀更多精彩內(nèi)容
- 前言 Google Play應(yīng)用市場對于應(yīng)用的targetSdkVersion有了更為嚴(yán)格的要求。從 2018 年...
- """1.個性化消息: 將用戶的姓名存到一個變量中腋腮,并向該用戶顯示一條消息雀彼。顯示的消息應(yīng)非常簡單壤蚜,如“Hello ...