@@ -193,6 +193,7 @@ public final class EmbeddedEventLoop: EventLoop {
193
193
}
194
194
}
195
195
196
+ @usableFromInline
196
197
class EmbeddedChannelCore : ChannelCore {
197
198
var isOpen : Bool = true
198
199
var isActive : Bool = false
@@ -217,23 +218,29 @@ class EmbeddedChannelCore: ChannelCore {
217
218
}
218
219
219
220
/// Contains the flushed items that went into the `Channel` (and on a regular channel would have hit the network).
220
- var outboundBuffer : [ NIOAny ] = [ ]
221
+ @usableFromInline
222
+ var outboundBuffer : CircularBuffer < NIOAny > = CircularBuffer ( )
221
223
222
224
/// Contains the unflushed items that went into the `Channel`
223
- var pendingOutboundBuffer : [ ( NIOAny , EventLoopPromise < Void > ? ) ] = [ ]
225
+ @usableFromInline
226
+ var pendingOutboundBuffer : MarkedCircularBuffer < ( NIOAny , EventLoopPromise < Void > ? ) > = MarkedCircularBuffer ( initialCapacity: 16 )
224
227
225
228
/// Contains the items that travelled the `ChannelPipeline` all the way and hit the tail channel handler. On a
226
229
/// regular `Channel` these items would be lost.
227
- var inboundBuffer : [ NIOAny ] = [ ]
230
+ @usableFromInline
231
+ var inboundBuffer : CircularBuffer < NIOAny > = CircularBuffer ( )
228
232
233
+ @usableFromInline
229
234
func localAddress0( ) throws -> SocketAddress {
230
235
throw ChannelError . operationUnsupported
231
236
}
232
237
238
+ @usableFromInline
233
239
func remoteAddress0( ) throws -> SocketAddress {
234
240
throw ChannelError . operationUnsupported
235
241
}
236
242
243
+ @usableFromInline
237
244
func close0( error: Error , mode: CloseMode , promise: EventLoopPromise < Void > ? ) {
238
245
guard self . isOpen else {
239
246
promise? . fail ( ChannelError . alreadyClosed)
@@ -254,43 +261,47 @@ class EmbeddedChannelCore: ChannelCore {
254
261
}
255
262
}
256
263
264
+ @usableFromInline
257
265
func bind0( to address: SocketAddress , promise: EventLoopPromise < Void > ? ) {
258
266
promise? . succeed ( ( ) )
259
267
}
260
268
269
+ @usableFromInline
261
270
func connect0( to address: SocketAddress , promise: EventLoopPromise < Void > ? ) {
262
271
isActive = true
263
272
promise? . succeed ( ( ) )
264
273
pipeline. fireChannelActive0 ( )
265
274
}
266
275
276
+ @usableFromInline
267
277
func register0( promise: EventLoopPromise < Void > ? ) {
268
278
promise? . succeed ( ( ) )
269
279
pipeline. fireChannelRegistered0 ( )
270
280
}
271
281
282
+ @usableFromInline
272
283
func registerAlreadyConfigured0( promise: EventLoopPromise < Void > ? ) {
273
284
isActive = true
274
285
register0 ( promise: promise)
275
286
pipeline. fireChannelActive0 ( )
276
287
}
277
288
289
+ @usableFromInline
278
290
func write0( _ data: NIOAny , promise: EventLoopPromise < Void > ? ) {
279
291
self . pendingOutboundBuffer. append ( ( data, promise) )
280
292
}
281
293
294
+ @usableFromInline
282
295
func flush0( ) {
283
- let pendings = self . pendingOutboundBuffer
284
- // removeAll(keepingCapacity:) is strictly more expensive than doing this, see
285
- // https://bugs.swift.org/browse/SR-13923.
286
- self . pendingOutboundBuffer = [ ]
287
- self . pendingOutboundBuffer. reserveCapacity ( pendings. capacity)
288
- for dataAndPromise in pendings {
296
+ self . pendingOutboundBuffer. mark ( )
297
+
298
+ while self . pendingOutboundBuffer. hasMark, let dataAndPromise = self . pendingOutboundBuffer. popFirst ( ) {
289
299
self . addToBuffer ( buffer: & self . outboundBuffer, data: dataAndPromise. 0 )
290
300
dataAndPromise. 1 ? . succeed ( ( ) )
291
301
}
292
302
}
293
303
304
+ @usableFromInline
294
305
func read0( ) {
295
306
// NOOP
296
307
}
@@ -299,6 +310,7 @@ class EmbeddedChannelCore: ChannelCore {
299
310
promise? . fail ( ChannelError . operationUnsupported)
300
311
}
301
312
313
+ @usableFromInline
302
314
func channelRead0( _ data: NIOAny ) {
303
315
addToBuffer ( buffer: & inboundBuffer, data: data)
304
316
}
@@ -309,7 +321,7 @@ class EmbeddedChannelCore: ChannelCore {
309
321
}
310
322
}
311
323
312
- private func addToBuffer< T> ( buffer: inout [ T ] , data: T ) {
324
+ private func addToBuffer< T> ( buffer: inout CircularBuffer < T > , data: T ) {
313
325
buffer. append ( data)
314
326
}
315
327
}
@@ -409,6 +421,11 @@ public final class EmbeddedChannel: Channel {
409
421
/// The type of the actual first element.
410
422
public let actual : Any . Type
411
423
424
+ public init ( expected: Any . Type , actual: Any . Type ) {
425
+ self . expected = expected
426
+ self . actual = actual
427
+ }
428
+
412
429
public static func == ( lhs: WrongTypeError , rhs: WrongTypeError ) -> Bool {
413
430
return lhs. expected == rhs. expected && lhs. actual == rhs. actual
414
431
}
@@ -424,7 +441,8 @@ public final class EmbeddedChannel: Channel {
424
441
/// - see: `Channel.closeFuture`
425
442
public var closeFuture : EventLoopFuture < Void > { return channelcore. closePromise. futureResult }
426
443
427
- private lazy var channelcore : EmbeddedChannelCore = EmbeddedChannelCore ( pipeline: self . _pipeline, eventLoop: self . eventLoop)
444
+ @usableFromInline
445
+ /*private but usableFromInline */ lazy var channelcore : EmbeddedChannelCore = EmbeddedChannelCore ( pipeline: self . _pipeline, eventLoop: self . eventLoop)
428
446
429
447
/// - see: `Channel._channelCore`
430
448
public var _channelCore : ChannelCore {
@@ -464,8 +482,8 @@ public final class EmbeddedChannel: Channel {
464
482
if c. outboundBuffer. isEmpty && c. inboundBuffer. isEmpty && c. pendingOutboundBuffer. isEmpty {
465
483
return . clean
466
484
} else {
467
- return . leftOvers( inbound: c. inboundBuffer,
468
- outbound: c. outboundBuffer,
485
+ return . leftOvers( inbound: Array ( c. inboundBuffer) ,
486
+ outbound: Array ( c. outboundBuffer) ,
469
487
pendingOutbound: c. pendingOutboundBuffer. map { $0. 0 } )
470
488
}
471
489
}
@@ -518,8 +536,9 @@ public final class EmbeddedChannel: Channel {
518
536
/// - note: Outbound events travel the `ChannelPipeline` _back to front_.
519
537
/// - note: `EmbeddedChannel.writeOutbound` will `write` data through the `ChannelPipeline`, starting with last
520
538
/// `ChannelHandler`.
539
+ @inlinable
521
540
public func readOutbound< T> ( as type: T . Type = T . self) throws -> T ? {
522
- return try readFromBuffer ( buffer: & channelcore. outboundBuffer)
541
+ return try _readFromBuffer ( buffer: & channelcore. outboundBuffer)
523
542
}
524
543
525
544
/// If available, this method reads one element of type `T` out of the `EmbeddedChannel`'s inbound buffer. If the
@@ -532,8 +551,9 @@ public final class EmbeddedChannel: Channel {
532
551
/// `ChannelHandlerContext.fireChannelRead`) or implicitly by not implementing `channelRead`.
533
552
///
534
553
/// - note: `EmbeddedChannel.writeInbound` will fire data through the `ChannelPipeline` using `fireChannelRead`.
554
+ @inlinable
535
555
public func readInbound< T> ( as type: T . Type = T . self) throws -> T ? {
536
- return try readFromBuffer ( buffer: & channelcore. inboundBuffer)
556
+ return try _readFromBuffer ( buffer: & channelcore. inboundBuffer)
537
557
}
538
558
539
559
/// Sends an inbound `channelRead` event followed by a `channelReadComplete` event through the `ChannelPipeline`.
@@ -545,11 +565,12 @@ public final class EmbeddedChannel: Channel {
545
565
/// - data: The data to fire through the pipeline.
546
566
/// - returns: The state of the inbound buffer which contains all the events that travelled the `ChannelPipeline`
547
567
// all the way.
568
+ @inlinable
548
569
@discardableResult public func writeInbound< T> ( _ data: T ) throws -> BufferState {
549
570
pipeline. fireChannelRead ( NIOAny ( data) )
550
571
pipeline. fireChannelReadComplete ( )
551
572
try throwIfErrorCaught ( )
552
- return self . channelcore. inboundBuffer. isEmpty ? . empty : . full( self . channelcore. inboundBuffer)
573
+ return self . channelcore. inboundBuffer. isEmpty ? . empty : . full( Array ( self . channelcore. inboundBuffer) )
553
574
}
554
575
555
576
/// Sends an outbound `writeAndFlush` event through the `ChannelPipeline`.
@@ -562,9 +583,10 @@ public final class EmbeddedChannel: Channel {
562
583
/// - data: The data to fire through the pipeline.
563
584
/// - returns: The state of the outbound buffer which contains all the events that travelled the `ChannelPipeline`
564
585
// all the way.
586
+ @inlinable
565
587
@discardableResult public func writeOutbound< T> ( _ data: T ) throws -> BufferState {
566
588
try writeAndFlush ( NIOAny ( data) ) . wait ( )
567
- return self . channelcore. outboundBuffer. isEmpty ? . empty : . full( self . channelcore. outboundBuffer)
589
+ return self . channelcore. outboundBuffer. isEmpty ? . empty : . full( Array ( self . channelcore. outboundBuffer) )
568
590
}
569
591
570
592
/// This method will throw the error that is stored in the `EmbeddedChannel` if any.
@@ -577,7 +599,8 @@ public final class EmbeddedChannel: Channel {
577
599
}
578
600
}
579
601
580
- private func readFromBuffer< T> ( buffer: inout [ NIOAny ] ) throws -> T ? {
602
+ @inlinable
603
+ func _readFromBuffer< T> ( buffer: inout CircularBuffer < NIOAny > ) throws -> T ? {
581
604
if buffer. isEmpty {
582
605
return nil
583
606
}
0 commit comments