forked from shadowfacts/Tusker
Remove in-memory caches of most original image data
This commit is contained in:
parent
c12d2db258
commit
6dee0957ea
|
@ -29,7 +29,7 @@ class ImageCache {
|
||||||
private var backgroundQueue = DispatchQueue(label: "ImageCache completion queue", qos: .default)
|
private var backgroundQueue = DispatchQueue(label: "ImageCache completion queue", qos: .default)
|
||||||
|
|
||||||
init(name: String, memoryExpiry: Expiry, diskExpiry: Expiry? = nil) {
|
init(name: String, memoryExpiry: Expiry, diskExpiry: Expiry? = nil) {
|
||||||
self.cache = ImageDataCache(name: name, memoryExpiry: memoryExpiry, diskExpiry: diskExpiry)
|
self.cache = ImageDataCache(name: name, memoryExpiry: memoryExpiry, diskExpiry: diskExpiry, storeOriginalDataInMemory: diskExpiry == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(_ url: URL, completion: ((Data?, UIImage?) -> Void)?) -> Request? {
|
func get(_ url: URL, completion: ((Data?, UIImage?) -> Void)?) -> Request? {
|
||||||
|
@ -39,9 +39,9 @@ class ImageCache {
|
||||||
// in performance sensitive paths. a nice optimization to DiskStorage would be adding an internal cache
|
// in performance sensitive paths. a nice optimization to DiskStorage would be adding an internal cache
|
||||||
// of the state (unknown/exists/does not exist) of whether or not objects exist on disk so that the slow, disk I/O
|
// of the state (unknown/exists/does not exist) of whether or not objects exist on disk so that the slow, disk I/O
|
||||||
// path can be avoided most of the time
|
// path can be avoided most of the time
|
||||||
let (data, image) = try? cache.get(key) {
|
let entry = try? cache.get(key) {
|
||||||
backgroundQueue.async {
|
backgroundQueue.async {
|
||||||
completion?(data, image)
|
completion?(entry.data, entry.image)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
|
@ -67,7 +67,7 @@ class ImageCache {
|
||||||
return try? cache.getData(url.absoluteString)
|
return try? cache.getData(url.absoluteString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(_ url: URL) -> (Data, UIImage)? {
|
func get(_ url: URL) -> ImageDataCache.Entry? {
|
||||||
return try? cache.get(url.absoluteString)
|
return try? cache.get(url.absoluteString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,12 @@ import Cache
|
||||||
|
|
||||||
class ImageDataCache {
|
class ImageDataCache {
|
||||||
|
|
||||||
private let memory: MemoryStorage<(Data, UIImage)>
|
private let memory: MemoryStorage<Entry>
|
||||||
private let disk: DiskStorage<Data>?
|
private let disk: DiskStorage<Data>?
|
||||||
|
|
||||||
init(name: String, memoryExpiry: Expiry, diskExpiry: Expiry?) {
|
private let storeOriginalDataInMemory: Bool
|
||||||
|
|
||||||
|
init(name: String, memoryExpiry: Expiry, diskExpiry: Expiry?, storeOriginalDataInMemory: Bool) {
|
||||||
let memoryConfig = MemoryConfig(expiry: memoryExpiry)
|
let memoryConfig = MemoryConfig(expiry: memoryExpiry)
|
||||||
self.memory = MemoryStorage(config: memoryConfig)
|
self.memory = MemoryStorage(config: memoryConfig)
|
||||||
|
|
||||||
|
@ -24,6 +26,8 @@ class ImageDataCache {
|
||||||
} else {
|
} else {
|
||||||
self.disk = nil
|
self.disk = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.storeOriginalDataInMemory = storeOriginalDataInMemory
|
||||||
}
|
}
|
||||||
|
|
||||||
func has(_ key: String) throws -> Bool {
|
func has(_ key: String) throws -> Bool {
|
||||||
|
@ -37,29 +41,30 @@ class ImageDataCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(_ key: String) throws -> (Data, UIImage)? {
|
func get(_ key: String) throws -> Entry? {
|
||||||
if try memory.existsObject(forKey: key) {
|
if try memory.existsObject(forKey: key) {
|
||||||
return try! memory.object(forKey: key)
|
return try! memory.object(forKey: key)
|
||||||
} else if let disk = self.disk,
|
} else if let disk = self.disk,
|
||||||
try disk.existsObject(forKey: key),
|
try disk.existsObject(forKey: key),
|
||||||
let data = try? disk.object(forKey: key),
|
let data = try? disk.object(forKey: key),
|
||||||
let image = UIImage(data: data) {
|
let image = UIImage(data: data) {
|
||||||
return (data, image)
|
return Entry(data: data, image: image)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImage(_ key: String) throws -> UIImage? {
|
func getImage(_ key: String) throws -> UIImage? {
|
||||||
return try get(key)?.1
|
return try get(key)?.image
|
||||||
}
|
}
|
||||||
|
|
||||||
func getData(_ key: String) throws -> Data? {
|
func getData(_ key: String) throws -> Data? {
|
||||||
return try get(key)?.0
|
return try get(key)?.data
|
||||||
}
|
}
|
||||||
|
|
||||||
func set(_ key: String, data: Data, image: UIImage) throws {
|
func set(_ key: String, data: Data, image: UIImage) throws {
|
||||||
memory.setObject((data, image), forKey: key)
|
let entry = Entry(data: storeOriginalDataInMemory ? data : nil, image: image)
|
||||||
|
memory.setObject(entry, forKey: key)
|
||||||
|
|
||||||
if let disk = self.disk {
|
if let disk = self.disk {
|
||||||
try disk.setObject(data, forKey: key)
|
try disk.setObject(data, forKey: key)
|
||||||
|
@ -72,3 +77,10 @@ class ImageDataCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension ImageDataCache {
|
||||||
|
struct Entry {
|
||||||
|
let data: Data?
|
||||||
|
let image: UIImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -85,8 +85,8 @@ class LoadingLargeImageViewController: UIViewController, LargeImageAnimatableVie
|
||||||
overrideUserInterfaceStyle = .dark
|
overrideUserInterfaceStyle = .dark
|
||||||
view.backgroundColor = .black
|
view.backgroundColor = .black
|
||||||
|
|
||||||
if let (data, image) = cache.get(url) {
|
if let entry = cache.get(url) {
|
||||||
createLargeImage(data: data, image: image, url: url)
|
createLargeImage(data: entry.data, image: entry.image, url: url)
|
||||||
} else {
|
} else {
|
||||||
createPreview()
|
createPreview()
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ class LoadingLargeImageViewController: UIViewController, LargeImageAnimatableVie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createLargeImage(data: Data, image: UIImage, url: URL) {
|
private func createLargeImage(data: Data?, image: UIImage, url: URL) {
|
||||||
guard !loaded else { return }
|
guard !loaded else { return }
|
||||||
loaded = true
|
loaded = true
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue