From 63c09cf7fa7b5cbdddd53e8581e75fbfa9c2341b Mon Sep 17 00:00:00 2001 From: Christian Treffs Date: Thu, 9 Jul 2020 17:10:00 +0200 Subject: [PATCH] Refine UnorderedSparseSet --- Sources/FirebladeECS/UnorderedSparseSet.swift | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/Sources/FirebladeECS/UnorderedSparseSet.swift b/Sources/FirebladeECS/UnorderedSparseSet.swift index 431c153..74b3d61 100644 --- a/Sources/FirebladeECS/UnorderedSparseSet.swift +++ b/Sources/FirebladeECS/UnorderedSparseSet.swift @@ -5,23 +5,36 @@ // Created by Christian Treffs on 30.10.17. // -public struct UnorderedSparseSet { - public typealias Index = Int - public typealias Key = Int +/// An (unordered) sparse set. +/// +/// - `Element`: the element (instance) to store. +/// - `Key`: the unique, hashable datastructure to use as a key to retrieve +/// an element from the sparse set. +/// +/// See for a reference implementation. +public struct UnorderedSparseSet { + /// An index into the dense store. + public typealias DenseIndex = Int + + /// A sparse store holding indices into the dense mapped to key. + public typealias SparseStore = [Key: DenseIndex] + + /// A dense store holding all the entries. + public typealias DenseStore = ContiguousArray public struct Entry { public let key: Key public let element: Element } - @usableFromInline var dense: ContiguousArray - @usableFromInline var sparse: [Key: Index] + @usableFromInline var dense: DenseStore + @usableFromInline var sparse: SparseStore public init() { self.init(sparse: [:], dense: []) } - init(sparse: [Index: Key], dense: ContiguousArray) { + init(sparse: SparseStore, dense: DenseStore) { self.sparse = sparse self.dense = dense } @@ -120,8 +133,18 @@ public struct UnorderedSparseSet { return (denseIndex, entry.element) } + @inlinable public var first: Element? { + dense.first?.element + } + + @inlinable public var last: Element? { + dense.last?.element + } +} + +extension UnorderedSparseSet where Key == Int { @inlinable - public subscript(position: Index) -> Element { + public subscript(position: DenseIndex) -> Element { get { get(unsafeAt: position) } @@ -130,14 +153,6 @@ public struct UnorderedSparseSet { insert(newValue, at: position) } } - - @inlinable public var first: Element? { - dense.first?.element - } - - @inlinable public var last: Element? { - dense.last?.element - } } // MARK: - Sequence @@ -148,9 +163,9 @@ extension UnorderedSparseSet: Sequence { // MARK: - UnorderedSparseSetIterator public struct ElementIterator: IteratorProtocol { - public private(set) var iterator: IndexingIterator.Entry>> + public private(set) var iterator: IndexingIterator.Entry>> - public init(_ sparseSet: UnorderedSparseSet) { + public init(_ sparseSet: UnorderedSparseSet) { iterator = sparseSet.dense.makeIterator() } @@ -163,7 +178,7 @@ extension UnorderedSparseSet: Sequence { // MARK: - Equatable extension UnorderedSparseSet.Entry: Equatable where Element: Equatable { } extension UnorderedSparseSet: Equatable where Element: Equatable { - public static func == (lhs: UnorderedSparseSet, rhs: UnorderedSparseSet) -> Bool { + public static func == (lhs: UnorderedSparseSet, rhs: UnorderedSparseSet) -> Bool { lhs.dense == rhs.dense && lhs.sparse == rhs.sparse } }