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

Cherry pick recent fixes to release/1.0 in preparation of tagging 1.0.3 #168

Merged
merged 12 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS_Store
/.swiftpm
/.build
/Packages
/*.xcodeproj
Expand Down
7 changes: 0 additions & 7 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

This file was deleted.

30 changes: 30 additions & 0 deletions Benchmarks/Benchmarks/DequeBenchmarks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,36 @@ extension Benchmark {
}
}

self.add(
title: "Deque<Int> modify through subscript (contiguous)",
input: ([Int], [Int]).self
) { input, lookups in
return { timer in
var deque = Deque(input)
timer.measure {
for i in lookups {
deque[i] += 1
}
}
blackHole(deque)
}
}

self.add(
title: "Deque<Int> modify through subscript (discontiguous)",
input: ([Int], [Int]).self
) { input, lookups in
return { timer in
var deque = Deque(discontiguous: input)
timer.measure {
for i in lookups {
deque[i] += 1
}
}
blackHole(deque)
}
}

self.add(
title: "Deque<Int> random swaps (contiguous)",
input: [Int].self
Expand Down
33 changes: 22 additions & 11 deletions Sources/DequeModule/Deque+Collection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -359,25 +359,36 @@ extension Deque: RandomAccessCollection {
handle.ptr(at: slot).pointee = newValue
}
}
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
precondition(index >= 0 && index < count, "Index out of bounds")
_storage.ensureUnique()
// We technically aren't supposed to escape storage pointers out of a
// managed buffer, so we escape a `(slot, value)` pair instead, leaving
// the corresponding slot temporarily uninitialized.
var (slot, value) = _storage.update { handle -> (_Slot, Element) in
let slot = handle.slot(forOffset: index)
return (slot, handle.ptr(at: slot).move())
}
var (slot, value) = _prepareForModify(at: index)
defer {
_storage.update { handle in
handle.ptr(at: slot).initialize(to: value)
}
_finalizeModify(slot, value)
}
yield &value
}
}

@inlinable
internal mutating func _prepareForModify(at index: Int) -> (_Slot, Element) {
_storage.ensureUnique()
// We technically aren't supposed to escape storage pointers out of a
// managed buffer, so we escape a `(slot, value)` pair instead, leaving
// the corresponding slot temporarily uninitialized.
return _storage.update { handle in
let slot = handle.slot(forOffset: index)
return (slot, handle.ptr(at: slot).move())
}
}

@inlinable
internal mutating func _finalizeModify(_ slot: _Slot, _ value: Element) {
_storage.update { handle in
handle.ptr(at: slot).initialize(to: value)
}
}

/// Accesses a contiguous subrange of the deque's elements.
///
/// - Parameters:
Expand Down
1 change: 1 addition & 0 deletions Sources/OrderedCollections/HashTable/_HashTable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ extension _HashTable {
@inlinable
internal var header: Header {
get { _storage.header }
@inline(__always) // https://github.com/apple/swift-collections/issues/164
nonmutating _modify { yield &_storage.header }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extension OrderedDictionary {
get {
Elements(_base: self)
}
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
var elements = Elements(_base: self)
self = Self()
Expand Down Expand Up @@ -63,6 +64,7 @@ extension OrderedDictionary.Elements {
get {
_base.values
}
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
var values = OrderedDictionary.Values(_base: _base)
self = Self(_base: .init())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ extension OrderedDictionary.Values: MutableCollection {
get {
_base._values[position]
}
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
yield &_base._values[position]
}
Expand Down
117 changes: 76 additions & 41 deletions Sources/OrderedCollections/OrderedDictionary/OrderedDictionary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ extension OrderedDictionary {
@inline(__always)
public var values: Values {
get { Values(_base: self) }
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
var values = Values(_base: self)
self = [:]
Expand Down Expand Up @@ -367,41 +368,59 @@ extension OrderedDictionary {
}
_checkInvariants()
}
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
let (index, bucket) = _keys._find(key)

// To support in-place mutations better, we swap the value to the end of
// the array, pop it off, then put things back in place when we're done.
var value: Value? = nil
if let index = index {
_values.swapAt(index, _values.count - 1)
value = _values.removeLast()
}

var value: Value?
let (index, bucket) = _prepareForKeyingModify(key, &value)
defer {
switch (index, value) {
case let (index?, value?): // Assign
_values.append(value)
_values.swapAt(index, _values.count - 1)
case let (index?, nil): // Remove
if index < _values.count {
let standin = _values.remove(at: index)
_values.append(standin)
}
_keys._removeExistingMember(at: index, in: bucket)
case let (nil, value?): // Insert
_keys._appendNew(key, in: bucket)
_values.append(value)
case (nil, nil): // Noop
break
}
_checkInvariants()
_finalizeKeyingModify(key, index, bucket, &value)
}

yield &value
}
}

@inlinable
internal mutating func _prepareForKeyingModify(
_ key: Key,
_ value: inout Value?
) -> (index: Int?, bucket: _HashTable.Bucket) {
let (index, bucket) = _keys._find(key)

// To support in-place mutations better, we swap the value to the end of
// the array, pop it off, then put things back in place when we're done.
if let index = index {
_values.swapAt(index, _values.count - 1)
value = _values.removeLast()
}
return (index, bucket)
}

@inlinable
internal mutating func _finalizeKeyingModify(
_ key: Key,
_ index: Int?,
_ bucket: _HashTable.Bucket,
_ value: inout Value?
) {
switch (index, value) {
case let (index?, value?): // Assign
_values.append(value)
_values.swapAt(index, _values.count - 1)
case let (index?, nil): // Remove
if index < _values.count {
let standin = _values.remove(at: index)
_values.append(standin)
}
_keys._removeExistingMember(at: index, in: bucket)
case let (nil, value?): // Insert
_keys._appendNew(key, in: bucket)
_values.append(value)
case (nil, nil): // Noop
break
}
_checkInvariants()
}

/// Accesses the value with the given key. If the dictionary doesn't contain
/// the given key, accesses the provided default value as if the key and
/// default value existed in the dictionary.
Expand Down Expand Up @@ -472,26 +491,42 @@ extension OrderedDictionary {
guard let offset = _keys.firstIndex(of: key) else { return defaultValue() }
return _values[offset]
}
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
let (inserted, index) = _keys.append(key)
if inserted {
assert(index == _values.count)
_values.append(defaultValue())
}
var value: Value = _values.withUnsafeMutableBufferPointer { buffer in
assert(index < buffer.count)
return (buffer.baseAddress! + index).move()
}
var (index, value) = _prepareForDefaultedModify(key, defaultValue)
defer {
_values.withUnsafeMutableBufferPointer { buffer in
assert(index < buffer.count)
(buffer.baseAddress! + index).initialize(to: value)
}
_finalizeDefaultedModify(index, &value)
}
yield &value
}
}

@inlinable
internal mutating func _prepareForDefaultedModify(
_ key: Key,
_ defaultValue: () -> Value
) -> (index: Int, value: Value) {
let (inserted, index) = _keys.append(key)
if inserted {
assert(index == _values.count)
_values.append(defaultValue())
}
let value: Value = _values.withUnsafeMutableBufferPointer { buffer in
assert(index < buffer.count)
return (buffer.baseAddress! + index).move()
}
return (index, value)
}

@inlinable
internal mutating func _finalizeDefaultedModify(
_ index: Int, _ value: inout Value
) {
_values.withUnsafeMutableBufferPointer { buffer in
assert(index < buffer.count)
(buffer.baseAddress! + index).initialize(to: value)
}
}
}

extension OrderedDictionary {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ extension OrderedSet {
/// conformance.
@frozen
public struct UnorderedView {
public typealias Element = OrderedSet.Element

@usableFromInline
internal var _base: OrderedSet

Expand Down Expand Up @@ -54,7 +52,7 @@ extension OrderedSet {
get {
UnorderedView(_base: self)
}
@inline(__always)
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
var view = UnorderedView(_base: self)
self = OrderedSet()
Expand Down Expand Up @@ -138,7 +136,9 @@ extension OrderedSet.UnorderedView: ExpressibleByArrayLiteral {
}
}

extension OrderedSet.UnorderedView: SetAlgebra {}
extension OrderedSet.UnorderedView: SetAlgebra {
public typealias Element = OrderedSet.Element
}

extension OrderedSet.UnorderedView {
/// Creates an empty set.
Expand Down Expand Up @@ -302,7 +302,7 @@ extension OrderedSet.UnorderedView {
@inlinable
@inline(__always)
@discardableResult
public mutating func remove(_ member: Self.Element) -> Self.Element? {
public mutating func remove(_ member: Element) -> Element? {
_base.remove(member)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ extension OrderedSet {
_UnstableInternals(self)
}

@inline(__always)
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
var view = _UnstableInternals(self)
self = OrderedSet()
Expand Down
1 change: 1 addition & 0 deletions Sources/OrderedCollections/OrderedSet/OrderedSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ extension OrderedSet {
set {
self = .init(newValue)
}
@inline(__always) // https://github.com/apple/swift-collections/issues/164
_modify {
var members = Array(_elements)
_elements = []
Expand Down
10 changes: 10 additions & 0 deletions Sources/OrderedCollections/Utilities/_UnsafeBitset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ extension _UnsafeBitset {
run body: (inout _UnsafeBitset) throws -> Void
) rethrows {
let wordCount = _UnsafeBitset.wordCount(forCapacity: capacity)
#if compiler(>=5.6)
return try withUnsafeTemporaryAllocation(
of: Word.self, capacity: wordCount
) { words in
words.initialize(repeating: .empty)
var bitset = Self(words: words, count: 0)
return try body(&bitset)
}
#else
if wordCount <= 2 {
var buffer: (Word, Word) = (.empty, .empty)
return try withUnsafeMutablePointer(to: &buffer) { p in
Expand All @@ -87,6 +96,7 @@ extension _UnsafeBitset {
defer { words.deallocate() }
var bitset = _UnsafeBitset(words: words, count: 0)
return try body(&bitset)
#endif
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
// This source file is part of the Swift Collections open source project
//
// Copyright (c) 2021 Apple Inc. and the Swift project authors
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
"repositoryURL": "https://github.com/apple/swift-argument-parser",
"state": {
"branch": null,
"revision": "986d191f94cec88f6350056da59c2e59e83d1229",
"version": "0.4.3"
"revision": "df9ee6676cd5b3bf5b330ec7568a5644f547201b",
"version": "1.1.3"
}
},
{
"package": "swift-system",
"repositoryURL": "https://github.com/apple/swift-system",
"state": {
"branch": null,
"revision": "2bc160bfe34d843ae5ff47168080add24dfd7eac",
"version": "0.0.2"
"revision": "39774ef16a6d91dee6f666b940e00ea202710cf7",
"version": "0.0.3"
}
}
]
Expand Down
Loading