Skip to content

Commit 03a6a48

Browse files
committed
code review
1 parent 74ce004 commit 03a6a48

4 files changed

+151
-126
lines changed

Sources/NIOCore/ByteBuffer-binaryEncodedLengthPrefix.swift

+73-65
Original file line numberDiff line numberDiff line change
@@ -28,96 +28,104 @@ import Bionic
2828

2929
/// Describes a way to encode and decode an integer as bytes
3030
///
31-
public protocol BinaryIntegerEncodingStrategy {
32-
/// Read an integer from a buffer. The reader index should be moved accordingly
33-
/// - Returns: The integer
31+
public protocol NIOBinaryIntegerEncodingStrategy {
32+
/// Read an integer from a buffer.
33+
/// If there are not enough bytes to read an integer of this encoding, return nil, and do not move the reader index.
34+
/// If the the full integer can be read, move the reader index to after the integer, and return the integer.
35+
/// - Parameters:
36+
/// - as: The type of integer to be read.
37+
/// - buffer: The buffer to read from.
38+
/// - Returns: The integer that was read, or nil if it was not possible to read it.
3439
func readInteger<IntegerType: FixedWidthInteger>(
3540
as: IntegerType.Type,
3641
from buffer: inout ByteBuffer
3742
) -> IntegerType?
3843

39-
/// Write an integer to a buffer. The writer index should be moved accordingly
44+
/// Write an integer to a buffer. Move the writer index to after the written integer.
45+
/// - Parameters:
46+
/// - integer: The type of the integer to write.
47+
/// - to: The buffer to write to.
4048
func writeInteger<IntegerType: FixedWidthInteger>(
4149
_ integer: IntegerType,
4250
to buffer: inout ByteBuffer
4351
) -> Int
4452

45-
/// When writing an integer using this strategy, how many bytes we should reserve
46-
/// If the actual bytes used by the write function is more or less than this, it will be necessary to shuffle bytes
47-
/// Therefore, an accurate prediction here will improve performance
48-
var reservedSpaceForInteger: Int { get }
53+
/// When writing an integer using this strategy, how many bytes we should reserve.
54+
/// If the actual bytes used by the write function is more or less than this, it will be necessary to shuffle bytes.
55+
/// Therefore, an accurate prediction here will improve performance.
56+
var reservedCapacityForInteger: Int { get }
4957

50-
/// Write an integer to a buffer. The writer index should be moved accordingly
51-
/// This function takes a `reservedSpace` parameter which is the number of bytes we already reserved for writing this integer
52-
/// If you use write more or less than this many bytes, we wll need to move bytes around to make that possible
53-
/// Therefore, you may decide to encode differently to use more bytes than you actually would need, if it is possible for you to do so
54-
/// That way, you waste the reserved bytes, but improve writing performance
55-
func writeIntegerWithReservedSpace(
58+
/// Write an integer to a buffer. The writer index should be moved accordingly.
59+
/// This function takes a `reservedCapacity` parameter which is the number of bytes we already reserved for writing this integer.
60+
/// If you use write more or less than this many bytes, we wll need to move bytes around to make that possible.
61+
/// Therefore, you may decide to encode differently to use more bytes than you actually would need, if it is possible for you to do so.
62+
/// That way, you waste the reserved bytes, but improve writing performance.
63+
func writeIntegerWithReservedCapacity(
5664
_ integer: Int,
57-
reservedSpace: Int,
65+
reservedCapacity: Int,
5866
to buffer: inout ByteBuffer
5967
) -> Int
6068
}
6169

62-
extension BinaryIntegerEncodingStrategy {
70+
extension NIOBinaryIntegerEncodingStrategy {
6371
@inlinable
64-
public var reservedSpaceForInteger: Int { 1 }
72+
public var reservedCapacityForInteger: Int { 1 }
6573

6674
@inlinable
67-
public func writeIntegerWithReservedSpace<IntegerType: FixedWidthInteger>(
75+
public func writeIntegerWithReservedCapacity<IntegerType: FixedWidthInteger>(
6876
_ integer: IntegerType,
69-
reservedSpace: Int,
77+
reservedCapacity: Int,
7078
to buffer: inout ByteBuffer
7179
) -> Int {
7280
self.writeInteger(integer, to: &buffer)
7381
}
7482
}
7583

7684
extension ByteBuffer {
77-
/// Read a binary encoded integer, moving the `readerIndex` appropriately
78-
/// If there are not enough bytes, nil is returned
85+
/// Read a binary encoded integer, moving the `readerIndex` appropriately.
86+
/// If there are not enough bytes, nil is returned.
7987
@inlinable
80-
public mutating func readEncodedInteger<Strategy: BinaryIntegerEncodingStrategy>(_ strategy: Strategy) -> Int? {
88+
public mutating func readEncodedInteger<Strategy: NIOBinaryIntegerEncodingStrategy>(_ strategy: Strategy) -> Int? {
8189
strategy.readInteger(as: Int.self, from: &self)
8290
}
8391

8492
/// Write a binary encoded integer.
8593
///
86-
/// - Returns: The number of bytes written
94+
/// - Returns: The number of bytes written.
8795
@discardableResult
8896
@inlinable
8997
public mutating func writeEncodedInteger<
9098
Integer: FixedWidthInteger,
91-
Strategy: BinaryIntegerEncodingStrategy
99+
Strategy: NIOBinaryIntegerEncodingStrategy
92100
>(
93101
_ value: Integer,
94102
strategy: Strategy
95103
) -> Int {
96104
strategy.writeInteger(value, to: &self)
97105
}
98106

99-
/// Prefixes a message written by `writeMessage` with the number of bytes written using `strategy`
107+
/// Prefixes a message written by `writeMessage` with the number of bytes written using `strategy`.
100108
///
101-
/// Implementation note: This function works by reserving the number of bytes suggested by ``BinaryIntegerEncodingStrategy.reservedSpace`` before the data
102-
/// It then writes the data, and then goes back to write the length
103-
/// If the reserved capacity turns out to be too little or too much, then the data will be shifted
104-
/// Therefore, this function is most performant if the strategy is able to use the same number of bytes that it reserved
109+
/// - Note: This function works by reserving the number of bytes suggested by `strategy` before the data.
110+
/// It then writes the data, and then goes back to write the length.
111+
/// If the reserved capacity turns out to be too little or too much, then the data will be shifted.
112+
/// Therefore, this function is most performant if the strategy is able to use the same number of bytes that it reserved.
105113
///
106114
/// - Parameters:
107-
/// - strategy: The strategy to use for encoding the length
108-
/// - writeMessage: A closure that takes a buffer, writes a message to it and returns the number of bytes written
109-
/// - Returns: Number of total bytes written. This is the length of the written message + the number of bytes used to write the length before it
115+
/// - strategy: The strategy to use for encoding the length.
116+
/// - writeMessage: A closure that takes a buffer, writes a message to it and returns the number of bytes written.
117+
/// - Returns: Number of total bytes written. This is the length of the written message + the number of bytes used to write the length before it.
110118
@discardableResult
111119
@inlinable
112-
public mutating func writeLengthPrefixed<Strategy: BinaryIntegerEncodingStrategy>(
120+
public mutating func writeLengthPrefixed<Strategy: NIOBinaryIntegerEncodingStrategy>(
113121
strategy: Strategy,
114122
writeMessage: (inout ByteBuffer) throws -> Int
115123
) rethrows -> Int {
116124
/// The index at which we write the length
117125
let lengthPrefixIndex = self.writerIndex
118126
/// The space which we reserve for writing the length
119-
let reservedSpace = strategy.reservedSpaceForInteger
120-
self.writeRepeatingByte(0, count: reservedSpace)
127+
let reservedCapacity = strategy.reservedCapacityForInteger
128+
self.writeRepeatingByte(0, count: reservedCapacity)
121129

122130
/// The index at which we start writing the message originally. We may later move the message if the reserved space for the length wasn't right
123131
let originalMessageStartIndex = self.writerIndex
@@ -142,18 +150,18 @@ extension ByteBuffer {
142150
// We write the length after the message to begin with. We will move it later
143151

144152
/// The actual number of bytes used to write the length written. The user may write more or fewer bytes than what we reserved
145-
let actualIntegerLength = strategy.writeIntegerWithReservedSpace(
153+
let actualIntegerLength = strategy.writeIntegerWithReservedCapacity(
146154
messageLength,
147-
reservedSpace: reservedSpace,
155+
reservedCapacity: reservedCapacity,
148156
to: &self
149157
)
150158

151159
switch actualIntegerLength {
152-
case reservedSpace:
160+
case reservedCapacity:
153161
// Good, exact match, swap the values and then "delete" the trailing bytes by moving the index back
154162
self._moveBytes(from: originalMessageEndIndex, to: lengthPrefixIndex, size: actualIntegerLength)
155163
self.moveWriterIndex(to: originalMessageEndIndex)
156-
case ..<reservedSpace:
164+
case ..<reservedCapacity:
157165
// We wrote fewer bytes. We now have to move the length bytes from the end, and
158166
// _then_ shrink the rest of the buffer onto it.
159167
self._moveBytes(from: originalMessageEndIndex, to: lengthPrefixIndex, size: actualIntegerLength)
@@ -164,10 +172,10 @@ extension ByteBuffer {
164172
size: messageLength
165173
)
166174
self.moveWriterIndex(to: newMessageStartIndex + messageLength)
167-
case reservedSpace...:
175+
case reservedCapacity...:
168176
// We wrote more bytes. We now have to create enough space. Once we do, we have the same
169177
// implementation as the matching case.
170-
let extraSpaceNeeded = actualIntegerLength - reservedSpace
178+
let extraSpaceNeeded = actualIntegerLength - reservedCapacity
171179
self._createSpace(before: lengthPrefixIndex, requiredSpace: extraSpaceNeeded)
172180

173181
// Clean up the indices.
@@ -183,10 +191,10 @@ extension ByteBuffer {
183191
return totalBytesWritten
184192
}
185193

186-
/// Reads a slice which is prefixed with a length. The length will be read using `strategy`, and then that many bytes will be read to create a slice
187-
/// - Returns: The slice, if there are enough bytes to read it fully. In this case, the readerIndex will move to after the slice
188-
/// If there are not enough bytes to read the full slice, the readerIndex will stay unchanged
189-
public mutating func readLengthPrefixedSlice<Strategy: BinaryIntegerEncodingStrategy>(
194+
/// Reads a slice which is prefixed with a length. The length will be read using `strategy`, and then that many bytes will be read to create a slice.
195+
/// - Returns: The slice, if there are enough bytes to read it fully. In this case, the readerIndex will move to after the slice.
196+
/// If there are not enough bytes to read the full slice, the readerIndex will stay unchanged.
197+
public mutating func readLengthPrefixedSlice<Strategy: NIOBinaryIntegerEncodingStrategy>(
190198
_ strategy: Strategy
191199
) -> ByteBuffer? {
192200
let originalReaderIndex = self.readerIndex
@@ -202,14 +210,14 @@ extension ByteBuffer {
202210
// MARK: - Helpers for writing length-prefixed things
203211

204212
extension ByteBuffer {
205-
/// Write the length of `buffer` using `strategy`. Then write the buffer
213+
/// Write the length of `buffer` using `strategy`. Then write the buffer.
206214
/// - Parameters:
207-
/// - buffer: The buffer to be written
208-
/// - strategy: The encoding strategy to use
209-
/// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the buffer itself
215+
/// - buffer: The buffer to be written.
216+
/// - strategy: The encoding strategy to use.
217+
/// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the buffer itself.
210218
@discardableResult
211219
public mutating func writeLengthPrefixedBuffer<
212-
Strategy: BinaryIntegerEncodingStrategy
220+
Strategy: NIOBinaryIntegerEncodingStrategy
213221
>(
214222
_ buffer: ByteBuffer,
215223
strategy: Strategy
@@ -220,14 +228,14 @@ extension ByteBuffer {
220228
return written
221229
}
222230

223-
/// Write the length of `string` using `strategy`. Then write the string
231+
/// Write the length of `string` using `strategy`. Then write the string.
224232
/// - Parameters:
225-
/// - string: The string to be written
226-
/// - strategy: The encoding strategy to use
227-
/// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the string itself
233+
/// - string: The string to be written.
234+
/// - strategy: The encoding strategy to use.
235+
/// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the string itself.
228236
@discardableResult
229237
public mutating func writeLengthPrefixedString<
230-
Strategy: BinaryIntegerEncodingStrategy
238+
Strategy: NIOBinaryIntegerEncodingStrategy
231239
>(
232240
_ string: String,
233241
strategy: Strategy
@@ -240,15 +248,15 @@ extension ByteBuffer {
240248
return written
241249
}
242250

243-
/// Write the length of `bytes` using `strategy`. Then write the bytes
251+
/// Write the length of `bytes` using `strategy`. Then write the bytes.
244252
/// - Parameters:
245-
/// - bytes: The bytes to be written
246-
/// - strategy: The encoding strategy to use
247-
/// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the bytes themselves
253+
/// - bytes: The bytes to be written.
254+
/// - strategy: The encoding strategy to use.
255+
/// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the bytes themselves.
248256
@inlinable
249257
public mutating func writeLengthPrefixedBytes<
250258
Bytes: Sequence,
251-
Strategy: BinaryIntegerEncodingStrategy
259+
Strategy: NIOBinaryIntegerEncodingStrategy
252260
>(
253261
_ bytes: Bytes,
254262
strategy: Strategy
@@ -271,11 +279,11 @@ extension ByteBuffer {
271279
}
272280

273281
extension ByteBuffer {
274-
/// Creates `requiredSpace` bytes of free space immediately before `index`
282+
/// Creates `requiredSpace` bytes of free space immediately before `index`.
275283
/// e.g. given [a, b, c, d, e, f, g, h, i, j] and calling this function with (before: 4, requiredSpace: 2) would result in
276284
/// [a, b, c, d, 0, 0, e, f, g, h, i, j]
277-
/// 2 extra bytes of space were created before index 4 (the letter e)
278-
/// The total bytes written will be equal to `requiredSpace`, and the writer index will be moved accordingly
285+
/// 2 extra bytes of space were created before index 4 (the letter e).
286+
/// The total bytes written will be equal to `requiredSpace`, and the writer index will be moved accordingly.
279287
@usableFromInline
280288
mutating func _createSpace(before index: Int, requiredSpace: Int) {
281289
let bytesToMove = self.writerIndex - index
@@ -294,8 +302,8 @@ extension ByteBuffer {
294302
}
295303
}
296304

297-
/// Move the `size` bytes starting from `source` to `destination`
298-
/// `source` and `destination` must both be within the writable range
305+
/// Move the `size` bytes starting from `source` to `destination`.
306+
/// `source` and `destination` must both be within the writable range.
299307
@usableFromInline
300308
mutating func _moveBytes(from source: Int, to destination: Int, size: Int) {
301309
precondition(source >= self.readerIndex && destination < self.writerIndex && source >= destination)

Sources/NIOCore/ByteBuffer-quicBinaryEncodingStrategy.swift

+18-21
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
extension ByteBuffer {
16-
public struct QUICBinaryEncodingStrategy: BinaryIntegerEncodingStrategy {
17-
public var reservedSpace: Int
16+
public struct QUICBinaryEncodingStrategy: NIOBinaryIntegerEncodingStrategy {
17+
public var reservedCapacityForInteger: Int
1818

1919
@inlinable
20-
public init(reservedSpace: Int) {
20+
public init(reservedCapacity: Int) {
2121
precondition(
22-
reservedSpace == 0
23-
|| reservedSpace == 1
24-
|| reservedSpace == 2
25-
|| reservedSpace == 4
26-
|| reservedSpace == 8
22+
reservedCapacity == 0
23+
|| reservedCapacity == 1
24+
|| reservedCapacity == 2
25+
|| reservedCapacity == 4
26+
|| reservedCapacity == 8
2727
)
28-
self.reservedSpace = reservedSpace
28+
self.reservedCapacityForInteger = reservedCapacity
2929
}
3030

3131
@inlinable
@@ -83,25 +83,22 @@ extension ByteBuffer {
8383
_ integer: IntegerType,
8484
to buffer: inout ByteBuffer
8585
) -> Int {
86-
self.writeIntegerWithReservedSpace(integer, reservedSpace: 0, to: &buffer)
86+
self.writeIntegerWithReservedCapacity(integer, reservedCapacity: 0, to: &buffer)
8787
}
8888

8989
@inlinable
90-
public var reservedSpaceForInteger: Int { 4 }
91-
92-
@inlinable
93-
public func writeIntegerWithReservedSpace<IntegerType: FixedWidthInteger>(
90+
public func writeIntegerWithReservedCapacity<IntegerType: FixedWidthInteger>(
9491
_ integer: IntegerType,
95-
reservedSpace: Int,
92+
reservedCapacity: Int,
9693
to buffer: inout ByteBuffer
9794
) -> Int {
98-
if reservedSpace > 8 {
95+
if reservedCapacity > 8 {
9996
fatalError("Reserved space for QUIC encoded integer must be at most 8 bytes")
10097
}
10198
// Use more space than necessary in order to fill the reserved space
10299
// This will avoid a memmove
103100
// If the needed space is more than the reserved, we can't avoid the move
104-
switch max(reservedSpace, self.bytesNeededForInteger(integer)) {
101+
switch max(reservedCapacity, self.bytesNeededForInteger(integer)) {
105102
case 1:
106103
// Easy, store the value. The top two bits are 0 so we don't need to do any masking.
107104
return buffer.writeInteger(UInt8(truncatingIfNeeded: integer))
@@ -124,12 +121,12 @@ extension ByteBuffer {
124121
}
125122
}
126123

127-
extension BinaryIntegerEncodingStrategy where Self == ByteBuffer.QUICBinaryEncodingStrategy {
124+
extension NIOBinaryIntegerEncodingStrategy where Self == ByteBuffer.QUICBinaryEncodingStrategy {
128125
@inlinable
129-
public static func quic(reservedSpace: Int) -> ByteBuffer.QUICBinaryEncodingStrategy {
130-
ByteBuffer.QUICBinaryEncodingStrategy(reservedSpace: reservedSpace)
126+
public static func quic(reservedCapacity: Int) -> ByteBuffer.QUICBinaryEncodingStrategy {
127+
ByteBuffer.QUICBinaryEncodingStrategy(reservedCapacity: reservedCapacity)
131128
}
132129

133130
@inlinable
134-
public static var quic: ByteBuffer.QUICBinaryEncodingStrategy { .quic(reservedSpace: 4) }
131+
public static var quic: ByteBuffer.QUICBinaryEncodingStrategy { .quic(reservedCapacity: 4) }
135132
}

0 commit comments

Comments
 (0)