Save caps less frequently

This commit is contained in:
Christoph Hagen 2022-05-28 21:58:51 +02:00
parent ee41e3bcd3
commit f4ab09a6f6

View File

@ -14,17 +14,24 @@ final class CapServer {
// MARK: Caps // MARK: Caps
private var saveImmediatelly = true
private var writers: Set<String> private var writers: Set<String>
/**
The time to wait for changes to be written to disk.
This delay is used to prevent file writes for each small update to the caps.
*/
private let saveDelay: TimeInterval = 1
/**
The time when a save should occur.
No save is necessary if this property is `nil`.
*/
private var nextSaveTime: Date?
private var caps = [Int: Cap]() { private var caps = [Int: Cap]() {
didSet { didSet { scheduleSave() }
guard saveImmediatelly else {
return
}
try? saveCaps()
}
} }
var nextClassifierVersion: Int { var nextClassifierVersion: Int {
@ -54,6 +61,31 @@ final class CapServer {
log("\(caps.count) caps loaded") log("\(caps.count) caps loaded")
} }
private func scheduleSave() {
nextSaveTime = Date().addingTimeInterval(saveDelay)
DispatchQueue.main.asyncAfter(deadline: .now() + saveDelay) {
self.performScheduledSave()
}
}
private func performScheduledSave() {
guard let date = nextSaveTime else {
// No save necessary, or already saved
return
}
guard date < Date() else {
// Save pushed to future
return
}
do {
try saveCaps()
nextSaveTime = nil
} catch {
// Attempt save again
scheduleSave()
}
}
private func saveCaps() throws { private func saveCaps() throws {
let data = try JSONEncoder().encode(caps.values.sorted()) let data = try JSONEncoder().encode(caps.values.sorted())
try data.write(to: dbFile) try data.write(to: dbFile)
@ -83,14 +115,11 @@ final class CapServer {
// MARK: Counts // MARK: Counts
private func updateCounts() throws { private func updateCounts() throws {
saveImmediatelly = false
caps = try caps.mapValues { caps = try caps.mapValues {
var cap = $0 var cap = $0
cap.count = try count(of: $0.id) cap.count = try count(of: $0.id)
return cap return cap
} }
saveImmediatelly = true
try? saveCaps()
} }
func countImages(in folder: URL) throws -> Int { func countImages(in folder: URL) throws -> Int {