Optimize sparse set

This commit is contained in:
Christian Treffs 2020-07-30 22:17:53 +02:00
parent 81f61cafbb
commit d08353fd53
No known key found for this signature in database
GPG Key ID: 49A4B4B460BE3ED4
2 changed files with 12 additions and 12 deletions

View File

@ -12,7 +12,7 @@
/// an element from the sparse set. /// an element from the sparse set.
/// ///
/// See <https://github.com/bombela/sparseset/blob/master/src/lib.rs> for a reference implementation. /// See <https://github.com/bombela/sparseset/blob/master/src/lib.rs> for a reference implementation.
public struct UnorderedSparseSet<Element, Key: Hashable & Codable> { public final class UnorderedSparseSet<Element, Key: Hashable & Codable> {
/// An index into the dense store. /// An index into the dense store.
public typealias DenseIndex = Int public typealias DenseIndex = Int
@ -30,7 +30,7 @@ public struct UnorderedSparseSet<Element, Key: Hashable & Codable> {
@usableFromInline var dense: DenseStore @usableFromInline var dense: DenseStore
@usableFromInline var sparse: SparseStore @usableFromInline var sparse: SparseStore
public init() { public convenience init() {
self.init(sparse: [:], dense: []) self.init(sparse: [:], dense: [])
} }
@ -55,7 +55,7 @@ public struct UnorderedSparseSet<Element, Key: Hashable & Codable> {
/// - key: the key /// - key: the key
/// - Returns: true if new, false if replaced. /// - Returns: true if new, false if replaced.
@discardableResult @discardableResult
public mutating func insert(_ element: Element, at key: Key) -> Bool { public func insert(_ element: Element, at key: Key) -> Bool {
if let denseIndex = findIndex(at: key) { if let denseIndex = findIndex(at: key) {
dense[denseIndex] = Entry(key: key, element: element) dense[denseIndex] = Entry(key: key, element: element)
return false return false
@ -63,7 +63,7 @@ public struct UnorderedSparseSet<Element, Key: Hashable & Codable> {
let nIndex = dense.count let nIndex = dense.count
dense.append(Entry(key: key, element: element)) dense.append(Entry(key: key, element: element))
sparse[key] = nIndex sparse.updateValue(nIndex, forKey: key)
return true return true
} }
@ -86,7 +86,7 @@ public struct UnorderedSparseSet<Element, Key: Hashable & Codable> {
/// - Parameter key: the key /// - Parameter key: the key
/// - Returns: removed value or nil if key not found. /// - Returns: removed value or nil if key not found.
@discardableResult @discardableResult
public mutating func remove(at key: Key) -> Entry? { public func remove(at key: Key) -> Entry? {
guard let denseIndex = findIndex(at: key) else { guard let denseIndex = findIndex(at: key) else {
return nil return nil
} }
@ -101,7 +101,7 @@ public struct UnorderedSparseSet<Element, Key: Hashable & Codable> {
} }
@inlinable @inlinable
public mutating func removeAll(keepingCapacity: Bool = false) { public func removeAll(keepingCapacity: Bool = false) {
sparse.removeAll(keepingCapacity: keepingCapacity) sparse.removeAll(keepingCapacity: keepingCapacity)
dense.removeAll(keepingCapacity: keepingCapacity) dense.removeAll(keepingCapacity: keepingCapacity)
} }
@ -111,7 +111,7 @@ public struct UnorderedSparseSet<Element, Key: Hashable & Codable> {
/// ///
/// - Parameter denseIndex: the dense index /// - Parameter denseIndex: the dense index
/// - Returns: the element entry /// - Returns: the element entry
private mutating func swapRemove(at denseIndex: Int) -> Entry { private func swapRemove(at denseIndex: Int) -> Entry {
dense.swapAt(denseIndex, dense.count - 1) dense.swapAt(denseIndex, dense.count - 1)
return dense.removeLast() return dense.removeLast()
} }

View File

@ -387,7 +387,7 @@ class SparseSetTests: XCTestCase {
func testSparseSetDoubleRemove() { func testSparseSetDoubleRemove() {
class AClass { } class AClass { }
var set = UnorderedSparseSet<AClass, Int>() let set = UnorderedSparseSet<AClass, Int>()
let a = AClass() let a = AClass()
let b = AClass() let b = AClass()
set.insert(a, at: 0) set.insert(a, at: 0)
@ -471,7 +471,7 @@ class SparseSetTests: XCTestCase {
} }
func testSparseSetReduce() { func testSparseSetReduce() {
var characters = UnorderedSparseSet<Character, Int>() let characters = UnorderedSparseSet<Character, Int>()
characters.insert("H", at: 4) characters.insert("H", at: 4)
characters.insert("e", at: 13) characters.insert("e", at: 13)
@ -497,7 +497,7 @@ class SparseSetTests: XCTestCase {
} }
func testSubscript() { func testSubscript() {
var characters = UnorderedSparseSet<Character, Int>() let characters = UnorderedSparseSet<Character, Int>()
characters[4] = "H" characters[4] = "H"
characters[13] = "e" characters[13] = "e"
@ -528,7 +528,7 @@ class SparseSetTests: XCTestCase {
} }
func testStartEndIndex() { func testStartEndIndex() {
var set = UnorderedSparseSet<Character, Int>() let set = UnorderedSparseSet<Character, Int>()
set.insert("C", at: 33) set.insert("C", at: 33)
set.insert("A", at: 11) set.insert("A", at: 11)
@ -541,7 +541,7 @@ class SparseSetTests: XCTestCase {
func testAlternativeKey() { func testAlternativeKey() {
var set = UnorderedSparseSet<Character, String>() let set = UnorderedSparseSet<Character, String>()
set.insert("A", at: "a") set.insert("A", at: "a")
set.insert("C", at: "c") set.insert("C", at: "c")