Skip to content

Commit

Permalink
feat(identity): Add removeAll API to clean storage (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
pjechris authored May 10, 2023
1 parent 9524b43 commit 11ccd8c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 18 deletions.
40 changes: 28 additions & 12 deletions Sources/CohesionKit/Identity/IdentityStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 121,6 @@ public class IdentityMap {
}
}

/// Remove an alias from the storage
public func removeAlias<T>(named: AliasKey<T>) {
refAliases.remove(for: named)
logger?.didUnregisterAlias(named)
}

/// Remove an alias from the storage
public func removeAlias<C: Collection>(named: AliasKey<C>) {
refAliases.remove(for: named)
logger?.didUnregisterAlias(named)
}

func nodeStore<T: Identifiable>(entity: T, modifiedAt: Stamp) -> EntityNode<T> {
let node = storage[entity, new: EntityNode(entity, modifiedAt: nil)]

Expand Down Expand Up @@ -321,3 309,31 @@ extension IdentityMap {
}
}
}

// MARK: Delete

extension IdentityMap {
/// Removes an alias from the storage
public func removeAlias<T>(named: AliasKey<T>) {
refAliases.remove(for: named)
logger?.didUnregisterAlias(named)
}

/// Removes an alias from the storage
public func removeAlias<C: Collection>(named: AliasKey<C>) {
refAliases.remove(for: named)
logger?.didUnregisterAlias(named)
}

/// Removes all alias from identity map
public func removeAllAlias() {
refAliases.removeAll()
}

/// Removes all alias AND all objects stored weakly. You should not need this method and rather use `removeAlias`. But this can be useful
/// if you fear retain cycles
public func removeAll() {
refAliases.removeAll()
storage.removeAll()
}
}
14 changes: 9 additions & 5 deletions Sources/CohesionKit/Storage/WeakStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 2,18 @@ import Foundation

struct WeakStorage {
typealias Storage = [String: AnyWeak]

private var storage: Storage = [:]


mutating func removeAll() {
storage.removeAll()
}

subscript<T: AnyObject>(_ type: T.Type, id id: Any) -> T? {
get { (storage[key(for: type, id: id)] as? Weak<T>)?.value }
set { storage[key(for: type, id: id)] = Weak(value: newValue) }
}

private func key<T>(for type: T.Type, id: Any) -> String {
"\(type)-\(id)"
}
Expand All @@ -30,9 34,9 @@ extension WeakStorage {
}

let value = create()

self[object] = value

return value
}
}
Expand Down
17 changes: 16 additions & 1 deletion Tests/CohesionKitTests/IdentityMapTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 106,22 @@ class IdentityMapTests: XCTestCase {
XCTAssertEqual(identityMap.find(named: .test).value, entity)
}

func test_findNamed_allAliasRemoved_returnNilValue() {
let identityMap = IdentityMap(queue: .main)

_ = identityMap.store(entity: SingleNodeFixture(id: 1), named: .test, modifiedAt: 0)

XCTAssertNotNil(identityMap.find(named: .test).value)

identityMap.removeAllAlias()

XCTAssertNil(identityMap.find(named: .test).value)
}
}

// PRAGMA: Update

extension IdentityMapTests {
func test_findNamed_entityStored_thenRemoved_returnNil() {
let identityMap = IdentityMap()
let entity = SingleNodeFixture(id: 1)
Expand Down Expand Up @@ -178,7 194,6 @@ class IdentityMapTests: XCTestCase {
wait(for: [expectation], timeout: 0.5)
}
}

}

private extension AliasKey where T == SingleNodeFixture {
Expand Down

0 comments on commit 11ccd8c

Please sign in to comment.