Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incubate persistent data structures #31

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
176 commits
Select commit Hold shift + click to select a range
488322e
[Capsule] Import sources
msteindorfer Apr 29, 2021
449e570
[Capsule] Add package configuration
msteindorfer Apr 29, 2021
13bd00b
[Capsule] Adhere to `CollectionsTestSupport` in test code
msteindorfer Apr 29, 2021
03913fd
[Capsule] Increase visibility of `count` and `subscript` to `public`
msteindorfer Apr 29, 2021
097e6b7
[Capsule] Update copyright headers
msteindorfer Apr 29, 2021
3cb6fb3
[Capsule] Split `HashMap` extensions into separate files
msteindorfer Apr 29, 2021
8805172
[Capsule] Rename `Common.swift` -> `_Common.swift`
msteindorfer Apr 29, 2021
1598e22
[Capsule] Split nested structs and classes into separate files
msteindorfer Apr 29, 2021
b3e1e9d
[Capsule] Harmonize identation
msteindorfer Apr 29, 2021
ce5a6bd
[Capsule] Update copyright headers
msteindorfer Apr 29, 2021
29dd2c8
[Capsule] Remove unused `XCTest` import
msteindorfer Apr 29, 2021
b518d56
[Capsule] Implement `Hashable` extension for `HashMap`
msteindorfer Apr 30, 2021
77ef612
[Capsule] Rename and simplify smoke tests
msteindorfer Apr 30, 2021
e09c8db
[Capsule] Implement preliminary hash-collision resolution
msteindorfer May 4, 2021
d4ecaa0
[Capsule] Make spine of trie monomorphic
msteindorfer May 4, 2021
8e2ec3c
[Capsule] Make `copyAndSetNode` generic
msteindorfer May 4, 2021
b34c8da
[Capsule] Implement `Equatable` protocol
msteindorfer May 4, 2021
212fa0e
[Capsule] Update copyright headers
msteindorfer May 4, 2021
b175001
[Capsule] Add support for Copy-On-Write
msteindorfer May 5, 2021
72950a9
[Capsule] Fix Copy-On-Write semantics for nested nodes
msteindorfer May 6, 2021
7d0cc05
[Capsule] Add test functions for feature exploration
msteindorfer May 6, 2021
2be8545
[Capsule] Use overflowing bit-wise operations
msteindorfer May 7, 2021
ec017cb
[Capsule] Use larger chunk size for more shallow tries
msteindorfer May 7, 2021
2c0b7d7
[Capsule] Generalize bitmap usage with `typealias`
msteindorfer May 7, 2021
21c0c0e
[Capsule] Prepare introduction of `collMap`
msteindorfer May 7, 2021
2ac27e6
[Capsule] Rework hash-collision logic based on monomorphic trie nodes
msteindorfer May 7, 2021
e6365db
[Capsule] Adopt Swift naming convention for chaining methods
msteindorfer May 7, 2021
5950335
[Capsule] Make test case deterministic
msteindorfer May 7, 2021
8d50cb4
[Capsule] Improve `==` for `CollidableInt` and fix white-space issues
msteindorfer May 7, 2021
4c7149f
[Capsule] Experiment with any nodes API
msteindorfer May 9, 2021
3803970
[Capsule] Fix compaction upon delete with `SizePredicate`
msteindorfer May 9, 2021
b489a6e
[Capsule] Add special case iterator test
msteindorfer May 9, 2021
da5b426
[Capsule] Made iterators aware of node enum type
msteindorfer May 10, 2021
e246bd5
[Capsule] Remove redundant `MapNode` protocol overrides
msteindorfer May 10, 2021
31a7f07
[Capsule] Rename hash collision node API in `Node` protocol
msteindorfer May 10, 2021
e0ff977
[Capsule] Rename bitmap indexed node API in `Node` protocol
msteindorfer May 10, 2021
b87d610
[Capsule] Rename generic node API in `Node` protocol
msteindorfer May 10, 2021
25f6de0
[Capsule] Clean-up associated types
msteindorfer May 10, 2021
2d45f7a
[Capsule] Rename `AnyNode` to `TrieNode`
msteindorfer May 10, 2021
e9fe942
[Capsule] Clean-up method names
msteindorfer May 10, 2021
b4c7f1d
[Capsule] Name payload tuple components
msteindorfer May 10, 2021
68948e1
[Capsule] Add precondition violation error message
msteindorfer May 10, 2021
11f7a8a
[Capsule] Remove outdated comment
msteindorfer May 10, 2021
0eae829
[Capsule] Clean-up `TrieNode` enum
msteindorfer May 10, 2021
43731f7
[Capsule] Update copyright headers
msteindorfer May 10, 2021
193753e
[Capsule] Add convenience initializer for `BitmapIndexedMapNode`
msteindorfer May 12, 2021
f168e7f
[Capsule] Introduce convenience constructors for `BitmapIndexedMapNode`
msteindorfer May 12, 2021
612252e
[Capsule] Rework merge functions
msteindorfer May 12, 2021
2e2297a
[Capsule] Avoid wrapping `if` conditions in parentheses
msteindorfer May 12, 2021
7a4005e
[Capsule] Put colons next to identifiers
msteindorfer May 12, 2021
5968608
[Capsule] Remove trailing whitespace
msteindorfer May 12, 2021
247b813
[Capsule] Resolve various code style issues
msteindorfer May 12, 2021
1550743
[Capsule] Rephrase return statement
msteindorfer May 12, 2021
385058a
[Capsule] Use `guard` statements for bitmap case distinctions
msteindorfer May 12, 2021
4a8a84f
[Capsule] Use `guard`s to check effects
msteindorfer May 12, 2021
c87ca84
[Capsule] Make dual nature of update/remove methods explicit
msteindorfer May 12, 2021
fcea661
[Capsule] Fix test case
msteindorfer May 12, 2021
50bfc64
[Capsule] Add test for hash-collision compaction
msteindorfer May 12, 2021
d2611a6
[Capsule] Fix hash-collision compaction scenario
msteindorfer May 12, 2021
2dbf067
[Capsule] Explode condition
msteindorfer May 12, 2021
0350c95
[Capsule] Fix code style issues in test case
msteindorfer May 12, 2021
e80fdb7
[Capsule] Add helpers for hash-collision compaction
msteindorfer May 15, 2021
e34d915
[Capsule] Extend `BitmapIndexedMapNode` with `Sequence` protocol
msteindorfer Jun 4, 2021
e28f675
[Capsule] Copy `DictionaryBenchmark` and add some `Dictionary` API
msteindorfer Jun 4, 2021
f53ca43
[Capsule] Use mutable API inside initializer
msteindorfer Jun 5, 2021
1181a85
[Capsule] Deduplicate `ExpressibleByDictionaryLiteral` implementation
msteindorfer Jun 5, 2021
5e50ccd
[Capsule] Turn some preconditions into asserts
msteindorfer Jun 5, 2021
8014cc6
[Capsule] Add inline annotations to initializer
msteindorfer Jun 5, 2021
3a8ee52
[Capsule] Add `init(uniqueKeys keys: Keys, values: Values)`
msteindorfer Jun 7, 2021
042d2eb
[Capsule] Add tuple labels to iterator return values
msteindorfer Jun 7, 2021
d9877e2
[Capsule] Add `underestimatedCount`
msteindorfer Jun 7, 2021
f719b1c
[Capsule] Copy base of `OrderedDictionary` tests
msteindorfer Jun 7, 2021
bce54c6
[Capsule] Fix tests for unordered collections
msteindorfer Jun 7, 2021
186bc95
[Capsule] Add `CustomStringConvertible` conformance
msteindorfer Jun 7, 2021
4a76bd9
[Capsule] Extract class `CollidableInt` from smoke tests
msteindorfer Jun 7, 2021
77f6043
[Capsule] Add `CustomDebugStringConvertible` conformance to `Collidab…
msteindorfer Jun 7, 2021
ea6257f
[Capsule] Enable `test_CustomStringConvertible`
msteindorfer Jun 7, 2021
0d91ef8
[Capsule] Enable more initializer tests
msteindorfer Jun 7, 2021
3110518
[Capsule] Extend copy-on-write optimizations
msteindorfer Jun 8, 2021
0940b27
[Capsule] Add benchmark helper script
msteindorfer Jun 9, 2021
7f44f54
[Capsule] Move allocation out of `isTrieNodeKnownUniquelyReferenced`
msteindorfer Jun 9, 2021
130e4a5
[Capsule] Experiment unifying node getter with uniqueness check
msteindorfer Jun 9, 2021
b2fe267
Revert "[Capsule] Experiment unifying node getter with uniqueness check"
msteindorfer Jun 9, 2021
1820910
[Capsule] Trim down bitmap size
msteindorfer Jun 10, 2021
fbb72e0
[Capsule] Use `count` as guidance for duplication checks
msteindorfer Jun 10, 2021
e688e36
[Capsule] Specialize initializers
msteindorfer Jun 10, 2021
c38d56d
[Capsule] Extract calls to `isKnownUniquelyReferenced`
msteindorfer Jun 10, 2021
35ccb9d
[Capsule] Add `typealias` for backend storage type
msteindorfer Jun 10, 2021
37a16d9
[Capsule] Benchmark with `-Ounchecked` to ignore bounce checks hit, e…
msteindorfer Jun 12, 2021
e32d9aa
[Capsule] Check content invariant
msteindorfer Jun 12, 2021
83716ef
[Capsule] Fix indentation
msteindorfer Jun 12, 2021
e3cda76
[Capsule] Reduce to one content slot per key/value tuple
msteindorfer Jun 12, 2021
b6b88b9
[Capsule] Simplify `isKnownUniquelyReferenced` logic
msteindorfer Jun 12, 2021
176c26f
[Capsule] Use `rounded(.up)` from standard library over `Foundation.c…
msteindorfer Jun 21, 2021
cf34478
[Capsule] Avoid `copyAndSetBitmapIndexedNode` on equal references whe…
msteindorfer Jun 23, 2021
3e559bb
[Capsule] Hack minimal example for constructing a trie
msteindorfer Jun 14, 2021
cedc74b
[Capsule] Hack minimal (continued)
msteindorfer Jun 14, 2021
83e40fc
[Capsule] Finalize `ManagedBuffer` rework
msteindorfer Jun 17, 2021
b065b31
[Capsule] Add header helpers for imploding/exploding
msteindorfer Jun 17, 2021
81a9c0e
[Capsule] Introduce `withUnsafeMutablePointerRanges`
msteindorfer Jun 17, 2021
d49ec64
[Capsule] Simplify bitmap processing
msteindorfer Jun 17, 2021
db398e8
[Capsule] Convert `Header` from tuple to struct
msteindorfer Jun 17, 2021
e66a39c
[Capsule] Use `withUnsafeMutablePointerRanges` over alternative APIs
msteindorfer Jun 17, 2021
11f137a
[Capsule] Relocate range copy and edit functions
msteindorfer Jun 21, 2021
22a7c6a
[Capsule] Avoid returning closure pointer
msteindorfer Jun 21, 2021
e4d45eb
[Capsule] Make range functions generic
msteindorfer Jun 21, 2021
9331a01
[Capsule] Use `fixedTrieCapacity` and rebind to `AnyObject`
msteindorfer Jun 22, 2021
84a4715
[Capsule] Name correctly usages of `trieRange`
msteindorfer Jun 22, 2021
2b0574c
[Capsule] Fix invariant references
msteindorfer Jun 22, 2021
2d9baf6
Revert "[Capsule] Use `fixedTrieCapacity` and rebind to `AnyObject`"
msteindorfer Jun 23, 2021
fdb2231
Revert "Revert "[Capsule] Use `fixedTrieCapacity` and rebind to `AnyO…
msteindorfer Jun 23, 2021
3a3e078
[Capsule] Bind `trieRange` with unsafe
msteindorfer Jun 23, 2021
fe7f34e
[Capsule] Make `fixedTrieCapacity` adjustable to bitmap format
msteindorfer Jun 23, 2021
d3816c2
[Capsule] Rework buffer to use `UnsafeMutableRawPointer`
msteindorfer Jun 28, 2021
4805a86
[Capsule] Replace `buffer` with `baseAddress` references
msteindorfer Jun 28, 2021
d7bda3b
[Capsule] Unclutter segment counts
msteindorfer Jun 28, 2021
b2808c4
[Capsule] Clean-up comments and unused constants
msteindorfer Jun 28, 2021
cf53106
[Capsule] Use provided `hasher` argument
msteindorfer Dec 1, 2021
d295c30
[Capsule] Remove unused key set hash code
msteindorfer Dec 1, 2021
2856197
[Capsule] Make alignment calculation robust
msteindorfer Dec 1, 2021
7bb9cba
[Capsule] Ensure object layout of `Node` is class reference
msteindorfer Dec 1, 2021
49c4788
[Capsule] Convert to unsigned bitmap type
msteindorfer Dec 1, 2021
5604bee
[Capsule] Make `ReturnPayload` binding explicit
msteindorfer Dec 1, 2021
f809ec1
[Capsule] Remove alternatives that have undefined behavior
msteindorfer Dec 1, 2021
40e0f80
[Capsule] Make `get` internal in favor of subscript
msteindorfer Dec 1, 2021
108289e
[Capsule] Fix heap buffer overflow issue during deletion
msteindorfer Dec 1, 2021
1ffd819
[Capsule] Draft benchmark configuration
msteindorfer Dec 1, 2021
94505e6
[Capsule] Make `ReturnPayload` binding explicit in hash collision node
msteindorfer Dec 6, 2021
624b245
[Capsule] Rework `MapKeyValueTupleIterator`
msteindorfer Dec 9, 2021
0f0c0bd
[Capsule] Pin type to Capsule hash-map
msteindorfer Dec 9, 2021
5fad00e
[Capsule] Remove `reserveCapacity` test since it is not supported
msteindorfer Dec 9, 2021
f956009
[Capsule] Add `[COW] subscript, insert` benchmark
msteindorfer Dec 9, 2021
fc60fae
[Capsule] Rename `HashMap` to `PersistentDictionary`
msteindorfer Dec 9, 2021
60f0b6d
[Capsule] Remove outdated Capsule benchmark helper
msteindorfer Dec 9, 2021
92d07b3
[Capsule] Add `[COW] subscript, remove existing` benchmark
msteindorfer Dec 9, 2021
ce70ede
[Capsule] Constrain capacity type
msteindorfer May 9, 2022
9305456
[Capsule] Add preliminary support for shrinking
msteindorfer Jun 11, 2022
fadd054
[Capsule] Add placeholders for missing `Dictionary` protocols
msteindorfer Jun 23, 2022
d9e2294
[Capsule] Provide skeletons for `keys` and `values` views
msteindorfer Aug 9, 2022
c7905a5
[Capsule] Add basic implementation of `PersistentDictionary.Index` type
msteindorfer Aug 9, 2022
0c192fd
[Capsule] Add bitmap to sequence converters
msteindorfer Aug 12, 2022
8563a91
[Capsule] Exemplify enumeration of compacted array
msteindorfer Aug 19, 2022
810f22d
[Capsule] Add sequence representations for slices
msteindorfer Aug 19, 2022
afcd915
[Capsule] Add persistent dictionary `index` benchmarks
msteindorfer Aug 24, 2022
3e3e3cc
[Capsule] Add `Equatable` smoke test for a special case
msteindorfer Aug 25, 2022
3b2c061
[Capsule] Backout explicit collision bitmap to simplify codebase
msteindorfer Aug 25, 2022
c8a8807
[Capsule] Simplify initializers
msteindorfer Aug 25, 2022
c6b9719
[Capsule] Replace top-level `cachedSize` with per node `count`
msteindorfer Aug 29, 2022
b879788
[Capsule] Replace `sizePredicate` usage by `count`
msteindorfer Aug 29, 2022
fa8afba
[Capsule] Convert to `TrieNode` content and add specialized `index`
msteindorfer Aug 29, 2022
cc0f051
[Capsule] Revert to `AnyObject` node representation
msteindorfer Aug 30, 2022
3d4b802
[Capsule] Add specialized `subscript(position: Self.Index)` method
msteindorfer Sep 2, 2022
5eb679d
[Capsule] Reduce expensive invariant check that slow down testing
msteindorfer Sep 2, 2022
26893b1
[Capsule][WIP] Return to monomorphic spine
msteindorfer Sep 2, 2022
0550c27
[Capsule] Add `BitmapIndexedDictionaryNode: CustomDebugStringConverti…
msteindorfer Sep 5, 2022
81a38b3
[Capsule] Add `BitmapIndexedDictionaryNode: CustomStringConvertible` …
msteindorfer Sep 5, 2022
ef523a9
[Capsule] Add smoke test for larger hash-collision nodes
msteindorfer Sep 5, 2022
bf22461
[Capsule][WIP] Return to monomorphic spine, continued
msteindorfer Sep 5, 2022
8bc5e20
[Capsule] Enable `Keys` and `Values` view benchmarks
msteindorfer Sep 5, 2022
45b9d8d
[Capsule] Use non-materializing data/trie slice views in iterator
msteindorfer Sep 5, 2022
e9dec67
[Capsule] Rename base iterators
msteindorfer Sep 5, 2022
870e49d
[Capsule] Remove not necessary type alias
msteindorfer Sep 5, 2022
f6fe3c0
[Capsule] Add `init(uncheckedUniqueKeysWithValues:)` benchmark
msteindorfer Sep 6, 2022
a4bce51
[Capsule] Fix TODO comment
msteindorfer Sep 6, 2022
6b905eb
[Capsule] Implement `BitmapIndexedDictionaryNode: CustomStringConvert…
msteindorfer Sep 6, 2022
5bc17ff
[Capsule] Rename package to `PersistentCollections`
msteindorfer Sep 6, 2022
4e213be
[Capsule] Simplify insertion methods
msteindorfer Sep 6, 2022
7ea47d7
[Capsule] Simplify deletion methods
msteindorfer Sep 6, 2022
26b97f9
[Capsule] Unify insertion/deletion methods
msteindorfer Sep 6, 2022
49283d3
[Capsule] Remove unchecked variant of initializer
msteindorfer Sep 6, 2022
868eb2f
[Capsule] Remove comment after check
msteindorfer Sep 6, 2022
031b762
[Capsule] Fix test case argument label
msteindorfer Sep 6, 2022
e2f5344
[Capsule] Add `subscript(position:)` benchmarks
msteindorfer Sep 6, 2022
f930801
[Capsule] Expand `index(forKey:)` tests
msteindorfer Sep 6, 2022
fbb8aed
[Capsule] Remove non-applicable tests
msteindorfer Sep 6, 2022
ccd11e5
[Capsule] Clean-up annotations
msteindorfer Sep 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions Benchmarks/Benchmarks/DictionaryBenchmarks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,26 @@ extension Benchmark {
blackHole(d)
}

self.add(
title: "Dictionary<Int, Int> [COW] subscript, insert",
input: ([Int], [Int]).self
) { input, insert in
return { timer in
let d = Dictionary(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
let c = input.count
timer.measure {
for i in insert {
var e = d
e[c + i] = 2 * (c + i)
precondition(e.count == input.count + 1)
blackHole(e)
}
}
precondition(d.count == input.count)
blackHole(d)
}
}

self.addSimple(
title: "Dictionary<Int, Int> subscript, insert, reserving capacity",
input: [Int].self
Expand Down Expand Up @@ -174,6 +194,25 @@ extension Benchmark {
}
}

self.add(
title: "Dictionary<Int, Int> [COW] subscript, remove existing",
input: ([Int], [Int]).self
) { input, lookups in
return { timer in
let d = Dictionary(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
timer.measure {
for i in lookups {
var e = d
e[i] = nil
precondition(e.count == input.count - 1)
blackHole(e)
}
}
precondition(d.count == input.count)
blackHole(d)
}
}

self.add(
title: "Dictionary<Int, Int> subscript, remove missing",
input: ([Int], [Int]).self
Expand All @@ -191,6 +230,19 @@ extension Benchmark {
}
}

self.add(
title: "Dictionary<Int, Int> subscript(position:)",
input: ([Int], [Int]).self
) { input, lookups in
let d = Dictionary(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
let indices = lookups.map { d.index(forKey: $0)! }
return { timer in
for i in indices {
blackHole(d[i])
}
}
}

self.add(
title: "Dictionary<Int, Int> defaulted subscript, successful lookups",
input: ([Int], [Int]).self
Expand Down
52 changes: 52 additions & 0 deletions Benchmarks/Benchmarks/OrderedDictionaryBenchmarks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ extension Benchmark {
}
}

self.add(
title: "OrderedDictionary<Int, Int> subscript(position:)",
input: ([Int], [Int]).self
) { input, lookups in
let d = OrderedDictionary(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
let indices = lookups.map { d.index(forKey: $0)! }
return { timer in
for i in indices {
blackHole(d.elements[indices[i]]) // uses `elements` random-access collection view
}
}
}

self.add(
title: "OrderedDictionary<Int, Int> subscript, successful lookups",
input: ([Int], [Int]).self
Expand Down Expand Up @@ -176,6 +189,26 @@ extension Benchmark {
blackHole(d)
}

self.add(
title: "OrderedDictionary<Int, Int> [COW] subscript, append",
input: ([Int], [Int]).self
) { input, insert in
return { timer in
let d = OrderedDictionary(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
let c = input.count
timer.measure {
for i in insert {
var e = d
e[c + i] = 2 * (c + i)
precondition(e.count == input.count + 1)
blackHole(e)
}
}
precondition(d.count == input.count)
blackHole(d)
}
}

self.addSimple(
title: "OrderedDictionary<Int, Int> subscript, append, reserving capacity",
input: [Int].self
Expand Down Expand Up @@ -206,6 +239,25 @@ extension Benchmark {
}
}

self.add(
title: "OrderedDictionary<Int, Int> [COW] subscript, remove existing",
input: ([Int], [Int]).self
) { input, lookups in
return { timer in
let d = OrderedDictionary(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
timer.measure {
for i in lookups {
var e = d
e[i] = nil
precondition(e.count == input.count - 1)
blackHole(e)
}
}
precondition(d.count == input.count)
blackHole(d)
}
}

self.add(
title: "OrderedDictionary<Int, Int> subscript, remove missing",
input: ([Int], [Int]).self
Expand Down
Loading