From b5d132717d2658997db7881cea2e48aa348dbe70 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 26 May 2024 12:13:01 -0700 Subject: [PATCH] Use a Set rather than an O(n) thing to unique DatabaseObjects. --- .../Related Objects/DatabaseLookupTable.swift | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/Database/Sources/Database/Related Objects/DatabaseLookupTable.swift b/Database/Sources/Database/Related Objects/DatabaseLookupTable.swift index 28fd49c7c..2501ea92d 100644 --- a/Database/Sources/Database/Related Objects/DatabaseLookupTable.swift +++ b/Database/Sources/Database/Related Objects/DatabaseLookupTable.swift @@ -126,7 +126,7 @@ private extension DatabaseLookupTable { // Save the actual related objects. - let relatedObjectsToSave = uniqueArrayOfRelatedObjects(with: objects) + let relatedObjectsToSave = uniqueRelatedObjects(with: objects) if relatedObjectsToSave.isEmpty { assertionFailure("updateRelationships: expected relatedObjectsToSave would not be empty. This should be unreachable.") return @@ -135,24 +135,12 @@ private extension DatabaseLookupTable { relatedTable.save(relatedObjectsToSave, in: database) } - func uniqueArrayOfRelatedObjects(with objects: [DatabaseObject]) -> [DatabaseObject] { - - // Can’t create a Set, because we can’t make a Set, because protocol-conforming objects can’t be made Hashable or even Equatable. - // We still want the array to include only one copy of each object, but we have to do it the slow way. Instruments will tell us if this is a performance problem. + func uniqueRelatedObjects(with objects: [DatabaseObject]) -> [DatabaseObject] { - var relatedObjectsUniqueArray = [DatabaseObject]() - for object in objects { - guard let relatedObjects = object.relatedObjectsWithName(relationshipName) else { - assertionFailure("uniqueArrayOfRelatedObjects: expected every object to have related objects.") - continue - } - for relatedObject in relatedObjects { - if !relatedObjectsUniqueArray.includesObjectWithDatabaseID(relatedObject.databaseID) { - relatedObjectsUniqueArray += [relatedObject] - } - } - } - return relatedObjectsUniqueArray + // All of our objects that conform to DatabaseObject are Hashable. + // If that’s ever not true, this will crash when run from Xcode. + let objectSet = Set(objects as! [AnyHashable]) + return Array(objectSet) as! [DatabaseObject] } func syncRelatedObjectsAndLookupTable(_ object: DatabaseObject, _ lookupTable: RelatedObjectIDsMap, _ database: FMDatabase) {