Skip to content

Instantly share code, notes, and snippets.

@eneko
Last active October 7, 2022 11:54
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eneko/c8b92a6005ad8e669ced69509575e361 to your computer and use it in GitHub Desktop.
Save eneko/c8b92a6005ad8e669ced69509575e361 to your computer and use it in GitHub Desktop.
Thread-safe, ordered-dictionary-backed, actor-based LRU cache
//
// LRUCacheActor.swift
// LRUCacheActor
//
// Created by Eneko Alonso on 9/5/21.
//
import Foundation
import OrderedCollections
/// A simple actor-based LRU cache, backed by an OrderedDictionary, implemented
/// for illustration purposes to compare performance between actors and serial
/// dispatch queues.
/// - Read performance is O(n), far from the ideal O(1).
/// - Write performance is O(1) (amortized)
@available(iOS 15, macOS 12, *)
public actor LRUCacheActor<Key: Hashable, Value> {
var store: OrderedDictionary<Key, Value> = [:]
var capacity: Int
public init(capacity: Int) async {
self.capacity = max(capacity, 1)
}
/// Read an item from the cache
/// - complexity: O(n) due to removal of item from current position
public func item(for key: Key) -> Value? {
guard let value = store.removeValue(forKey: key) else {
return nil
}
store[key] = value
return value
}
/// Add a new item to the cache
/// - complexity: O(1) (assuming the cache does not contain more items than it's capacity)
public func set(item: Value?, for key: Key) {
while store.count >= capacity {
store.removeFirst()
}
store[key] = item
}
/// Number of elements in the cache
/// - complexity: O(1)
public var count: Int { store.count }
/// Test if the cache contains any elements
/// - complexity: O(1)
public var isEmpty: Bool { store.isEmpty }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment