Created
May 17, 2017 13:27
-
-
Save BenziAhamed/6b3e03c2462bf6b82f34174c4fac179d to your computer and use it in GitHub Desktop.
In-process, single thread safe memcache in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
public struct Memcache { | |
enum Expiration { | |
case never | |
case at(Double) | |
var expired: Bool { | |
switch self { | |
case .never: return false | |
case .at(let ttl): return Date.timeIntervalSinceReferenceDate > ttl | |
} | |
} | |
} | |
struct Entry { | |
let item: Any | |
let expiry: Expiration | |
var expired: Bool { return expiry.expired } | |
} | |
typealias Cache = [String: Entry] | |
var namespaceCache = [String: Cache]() | |
var cache = Cache() | |
public mutating func put(key: String, value: Any, namespace: String? = nil, ttl: Double = -1) { | |
// key - the cache entry key | |
// value - the item to be cached | |
// namespace - optional namespace associated with the key | |
// ttl - duration in seconds for entry to be valid, -1 means cache will never expire | |
let entry = Entry( | |
item: value, | |
expiry: ttl < 0 ? .never : .at(Date.timeIntervalSinceReferenceDate + ttl) | |
) | |
if let ns = namespace { | |
if namespaceCache[ns] == nil { | |
namespaceCache[ns] = [:] | |
} | |
namespaceCache[ns]![key] = entry | |
} | |
else { | |
cache[key] = entry | |
} | |
} | |
public func get(key: String, namespace: String? = nil) -> Any? { | |
guard let entry = getEntry(key, namespace), !entry.expired else { return nil } | |
return entry.item | |
} | |
private func getEntry(_ key: String, _ namespace: String?) -> Entry? { | |
if let ns = namespace { | |
return namespaceCache[ns]?[key] | |
} | |
return cache[key] | |
} | |
mutating public func clear(namespace: String? = nil) { | |
// if invoked with a namespace | |
// we will clear out all caches entries associated | |
// with that namespace | |
// else we clear out everything | |
if let ns = namespace { | |
namespaceCache[ns] = nil | |
} | |
else { | |
cache.removeAll() | |
namespaceCache.removeAll() | |
} | |
} | |
} |
Author
BenziAhamed
commented
May 17, 2017
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment