diff --git a/Sources/Boutique/Store.ItemRemovalStrategy.swift b/Sources/Boutique/Store.ItemRemovalStrategy.swift index 1e31ce2..ce23608 100644 --- a/Sources/Boutique/Store.ItemRemovalStrategy.swift +++ b/Sources/Boutique/Store.ItemRemovalStrategy.swift @@ -1,6 +1,6 @@ import Foundation -public extension Store { +extension Store { /// An invalidation strategy for a `Store` instance. /// /// An `ItemRemovalStrategy` provides control over how items are removed from the `Store` diff --git a/Sources/Boutique/Store.swift b/Sources/Boutique/Store.swift index ddabfc8..1b12e03 100644 --- a/Sources/Boutique/Store.swift +++ b/Sources/Boutique/Store.swift @@ -385,14 +385,14 @@ public extension Store { // Internal versions of the `insert`, `remove`, and `removeAll` function code paths so we can avoid duplicating code. internal extension Store { func performInsert(_ item: Item, firstRemovingExistingItems existingItemsStrategy: ItemRemovalStrategy? = nil) async throws { - var currentItems = await self.items - if let strategy = existingItemsStrategy { // Remove items from disk and memory based on the cache invalidation strategy - try await self.removeItems(withStrategy: strategy, items: ¤tItems) + var removedItems: [Item] = [item] + try await self.removeItems(&removedItems, withStrategy: strategy) } // Take the current items array and turn it into an OrderedDictionary. + let currentItems = await self.items let identifier = item[keyPath: self.cacheIdentifier] let currentItemsKeys = currentItems.map({ $0[keyPath: self.cacheIdentifier] }) var currentValuesDictionary = OrderedDictionary(uniqueKeys: currentItemsKeys, values: currentItems) @@ -407,11 +407,11 @@ internal extension Store { } func performInsert(_ items: [Item], firstRemovingExistingItems existingItemsStrategy: ItemRemovalStrategy? = nil) async throws { - var currentItems = await self.items if let strategy = existingItemsStrategy { // Remove items from disk and memory based on the cache invalidation strategy - try await self.removeItems(withStrategy: strategy, items: ¤tItems) + var removedItems = items + try await self.removeItems(&removedItems, withStrategy: strategy) } var insertedItemsDictionary = OrderedDictionary() @@ -424,6 +424,7 @@ internal extension Store { } // Take the current items array and turn it into an OrderedDictionary. + let currentItems = await self.items let currentItemsKeys = currentItems.map({ $0[keyPath: self.cacheIdentifier] }) var currentValuesDictionary = OrderedDictionary(uniqueKeys: currentItemsKeys, values: currentItems) @@ -502,30 +503,24 @@ private extension Store { try await self.storageEngine.remove(keys: itemKeys) } - func removeItems(withStrategy strategy: ItemRemovalStrategy, items: inout [Item]) async throws { + func removeItems(_ items: inout [Item], withStrategy strategy: ItemRemovalStrategy) async throws { let itemsToRemove = strategy.removedItems(items) // If we're using the `.removeNone` strategy then there are no items to invalidate and we can return early guard itemsToRemove.count != 0 else { return } - // If we're using the `.removeAll` strategy then we want to remove all the data without iterating - // Else, we're using a strategy and need to iterate over all of the `itemsToInvalidate` and invalidate them - if items.count == itemsToRemove.count { - items = [] - try await self.storageEngine.removeAllData() - } else { - items = items.filter { item in - !itemsToRemove.contains(where: { - $0[keyPath: cacheIdentifier] == item[keyPath: cacheIdentifier] - } - )} - let itemKeys = items.map({ CacheKey(verbatim: $0[keyPath: self.cacheIdentifier]) }) - - if itemKeys.count == 1 { - try await self.storageEngine.remove(key: itemKeys[0]) - } else { - try await self.storageEngine.remove(keys: itemKeys) + items = items.filter { item in + !itemsToRemove.contains(where: { + $0[keyPath: cacheIdentifier] == item[keyPath: cacheIdentifier] } + )} + + let itemKeys = itemsToRemove.map({ CacheKey(verbatim: $0[keyPath: self.cacheIdentifier]) }) + + if itemKeys.count == 1 { + try await self.storageEngine.remove(key: itemKeys[0]) + } else { + try await self.storageEngine.remove(keys: itemKeys) } } }