Skip to content

Commit 6e2d604

Browse files
committed
Make everything inlinable.
There are a number of performance constraints that can be lifted in the source-available build mode. Many of these are ultimately about specialization, but we should resolve all of these with a judicious sprinkling of @inlinables.
1 parent 4bd2f81 commit 6e2d604

13 files changed

+371
-180
lines changed

Sources/HTTPTypes/HTTPField.swift

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,32 @@ public struct HTTPField: Sendable, Hashable {
2020
/// The strategy for whether the field is indexed in the HPACK or QPACK dynamic table.
2121
public struct DynamicTableIndexingStrategy: Sendable, Hashable {
2222
/// Default strategy.
23+
@inlinable
2324
public static var automatic: Self { .init(uncheckedValue: 0) }
2425

2526
/// Always put this field in the dynamic table if possible.
27+
@inlinable
2628
public static var prefer: Self { .init(uncheckedValue: 1) }
2729

2830
/// Don't put this field in the dynamic table.
31+
@inlinable
2932
public static var avoid: Self { .init(uncheckedValue: 2) }
3033

3134
/// Don't put this field in the dynamic table, and set a flag to disallow intermediaries to
3235
/// index this field.
36+
@inlinable
3337
public static var disallow: Self { .init(uncheckedValue: 3) }
3438

35-
fileprivate let rawValue: UInt8
39+
/* fileprivate but */ @usableFromInline let rawValue: UInt8
3640

37-
private static let maxRawValue: UInt8 = 3
41+
/* private but */ @usableFromInline static let maxRawValue: UInt8 = 3
3842

39-
private init(uncheckedValue: UInt8) {
43+
/* private but */ @inlinable init(uncheckedValue: UInt8) {
4044
assert(uncheckedValue <= Self.maxRawValue)
4145
self.rawValue = uncheckedValue
4246
}
4347

44-
fileprivate init?(rawValue: UInt8) {
48+
/* fileprivate but */ @inlinable init?(rawValue: UInt8) {
4549
if rawValue > Self.maxRawValue {
4650
return nil
4751
}
@@ -54,6 +58,7 @@ public struct HTTPField: Sendable, Hashable {
5458
/// - name: The HTTP field name.
5559
/// - value: The HTTP field value is initialized from the UTF-8 encoded bytes of the string.
5660
/// Invalid bytes are converted into space characters.
61+
@inlinable
5762
public init(name: Name, value: String) {
5863
self.name = name
5964
self.rawValue = Self.legalizeValue(ISOLatin1String(value))
@@ -63,6 +68,7 @@ public struct HTTPField: Sendable, Hashable {
6368
/// - Parameters:
6469
/// - name: The HTTP field name.
6570
/// - value: The HTTP field value. Invalid bytes are converted into space characters.
71+
@inlinable
6672
public init(name: Name, value: some Collection<UInt8>) {
6773
self.name = name
6874
self.rawValue = Self.legalizeValue(ISOLatin1String(value))
@@ -73,11 +79,13 @@ public struct HTTPField: Sendable, Hashable {
7379
/// - name: The HTTP field name.
7480
/// - lenientValue: The HTTP field value. Newlines and NULs are converted into space
7581
/// characters.
82+
@inlinable
7683
public init(name: Name, lenientValue: some Collection<UInt8>) {
7784
self.name = name
7885
self.rawValue = Self.lenientLegalizeValue(ISOLatin1String(lenientValue))
7986
}
8087

88+
@inlinable
8189
init(name: Name, uncheckedValue: ISOLatin1String) {
8290
self.name = name
8391
self.rawValue = uncheckedValue
@@ -94,6 +102,7 @@ public struct HTTPField: Sendable, Hashable {
94102
///
95103
/// If the field is not UTF-8 encoded, `withUnsafeBytesOfValue` can be used to access the
96104
/// underlying bytes of the field value.
105+
@inlinable
97106
public var value: String {
98107
get {
99108
self.rawValue.string
@@ -112,6 +121,7 @@ public struct HTTPField: Sendable, Hashable {
112121
///
113122
/// - Parameter body: The closure to be invoked with the buffer.
114123
/// - Returns: Result of the `body` closure.
124+
@inlinable
115125
public func withUnsafeBytesOfValue<Result>(
116126
_ body: (UnsafeBufferPointer<UInt8>) throws -> Result
117127
) rethrows -> Result {
@@ -121,9 +131,10 @@ public struct HTTPField: Sendable, Hashable {
121131
/// The strategy for whether the field is indexed in the HPACK or QPACK dynamic table.
122132
public var indexingStrategy: DynamicTableIndexingStrategy = .automatic
123133

134+
@usableFromInline
124135
var rawValue: ISOLatin1String
125136

126-
private static func _isValidValue(_ bytes: some Sequence<UInt8>) -> Bool {
137+
/* private but */ @inlinable static func _isValidValue(_ bytes: some Sequence<UInt8>) -> Bool {
127138
var iterator = bytes.makeIterator()
128139
guard var byte = iterator.next() else {
129140
// Empty string is allowed.
@@ -155,6 +166,7 @@ public struct HTTPField: Sendable, Hashable {
155166
return true
156167
}
157168

169+
@inlinable
158170
static func legalizeValue(_ value: ISOLatin1String) -> ISOLatin1String {
159171
if self._isValidValue(value._storage.utf8) {
160172
return value
@@ -176,6 +188,7 @@ public struct HTTPField: Sendable, Hashable {
176188
}
177189
}
178190

191+
@inlinable
179192
static func lenientLegalizeValue(_ value: ISOLatin1String) -> ISOLatin1String {
180193
if value._storage.utf8.allSatisfy({ $0 != 0x00 && $0 != 0x0A && $0 != 0x0D }) {
181194
return value
@@ -198,6 +211,7 @@ public struct HTTPField: Sendable, Hashable {
198211
///
199212
/// - Parameter value: The string to validate.
200213
/// - Returns: Whether the string is valid.
214+
@inlinable
201215
public static func isValidValue(_ value: String) -> Bool {
202216
self._isValidValue(value.utf8)
203217
}
@@ -208,30 +222,35 @@ public struct HTTPField: Sendable, Hashable {
208222
///
209223
/// - Parameter value: The byte collection to validate.
210224
/// - Returns: Whether the byte collection is valid.
225+
@inlinable
211226
public static func isValidValue(_ value: some Collection<UInt8>) -> Bool {
212227
self._isValidValue(value)
213228
}
214229
}
215230

216231
extension HTTPField: CustomStringConvertible {
232+
@inlinable
217233
public var description: String {
218234
"\(self.name): \(self.value)"
219235
}
220236
}
221237

222238
extension HTTPField: CustomPlaygroundDisplayConvertible {
239+
@inlinable
223240
public var playgroundDescription: Any {
224241
self.description
225242
}
226243
}
227244

228245
extension HTTPField: Codable {
246+
@usableFromInline
229247
enum CodingKeys: String, CodingKey {
230248
case name
231249
case value
232250
case indexingStrategy
233251
}
234252

253+
@inlinable
235254
public func encode(to encoder: Encoder) throws {
236255
var container = encoder.container(keyedBy: CodingKeys.self)
237256
try container.encode(self.name, forKey: .name)
@@ -241,6 +260,7 @@ extension HTTPField: Codable {
241260
}
242261
}
243262

263+
@inlinable
244264
public init(from decoder: Decoder) throws {
245265
let container = try decoder.container(keyedBy: CodingKeys.self)
246266
let name = try container.decode(Name.self, forKey: .name)
@@ -262,6 +282,7 @@ extension HTTPField: Codable {
262282
}
263283

264284
extension HTTPField {
285+
@inlinable
265286
static func isValidToken(_ token: some StringProtocol) -> Bool {
266287
!token.isEmpty
267288
&& token.utf8.allSatisfy {

0 commit comments

Comments
 (0)