mirror of
git://jb55.com/damus
synced 2024-09-19 11:43:44 +00:00
speed optimizations: cache network_pull_date in memory and ensure writes on background queue
This commit is contained in:
parent
91113fbc6d
commit
7259641e26
@ -19,6 +19,7 @@ final class ProfileDatabase {
|
|||||||
private var persistent_container: NSPersistentContainer?
|
private var persistent_container: NSPersistentContainer?
|
||||||
private var background_context: NSManagedObjectContext?
|
private var background_context: NSManagedObjectContext?
|
||||||
private let cache_url: URL
|
private let cache_url: URL
|
||||||
|
private var network_pull_date_cache = [String: Date]()
|
||||||
|
|
||||||
init(cache_url: URL = ProfileDatabase.profile_cache_url) {
|
init(cache_url: URL = ProfileDatabase.profile_cache_url) {
|
||||||
self.cache_url = cache_url
|
self.cache_url = cache_url
|
||||||
@ -66,11 +67,28 @@ final class ProfileDatabase {
|
|||||||
background_context?.mergePolicy = NSMergePolicy(merge: .mergeByPropertyObjectTrumpMergePolicyType)
|
background_context?.mergePolicy = NSMergePolicy(merge: .mergeByPropertyObjectTrumpMergePolicyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_persisted(id: String) -> PersistedProfile? {
|
private func get_persisted(id: String, context: NSManagedObjectContext) -> PersistedProfile? {
|
||||||
let request = NSFetchRequest<PersistedProfile>(entityName: entity_name)
|
let request = NSFetchRequest<PersistedProfile>(entityName: entity_name)
|
||||||
request.predicate = NSPredicate(format: "id == %@", id)
|
request.predicate = NSPredicate(format: "id == %@", id)
|
||||||
request.fetchLimit = 1
|
request.fetchLimit = 1
|
||||||
return try? persistent_container?.viewContext.fetch(request).first
|
return try? context.fetch(request).first
|
||||||
|
}
|
||||||
|
|
||||||
|
func get_network_pull_date(id: String) -> Date? {
|
||||||
|
if let pull_date = network_pull_date_cache[id] {
|
||||||
|
return pull_date
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = NSFetchRequest<PersistedProfile>(entityName: entity_name)
|
||||||
|
request.predicate = NSPredicate(format: "id == %@", id)
|
||||||
|
request.fetchLimit = 1
|
||||||
|
request.propertiesToFetch = ["network_pull_date"]
|
||||||
|
guard let profile = try? persistent_container?.viewContext.fetch(request).first else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
network_pull_date_cache[id] = profile.network_pull_date
|
||||||
|
return profile.network_pull_date
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
@ -86,26 +104,34 @@ final class ProfileDatabase {
|
|||||||
throw ProfileDatabaseError.missing_context
|
throw ProfileDatabaseError.missing_context
|
||||||
}
|
}
|
||||||
|
|
||||||
var persisted_profile: PersistedProfile?
|
Task {
|
||||||
if let profile = get_persisted(id: id) {
|
try await context.perform {
|
||||||
if let existing_last_update = profile.last_update, last_update < existing_last_update {
|
var persisted_profile: PersistedProfile?
|
||||||
throw ProfileDatabaseError.outdated_input
|
if let profile = self.get_persisted(id: id, context: context) {
|
||||||
} else {
|
if let existing_last_update = profile.last_update, last_update < existing_last_update {
|
||||||
persisted_profile = profile
|
throw ProfileDatabaseError.outdated_input
|
||||||
|
} else {
|
||||||
|
persisted_profile = profile
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
persisted_profile = NSEntityDescription.insertNewObject(forEntityName: self.entity_name, into: context) as? PersistedProfile
|
||||||
|
persisted_profile?.id = id
|
||||||
|
}
|
||||||
|
persisted_profile?.copyValues(from: profile)
|
||||||
|
persisted_profile?.last_update = last_update
|
||||||
|
|
||||||
|
let pull_date = Date.now
|
||||||
|
persisted_profile?.network_pull_date = pull_date
|
||||||
|
self.network_pull_date_cache[id] = pull_date
|
||||||
|
|
||||||
|
try context.save()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
persisted_profile = NSEntityDescription.insertNewObject(forEntityName: entity_name, into: context) as? PersistedProfile
|
|
||||||
persisted_profile?.id = id
|
|
||||||
}
|
}
|
||||||
persisted_profile?.copyValues(from: profile)
|
|
||||||
persisted_profile?.last_update = last_update
|
|
||||||
persisted_profile?.network_pull_date = Date.now
|
|
||||||
|
|
||||||
try context.save()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(id: String) -> Profile? {
|
func get(id: String) -> Profile? {
|
||||||
guard let profile = get_persisted(id: id) else {
|
guard let container = persistent_container,
|
||||||
|
let profile = get_persisted(id: id, context: container.viewContext) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return Profile(persisted_profile: profile)
|
return Profile(persisted_profile: profile)
|
||||||
@ -122,6 +148,8 @@ final class ProfileDatabase {
|
|||||||
throw ProfileDatabaseError.missing_context
|
throw ProfileDatabaseError.missing_context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
network_pull_date_cache.removeAll()
|
||||||
|
|
||||||
let request = NSFetchRequest<NSFetchRequestResult>(entityName: entity_name)
|
let request = NSFetchRequest<NSFetchRequestResult>(entityName: entity_name)
|
||||||
let batch_delete_request = NSBatchDeleteRequest(fetchRequest: request)
|
let batch_delete_request = NSBatchDeleteRequest(fetchRequest: request)
|
||||||
batch_delete_request.resultType = .resultTypeObjectIDs
|
batch_delete_request.resultType = .resultTypeObjectIDs
|
||||||
|
@ -69,8 +69,7 @@ class Profiles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// then disk
|
// then disk
|
||||||
guard let persisted_profile = database.get_persisted(id: id),
|
guard let pull_date = database.get_network_pull_date(id: id) else {
|
||||||
let pull_date = persisted_profile.network_pull_date else {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return Date.now.timeIntervalSince(pull_date) < Profiles.db_freshness_threshold
|
return Date.now.timeIntervalSince(pull_date) < Profiles.db_freshness_threshold
|
||||||
|
Loading…
Reference in New Issue
Block a user