Skip to content

Commit

Permalink
Create RefdsDictionary.swift
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelesantos committed Oct 28, 2024
1 parent 6336120 commit 187d6a9
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions Sources/RefdsShared/Foundation/RefdsDictionary.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Foundation

public actor RefdsDictionary<
Key: Hashable & Sendable,
Value,
Transform: Comparable
> {
private var elements: [Key: Value] = [:]
private let keyPath: KeyPath<Value, Transform>

public init(
for type: Value.Type,
by keyPath: KeyPath<Value, Transform>
) {
self.keyPath = keyPath
}

public subscript(key: Key) -> Value? {
get { elements[key] }
set {
guard let newValue else { return remove(for: key) }
if elements[key] == nil { insert(for: key) }
elements[key] = newValue
}
}

public var keys: [Key] = []
public var values: [Value] {
keys.compactMap { elements[$0] }
}

private func insert(for key: Key) {
let index = keys.firstIndex(where: { k in
guard let lhs = elements[k].map({ $0[keyPath: keyPath] }),
let rhs = elements[key].map({ $0[keyPath: keyPath] }) else { return false }
return lhs >= rhs
}) ?? keys.count
keys.insert(key, at: index)
}

private func remove(for key: Key) {
elements.removeValue(forKey: key)
keys.removeAll { $0 == key }
}
}

0 comments on commit 187d6a9

Please sign in to comment.