Do not use @inline(__always)
Use @inlinable instead, or let the compiler be smart. Also make more public things @inlinable for speedz.
This commit is contained in:
parent
d1119047d0
commit
ad70fc06ca
|
@ -1,6 +1,5 @@
|
|||
# SwiftNIO Redis
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
|
|
@ -133,7 +133,7 @@ open class RESPChannelHandler : ChannelDuplexHandler {
|
|||
context.write(wrapOutboundOut(out), promise: promise)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
@inlinable
|
||||
final func encode<S: Collection>(simpleString bytes: S,
|
||||
out: inout ByteBuffer)
|
||||
where S.Element == UInt8
|
||||
|
@ -143,7 +143,7 @@ open class RESPChannelHandler : ChannelDuplexHandler {
|
|||
out.writeBytes(eol)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
@inlinable
|
||||
final func encode(simpleString bytes: ByteBuffer, out: inout ByteBuffer) {
|
||||
var s = bytes
|
||||
out.writeInteger(UInt8(43)) // +
|
||||
|
@ -151,7 +151,7 @@ open class RESPChannelHandler : ChannelDuplexHandler {
|
|||
out.writeBytes(eol)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
@inlinable
|
||||
final func encode(bulkString bytes: ByteBuffer?, out: inout ByteBuffer) {
|
||||
if var s = bytes {
|
||||
out.writeInteger(UInt8(36)) // $
|
||||
|
@ -165,7 +165,7 @@ open class RESPChannelHandler : ChannelDuplexHandler {
|
|||
}
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
@inlinable
|
||||
final func encode<S: Collection>(bulkString bytes: S?,
|
||||
out: inout ByteBuffer)
|
||||
where S.Element == UInt8
|
||||
|
@ -182,14 +182,14 @@ open class RESPChannelHandler : ChannelDuplexHandler {
|
|||
}
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
@inlinable
|
||||
final func encode(integer i: Int, out: inout ByteBuffer) {
|
||||
out.writeInteger(UInt8(58)) // :
|
||||
out.write(integerAsString : i)
|
||||
out.writeBytes(eol)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
@inlinable
|
||||
final func encode(error: RESPError, out: inout ByteBuffer) {
|
||||
out.writeInteger(UInt8(45)) // -
|
||||
out.writeString(error.code)
|
||||
|
@ -241,8 +241,10 @@ open class RESPChannelHandler : ChannelDuplexHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private let eol : ContiguousArray<UInt8> = [ 13, 10 ] // \r\n
|
||||
private let nilString : ContiguousArray<UInt8> = [ 36, 45, 49, 13, 10 ] // $-1\r\n
|
||||
@usableFromInline
|
||||
let eol : ContiguousArray<UInt8> = [ 13, 10 ] // \r\n
|
||||
@usableFromInline
|
||||
let nilString : ContiguousArray<UInt8> = [ 36, 45, 49, 13, 10 ] // $-1\r\n
|
||||
private let nilArray : ContiguousArray<UInt8> = [ 42, 45, 49, 13, 10 ] // *-1\r\n
|
||||
|
||||
fileprivate enum ConstantBuffers {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// This source file is part of the swift-nio-redis open source project
|
||||
//
|
||||
// Copyright (c) 2018 ZeeZide GmbH. and the swift-nio-redis project authors
|
||||
// Copyright (c) 2018-2021 ZeeZide GmbH. and the swift-nio-redis project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
|
@ -18,68 +18,58 @@ import struct NIO.ByteBuffer
|
|||
public protocol RESPEncodable {
|
||||
|
||||
func toRESPValue() -> RESPValue
|
||||
|
||||
}
|
||||
|
||||
extension RESPValue : RESPEncodable {
|
||||
|
||||
public func toRESPValue() -> RESPValue {
|
||||
return self
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue { return self }
|
||||
}
|
||||
|
||||
extension RESPError : RESPEncodable {
|
||||
|
||||
public func toRESPValue() -> RESPValue {
|
||||
return .error(self)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue { return .error(self) }
|
||||
}
|
||||
|
||||
extension Int : RESPEncodable {
|
||||
|
||||
public func toRESPValue() -> RESPValue {
|
||||
return .integer(self)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue { return .integer(self) }
|
||||
}
|
||||
|
||||
extension Bool : RESPEncodable {
|
||||
|
||||
public func toRESPValue() -> RESPValue {
|
||||
return .integer(self ? 1 : 0)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue { return .integer(self ? 1 : 0) }
|
||||
}
|
||||
|
||||
extension String : RESPEncodable {
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue {
|
||||
return .bulkString(self.utf8.asByteBuffer)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Data : RESPEncodable {
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue {
|
||||
return .bulkString(self.asByteBuffer)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ByteBuffer : RESPEncodable {
|
||||
|
||||
public func toRESPValue() -> RESPValue {
|
||||
return .bulkString(self)
|
||||
}
|
||||
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue { return .bulkString(self) }
|
||||
}
|
||||
|
||||
|
||||
extension Array where Element: RESPEncodable {
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue {
|
||||
let arrayOfRedisValues = self.map { $0.toRESPValue() }
|
||||
return .array(ContiguousArray(arrayOfRedisValues))
|
||||
|
@ -89,6 +79,7 @@ extension Array where Element: RESPEncodable {
|
|||
|
||||
extension Array: RESPEncodable {
|
||||
|
||||
@inlinable
|
||||
public func toRESPValue() -> RESPValue {
|
||||
let array : [ RESPValue ] = self.map { v in
|
||||
if let rv = (v as? RESPEncodable) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// This source file is part of the swift-nio-redis open source project
|
||||
//
|
||||
// Copyright (c) 2018-2020 ZeeZide GmbH. and the swift-nio-redis project authors
|
||||
// Copyright (c) 2018-2021 ZeeZide GmbH. and the swift-nio-redis project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
|
@ -35,7 +35,6 @@ public struct RESPParser {
|
|||
let count = bp.count
|
||||
var i = 0
|
||||
|
||||
@inline(__always)
|
||||
func doSkipNL() {
|
||||
if i >= count {
|
||||
overflowSkipNL = true
|
||||
|
@ -238,7 +237,6 @@ public struct RESPParser {
|
|||
|
||||
// MARK: - Parsing
|
||||
|
||||
@inline(__always)
|
||||
private mutating func pushArrayContext(expectedCount: Int) {
|
||||
if ctxIndex == ctxCapacity {
|
||||
for _ in 0..<4 {
|
||||
|
@ -252,7 +250,6 @@ public struct RESPParser {
|
|||
arrayContextBuffer[ctxIndex].values.reserveCapacity(expectedCount)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
private mutating func decoded(value: RESPValue, yield: Yield) {
|
||||
if ctxIndex < 0 {
|
||||
return yield(value)
|
||||
|
@ -313,11 +310,8 @@ public struct RESPParser {
|
|||
values.reserveCapacity(expectedCount + 1)
|
||||
}
|
||||
|
||||
var isDone : Bool {
|
||||
@inline(__always) get { return expectedCount <= values.count }
|
||||
}
|
||||
var isDone : Bool { return expectedCount <= values.count }
|
||||
|
||||
@inline(__always)
|
||||
mutating func append(value v: RESPValue) -> Bool {
|
||||
assert(!isDone, "attempt to add to a context which is not TL or done")
|
||||
values.append(v)
|
||||
|
@ -331,5 +325,4 @@ public struct RESPParser {
|
|||
private var countValue = 0
|
||||
private var overflowSkipNL = false
|
||||
private var overflowBuffer : ByteBuffer?
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// This source file is part of the swift-nio-redis open source project
|
||||
//
|
||||
// Copyright (c) 2018-2020 ZeeZide GmbH. and the swift-nio-redis project authors
|
||||
// Copyright (c) 2018-2021 ZeeZide GmbH. and the swift-nio-redis project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
|
@ -17,6 +17,7 @@ import class NIO.EventLoopFuture
|
|||
|
||||
public extension ChannelPipeline {
|
||||
|
||||
@inlinable
|
||||
func configureRedisPipeline(first : Bool = false,
|
||||
name : String = "de.zeezide.nio.RESP")
|
||||
-> EventLoopFuture<Void>
|
||||
|
|
|
@ -49,14 +49,14 @@ public struct RESPError : Error, CustomStringConvertible {
|
|||
|
||||
// MARK: - Initializers
|
||||
|
||||
fileprivate let sharedAllocator = ByteBufferAllocator()
|
||||
@usableFromInline let sharedAllocator = ByteBufferAllocator()
|
||||
|
||||
public extension RESPValue {
|
||||
|
||||
init(_ v: Int) {
|
||||
self = .integer(v)
|
||||
}
|
||||
@inlinable
|
||||
init(_ v: Int) { self = .integer(v) }
|
||||
|
||||
@inlinable
|
||||
init(bulkString s: String?) {
|
||||
if let s = s {
|
||||
let utf8 = s.utf8
|
||||
|
@ -68,12 +68,14 @@ public extension RESPValue {
|
|||
self = .bulkString(nil)
|
||||
}
|
||||
}
|
||||
@inlinable
|
||||
init(bulkString s: Data) {
|
||||
var buffer = sharedAllocator.buffer(capacity: s.count)
|
||||
buffer.writeBytes(s)
|
||||
self = .bulkString(buffer)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
init(bulkString s: Int) {
|
||||
let s = String(s)
|
||||
let utf8 = s.utf8
|
||||
|
@ -82,45 +84,48 @@ public extension RESPValue {
|
|||
self = .bulkString(buffer)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
init(simpleString s: String) {
|
||||
self = .simpleString(s.utf8.asByteBuffer)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
init(errorCode code: String, message: String? = nil) {
|
||||
self = .error(RESPError(code: code, message: message ?? "Failed: \(code)"))
|
||||
}
|
||||
|
||||
@inlinable
|
||||
init<T: Sequence>(array: T) where T.Element == RESPValue {
|
||||
self = .array(ContiguousArray(array))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public extension RESPValue { // MARK: - Content Accessors
|
||||
|
||||
@inlinable
|
||||
var byteBuffer : ByteBuffer? {
|
||||
@inline(__always)
|
||||
get {
|
||||
switch self {
|
||||
case .simpleString(let cs), .bulkString(.some(let cs)): return cs
|
||||
default: return nil
|
||||
}
|
||||
switch self {
|
||||
case .simpleString(let cs), .bulkString(.some(let cs)): return cs
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
@inlinable
|
||||
var stringValue : String? {
|
||||
@inline(__always)
|
||||
get {
|
||||
switch self {
|
||||
case .simpleString(let cs), .bulkString(.some(let cs)):
|
||||
return cs.getString(at: cs.readerIndex, length: cs.readableBytes)
|
||||
|
||||
case .integer(let i):
|
||||
return String(i)
|
||||
|
||||
default: return nil
|
||||
}
|
||||
switch self {
|
||||
case .simpleString(let cs), .bulkString(.some(let cs)):
|
||||
return cs.getString(at: cs.readerIndex, length: cs.readableBytes)
|
||||
|
||||
case .integer(let i):
|
||||
return String(i)
|
||||
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
@inlinable
|
||||
var dataValue : Data? {
|
||||
@inline(__always)
|
||||
get {
|
||||
switch self {
|
||||
case .simpleString(let cs), .bulkString(.some(let cs)):
|
||||
|
@ -131,12 +136,10 @@ public extension RESPValue {
|
|||
}
|
||||
}
|
||||
|
||||
var keyValue : Data? {
|
||||
@inline(__always)
|
||||
get { return self.dataValue }
|
||||
}
|
||||
@inlinable
|
||||
var keyValue : Data? { return self.dataValue }
|
||||
|
||||
@inline(__always)
|
||||
@inlinable
|
||||
func withKeyValue(_ cb: ( Data? ) throws -> Void) rethrows {
|
||||
// SR-7378
|
||||
switch self {
|
||||
|
@ -154,28 +157,27 @@ public extension RESPValue {
|
|||
}
|
||||
}
|
||||
|
||||
@inlinable
|
||||
var intValue : Int? {
|
||||
@inline(__always)
|
||||
get {
|
||||
switch self {
|
||||
case .integer(let i):
|
||||
return i
|
||||
|
||||
case .simpleString(let cs), .bulkString(.some(let cs)):
|
||||
// PERF: inline atoi instead of constructing a string!
|
||||
guard let s = cs.getString(at: cs.readerIndex,
|
||||
length: cs.readableBytes) else {
|
||||
return nil
|
||||
}
|
||||
return Int(s)
|
||||
|
||||
default:
|
||||
switch self {
|
||||
case .integer(let i):
|
||||
return i
|
||||
|
||||
case .simpleString(let cs), .bulkString(.some(let cs)):
|
||||
// PERF: inline atoi instead of constructing a string!
|
||||
guard let s = cs.getString(at: cs.readerIndex,
|
||||
length: cs.readableBytes) else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return Int(s)
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func ==(lhs: RESPValue, rhs: String) -> Bool {
|
||||
switch lhs {
|
||||
case .simpleString, .bulkString:
|
||||
|
@ -191,6 +193,8 @@ public func ==(lhs: RESPValue, rhs: String) -> Bool {
|
|||
// MARK: - Parse Literals
|
||||
|
||||
extension RESPValue : ExpressibleByIntegerLiteral {
|
||||
|
||||
@inlinable
|
||||
public init(integerLiteral value: IntegerLiteralType) {
|
||||
self = .integer(value)
|
||||
}
|
||||
|
@ -199,6 +203,8 @@ extension RESPValue : ExpressibleByIntegerLiteral {
|
|||
import NIOFoundationCompat
|
||||
|
||||
extension Data {
|
||||
|
||||
@usableFromInline
|
||||
var asByteBuffer : ByteBuffer {
|
||||
var bb = sharedAllocator.buffer(capacity: count)
|
||||
bb.writeBytes(self)
|
||||
|
@ -207,6 +213,8 @@ extension Data {
|
|||
}
|
||||
|
||||
extension String.UTF8View {
|
||||
|
||||
@usableFromInline
|
||||
var asByteBuffer : ByteBuffer {
|
||||
var bb = sharedAllocator.buffer(capacity: count)
|
||||
bb.writeBytes(self)
|
||||
|
@ -216,20 +224,23 @@ extension String.UTF8View {
|
|||
|
||||
extension RESPValue : ExpressibleByStringLiteral {
|
||||
|
||||
@inlinable
|
||||
public init(stringLiteral value: String) {
|
||||
self = .bulkString(value.utf8.asByteBuffer)
|
||||
}
|
||||
@inlinable
|
||||
public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
|
||||
self = .bulkString(value.utf8.asByteBuffer)
|
||||
}
|
||||
@inlinable
|
||||
public init(unicodeScalarLiteral value: StringLiteralType) {
|
||||
self = .bulkString(value.utf8.asByteBuffer)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension RESPValue : CustomStringConvertible {
|
||||
|
||||
@inlinable
|
||||
public var description : String {
|
||||
switch self {
|
||||
case .simpleString(let cs): return stringValue ?? "\(cs)"
|
||||
|
@ -249,12 +260,14 @@ extension RESPValue : CustomStringConvertible {
|
|||
extension String {
|
||||
// FIXME: we can probably do this in the buffer
|
||||
|
||||
@inlinable
|
||||
static func decode<I: Collection>(utf8 ba: I) -> String?
|
||||
where I.Iterator.Element == UInt8
|
||||
{
|
||||
return decode(units: ba, decoder: UTF8())
|
||||
}
|
||||
|
||||
@inlinable
|
||||
static func decode<Codec: UnicodeCodec, I: Collection>
|
||||
(units b: I, decoder d: Codec) -> String?
|
||||
where I.Iterator.Element == Codec.CodeUnit
|
||||
|
|
Loading…
Reference in New Issue