Skip to content

Commit

Permalink
Move _TinyArray into a separate module
Browse files Browse the repository at this point in the history
and apply review feedback
  • Loading branch information
dnadoba committed Jun 19, 2023
1 parent 6a42c66 commit e2f3a52
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@
//
//===----------------------------------------------------------------------===//

@_spi(IntegrationTests) import X509
import _CertificateInternals

func run(identifier: String) {
measure(identifier: identifier) {
var tinyArray = TinyArray<Int>()
for i in 0..<1000 {
tinyArray.append(i)
var count = 0
for _ in 0..<1000 {
var tinyArray = _TinyArray<Int>()
for i in 0..<1000 {
tinyArray.append(i)
}
count += tinyArray.count
}
return tinyArray.count

return count
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@
//
//===----------------------------------------------------------------------===//

@_spi(IntegrationTests) import X509
import _CertificateInternals

func run(identifier: String) {
measure(identifier: identifier) {
var counts = 0
counts += TinyArray(CollectionOfOne(1)).count

do {
var array = TinyArray<Int>()
array.append(contentsOf: CollectionOfOne(1))
counts += array.count
for _ in 0..<1000 {
counts += _TinyArray(CollectionOfOne(1)).count

do {
var array = _TinyArray<Int>()
array.append(contentsOf: CollectionOfOne(1))
counts += array.count
}
}

return counts
Expand Down
11 changes: 11 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ let package = Package(
.target(
name: "X509",
dependencies: [
"_CertificateInternals",
.product(name: "SwiftASN1", package: "swift-asn1"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "_CryptoExtras", package: "swift-crypto"),
Expand All @@ -55,6 +56,16 @@ let package = Package(
.copy("PEMTestRSACertificate.pem"),
.copy("CSR Vectors/"),
]),
.target(
name: "_CertificateInternals",
exclude: [
"CMakeLists.txt",
]),
.testTarget(
name: "CertificateInternalsTests",
dependencies: [
"_CertificateInternals",
]),
]
)

Expand Down
1 change: 1 addition & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
##===----------------------------------------------------------------------===##

add_subdirectory(X509)
add_subdirectory(_CertificateInternals)
1 change: 0 additions & 1 deletion Sources/X509/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ add_library(X509
"SEC1PrivateKey.swift"
"Signature.swift"
"SignatureAlgorithm.swift"
"TinyArray.swift"
"Verifier/AnyPolicy.swift"
"Verifier/CertificateStore.swift"
"Verifier/PolicyBuilder.swift"
Expand Down
23 changes: 23 additions & 0 deletions Sources/_CertificateInternals/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftCertificates open source project
##
## Copyright (c) 2023 Apple Inc. and the SwiftCertificates project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftCertificates project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##

add_library(_CertificateInternals
"TinyArray.swift")

target_link_libraries(X509 PUBLIC)
set_target_properties(_CertificateInternals PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})

_install_target(_CertificateInternals)
set_property(GLOBAL APPEND PROPERTY SWIFT_CERTIFICATES_EXPORTS _TinyArray)
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import Foundation
/// ``TinyArray`` is a ``RandomAccessCollection`` optimised to store zero or one ``Element``.
/// It supports arbitrary many elements but if only up to one ``Element`` is stored it does **not** allocate separate storage on the heap
/// and instead stores the ``Element`` inline.
@_spi(IntegrationTests) public struct TinyArray<Element> {
public struct _TinyArray<Element> {
@usableFromInline
enum Storage {
case one(Element)
Expand All @@ -30,79 +30,79 @@ import Foundation

// MARK: - TinyArray "public" interface

extension TinyArray: Equatable where Element: Equatable {}
extension TinyArray: Hashable where Element: Hashable {}
extension TinyArray: Sendable where Element: Sendable {}
extension _TinyArray: Equatable where Element: Equatable {}
extension _TinyArray: Hashable where Element: Hashable {}
extension _TinyArray: Sendable where Element: Sendable {}

extension TinyArray: RandomAccessCollection {
@_spi(IntegrationTests) public typealias Element = Element
extension _TinyArray: RandomAccessCollection {
public typealias Element = Element

@_spi(IntegrationTests) public typealias Index = Int
public typealias Index = Int

@inlinable
@_spi(IntegrationTests) public subscript(position: Int) -> Element {
public subscript(position: Int) -> Element {
get {
self.storage[position]
}
}

@inlinable
@_spi(IntegrationTests) public var startIndex: Int {
public var startIndex: Int {
self.storage.startIndex
}

@inlinable
@_spi(IntegrationTests) public var endIndex: Int {
public var endIndex: Int {
self.storage.endIndex
}
}

extension TinyArray {
extension _TinyArray {
@inlinable
@_spi(IntegrationTests) public init(_ elements: some Sequence<Element>) {
public init(_ elements: some Sequence<Element>) {
self.storage = .init(elements)
}

@inlinable
@_spi(IntegrationTests) public init(_ elements: some Sequence<Result<Element, some Error>>) throws {
public init(_ elements: some Sequence<Result<Element, some Error>>) throws {
self.storage = try .init(elements)
}

@inlinable
@_spi(IntegrationTests) public init() {
public init() {
self.storage = .init()
}

@inlinable
@_spi(IntegrationTests) public mutating func append(_ newElement: Element) {
public mutating func append(_ newElement: Element) {
self.storage.append(newElement)
}

@inlinable
@_spi(IntegrationTests) public mutating func append(contentsOf newElements: some Sequence<Element>){
public mutating func append(contentsOf newElements: some Sequence<Element>){
self.storage.append(contentsOf: newElements)
}

@discardableResult
@inlinable
@_spi(IntegrationTests) public mutating func remove(at index: Int) -> Element {
public mutating func remove(at index: Int) -> Element {
self.storage.remove(at: index)
}

@inlinable
@_spi(IntegrationTests) public mutating func removeAll(where shouldBeRemoved: (Element) throws -> Bool) rethrows {
public mutating func removeAll(where shouldBeRemoved: (Element) throws -> Bool) rethrows {
try self.storage.removeAll(where: shouldBeRemoved)
}

@inlinable
@_spi(IntegrationTests) public mutating func sort(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows {
public mutating func sort(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows {
try self.storage.sort(by: areInIncreasingOrder)
}
}

// MARK: - TinyArray.Storage "private" implementation

extension TinyArray.Storage: Equatable where Element: Equatable {
extension _TinyArray.Storage: Equatable where Element: Equatable {
@inlinable
static func ==(lhs: Self, rhs: Self) -> Bool {
switch (lhs, rhs) {
Expand All @@ -123,7 +123,7 @@ extension TinyArray.Storage: Equatable where Element: Equatable {
}
}
}
extension TinyArray.Storage: Hashable where Element: Hashable {
extension _TinyArray.Storage: Hashable where Element: Hashable {
@inlinable
func hash(into hasher: inout Hasher) {
// same strategy as Array: https://github.com/apple/swift/blob/b42019005988b2d13398025883e285a81d323efa/stdlib/public/core/Array.swift#L1801
Expand All @@ -133,9 +133,9 @@ extension TinyArray.Storage: Hashable where Element: Hashable {
}
}
}
extension TinyArray.Storage: Sendable where Element: Sendable {}
extension _TinyArray.Storage: Sendable where Element: Sendable {}

extension TinyArray.Storage: RandomAccessCollection {
extension _TinyArray.Storage: RandomAccessCollection {
@inlinable
subscript(position: Int) -> Element {
get {
Expand Down Expand Up @@ -165,7 +165,7 @@ extension TinyArray.Storage: RandomAccessCollection {
}
}

extension TinyArray.Storage {
extension _TinyArray.Storage {
@inlinable
init(_ elements: some Sequence<Element>) {
self = .arbitrary([])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@
//===----------------------------------------------------------------------===//

import XCTest
@_spi(IntegrationTests) import X509
import _CertificateInternals

final class TinyArrayTests: XCTestCase {
private func _assertEqual(
_ expected: @autoclosure () -> some Sequence<Int>,
initial: @autoclosure () -> TinyArray<Int>,
_ mutate: (inout TinyArray<Int>) -> (),
initial: @autoclosure () -> _TinyArray<Int>,
_ mutate: (inout _TinyArray<Int>) -> (),
file: StaticString = #filePath,
line: UInt = #line
) {
var actual = initial()
mutate(&actual)
XCTAssertEqual(Array(actual), Array(expected()), file: file, line: line)
let expected = TinyArray(expected())
let expected = _TinyArray(expected())
XCTAssertEqual(actual, expected, file: file, line: line)
var acutalHasher = Hasher()
acutalHasher.combine(actual)
Expand All @@ -37,8 +37,8 @@ final class TinyArrayTests: XCTestCase {

private func assertEqual(
_ expected: [Int],
initial: @autoclosure () -> TinyArray<Int> = TinyArray(),
_ mutate: (inout TinyArray<Int>) -> (),
initial: @autoclosure () -> _TinyArray<Int> = _TinyArray(),
_ mutate: (inout _TinyArray<Int>) -> (),
file: StaticString = #filePath,
line: UInt = #line
) {
Expand All @@ -48,17 +48,17 @@ final class TinyArrayTests: XCTestCase {
}

func testInit() {
XCTAssertEqual(Array(TinyArray([Int]())), [])
XCTAssertEqual(Array(TinyArray<Int>()), [])
XCTAssertEqual(TinyArray<Int>(), TinyArray<Int>([]))
XCTAssertEqual(Array(_TinyArray([Int]())), [])
XCTAssertEqual(Array(_TinyArray<Int>()), [])
XCTAssertEqual(_TinyArray<Int>(), _TinyArray<Int>([]))

XCTAssertEqual(Array(TinyArray<Int>(CollectionOfOne(1))), [1])
XCTAssertEqual(Array(TinyArray<Int>([1])), [1])
XCTAssertEqual(Array(TinyArray<Int>([1, 2])), [1, 2])
XCTAssertEqual(Array(_TinyArray<Int>(CollectionOfOne(1))), [1])
XCTAssertEqual(Array(_TinyArray<Int>([1])), [1])
XCTAssertEqual(Array(_TinyArray<Int>([1, 2])), [1, 2])

XCTAssertEqual(Array(TinyArray<Int>([1, 2, 3])), [1, 2, 3])
XCTAssertEqual(Array(TinyArray<Int>([1, 2, 3, 4])), [1, 2, 3, 4])
XCTAssertEqual(Array(TinyArray<Int>([1, 2, 3, 4, 5])), [1, 2, 3, 4, 5])
XCTAssertEqual(Array(_TinyArray<Int>([1, 2, 3])), [1, 2, 3])
XCTAssertEqual(Array(_TinyArray<Int>([1, 2, 3, 4])), [1, 2, 3, 4])
XCTAssertEqual(Array(_TinyArray<Int>([1, 2, 3, 4, 5])), [1, 2, 3, 4, 5])
}

func testAppend() {
Expand Down Expand Up @@ -279,27 +279,27 @@ final class TinyArrayTests: XCTestCase {
}

func testThrowingInitFromResult() {
XCTAssertEqual(Array(try TinyArray<Int>(CollectionOfOne(Result<_, Error>.success(1)))), [1])
XCTAssertEqual(Array(try TinyArray([Result<_, Error>.success(1)])), [1])
XCTAssertEqual(Array(try TinyArray([Result<_, Error>.success(1), .success(2)])), [1, 2])
XCTAssertEqual(Array(try TinyArray([Result<_, Error>.success(1), .success(2), .success(3)])), [1, 2, 3])
XCTAssertEqual(Array(try TinyArray([Result<_, Error>.success(1), .success(2), .success(3), .success(4)])), [1, 2, 3, 4])
XCTAssertEqual(Array(try TinyArray([Result<_, Error>.success(1), .success(2), .success(3), .success(4), .success(5)])), [1, 2, 3, 4, 5])
XCTAssertEqual(Array(try _TinyArray<Int>(CollectionOfOne(Result<_, Error>.success(1)))), [1])
XCTAssertEqual(Array(try _TinyArray([Result<_, Error>.success(1)])), [1])
XCTAssertEqual(Array(try _TinyArray([Result<_, Error>.success(1), .success(2)])), [1, 2])
XCTAssertEqual(Array(try _TinyArray([Result<_, Error>.success(1), .success(2), .success(3)])), [1, 2, 3])
XCTAssertEqual(Array(try _TinyArray([Result<_, Error>.success(1), .success(2), .success(3), .success(4)])), [1, 2, 3, 4])
XCTAssertEqual(Array(try _TinyArray([Result<_, Error>.success(1), .success(2), .success(3), .success(4), .success(5)])), [1, 2, 3, 4, 5])

struct MyError: Error {}

XCTAssertThrowsError(Array(try TinyArray<Int>([Result.failure(MyError())])))
XCTAssertThrowsError(Array(try TinyArray<Int>([Result.failure(MyError()), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try TinyArray<Int>([.success(1), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try TinyArray<Int>([.success(1), Result.failure(MyError()), .success(2)])))
XCTAssertThrowsError(Array(try TinyArray<Int>([.success(1), .success(2), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try TinyArray<Int>([.success(1), .success(2), Result.failure(MyError()), .success(4)])))
XCTAssertThrowsError(Array(try TinyArray<Int>([.success(1), .success(2), .success(3), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try TinyArray<Int>([.success(1), .success(2), .success(3), .success(4), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try _TinyArray<Int>([Result.failure(MyError())])))
XCTAssertThrowsError(Array(try _TinyArray<Int>([Result.failure(MyError()), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try _TinyArray<Int>([.success(1), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try _TinyArray<Int>([.success(1), Result.failure(MyError()), .success(2)])))
XCTAssertThrowsError(Array(try _TinyArray<Int>([.success(1), .success(2), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try _TinyArray<Int>([.success(1), .success(2), Result.failure(MyError()), .success(4)])))
XCTAssertThrowsError(Array(try _TinyArray<Int>([.success(1), .success(2), .success(3), Result.failure(MyError())])))
XCTAssertThrowsError(Array(try _TinyArray<Int>([.success(1), .success(2), .success(3), .success(4), Result.failure(MyError())])))
}
}

extension TinyArray: ExpressibleByArrayLiteral {
extension _TinyArray: ExpressibleByArrayLiteral {
public typealias ArrayLiteralElement = Element

public init(arrayLiteral elements: Element...) {
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose.2204.57.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ services:
image: swift-certificates:22.04-5.7
environment:
- WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
- MAX_ALLOCS_ALLOWED_tiny_array_cow_append_contents_of=10
- MAX_ALLOCS_ALLOWED_tiny_array_cow_append_contents_of=10000
- MAX_ALLOCS_ALLOWED_tiny_array_non_allocating_operations=0
# - SANITIZER_ARG=--sanitize=thread # TSan broken still

Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose.2204.58.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ services:
environment:
- WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
- IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error
- MAX_ALLOCS_ALLOWED_tiny_array_cow_append_contents_of=10
- MAX_ALLOCS_ALLOWED_tiny_array_cow_append_contents_of=10000
- MAX_ALLOCS_ALLOWED_tiny_array_non_allocating_operations=0
# - SANITIZER_ARG=--sanitize=thread # TSan broken still

Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose.2204.59.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ services:
environment:
- WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
- IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error
- MAX_ALLOCS_ALLOWED_tiny_array_cow_append_contents_of=10
- MAX_ALLOCS_ALLOWED_tiny_array_cow_append_contents_of=10000
- MAX_ALLOCS_ALLOWED_tiny_array_non_allocating_operations=0
# - SANITIZER_ARG=--sanitize=thread # TSan broken still

Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose.2204.main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ services:
environment:
- WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
- IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error
- MAX_ALLOCS_ALLOWED_tiny_array_cow_append_contents_of=10
- MAX_ALLOCS_ALLOWED_tiny_array_cow_append_contents_of=10000
- MAX_ALLOCS_ALLOWED_tiny_array_non_allocating_operations=0
# - SANITIZER_ARG=--sanitize=thread # TSan broken still

Expand Down
1 change: 1 addition & 0 deletions scripts/update_cmakelists.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ function update_cmakelists_source() {
}

update_cmakelists_source "X509" "*.swift"
update_cmakelists_source "_CertificateInternals" "*.swift"

0 comments on commit e2f3a52

Please sign in to comment.