Skip to content

Commit a904c4b

Browse files
committed
Merge branch 'develop'
2 parents 7339dbd + dae92a7 commit a904c4b

File tree

2 files changed

+72
-25
lines changed

2 files changed

+72
-25
lines changed

Sources/NIORedis/RESPChannelHandler.swift

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ open class RedisChannelHandler : ChannelInboundHandler,
121121
let count = array.count
122122
out = ctx.channel.allocator.buffer(capacity: 1 + 4 + 3 + count * 32)
123123
out.write(integer: UInt8(42)) // *
124-
out.write(string: String(array.count, radix: 10))
124+
out.write(integerAsString: array.count)
125125
out.write(bytes: eol)
126126
for item in array {
127127
encode(ctx: ctx, data: item, level: 1, out: &out)
@@ -229,7 +229,7 @@ open class RedisChannelHandler : ChannelInboundHandler,
229229
case .array(let array): // *
230230
if let array = array {
231231
out.write(integer: UInt8(42)) // *
232-
out.write(string: String(array.count, radix: 10))
232+
out.write(integerAsString: array.count)
233233
out.write(bytes: eol)
234234
for item in array {
235235
encode(ctx: ctx, data: item, level: level + 1, out: &out)
@@ -264,31 +264,69 @@ fileprivate enum ConstantBuffers {
264264
}()
265265
}
266266

267+
fileprivate extension BinaryInteger {
268+
269+
var numberOfDecimalDigits : Int {
270+
@inline(__always) get {
271+
var value = self
272+
var count = 0
273+
274+
repeat {
275+
value /= 10
276+
count += 1
277+
}
278+
while value != 0
279+
280+
return count
281+
}
282+
}
283+
}
284+
267285
extension ByteBuffer {
268286

269287
@discardableResult
270-
public mutating func write<T: FixedWidthInteger>(integerAsString integer: T,
271-
as: T.Type = T.self) -> Int
288+
public mutating func write<T: SignedInteger>(integerAsString integer: T,
289+
as: T.Type = T.self) -> Int
272290
{
273291
let bytesWritten = set(integerAsString: integer, at: self.writerIndex)
274292
moveWriterIndex(forwardBy: bytesWritten)
275293
return Int(bytesWritten)
276294
}
277295

278296
@discardableResult
279-
public mutating func set<T: FixedWidthInteger>(integerAsString integer: T,
280-
at index: Int,
281-
as: T.Type = T.self) -> Int
297+
public mutating func set<T: SignedInteger>(integerAsString integer: T,
298+
at index: Int,
299+
as: T.Type = T.self) -> Int
282300
{
283-
var value = integer
301+
let charCount = integer.numberOfDecimalDigits + (integer < 0 ? 1 : 0)
302+
let avail = capacity - index
284303

285-
#if true // slow, fixme
286-
let len = String(value, radix: 10)
287-
return set(string: len, at: index)! // TBD: why is this returning an Opt?
288-
#else
289-
return Swift.withUnsafeBytes(of: &value) { ptr in
290-
// TODO: do the itoa thing to make it fast
304+
if avail < charCount {
305+
changeCapacity(to: capacity + (charCount - avail))
306+
}
307+
308+
self.withVeryUnsafeBytes { rbpp in
309+
let mrbpp = UnsafeMutableRawBufferPointer(mutating: rbpp)
310+
let base = mrbpp.baseAddress!.assumingMemoryBound(to: UInt8.self)
311+
.advanced(by: index)
312+
var cursor = base.advanced(by: charCount)
313+
314+
let c0 : T = 48
315+
var negativeAbsoluteValue = integer < 0 ? integer : -integer
316+
repeat {
317+
cursor -= 1
318+
cursor.pointee = UInt8(c0 - (negativeAbsoluteValue % 10))
319+
negativeAbsoluteValue /= 10;
291320
}
292-
#endif
321+
while negativeAbsoluteValue != 0
322+
323+
if integer < 0 {
324+
cursor -= 1
325+
cursor.pointee = 45 // -
326+
}
327+
328+
}
329+
330+
return charCount
293331
}
294332
}

Sources/NIORedis/RESPValue.swift

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,6 @@
1515
import NIO
1616
import Foundation
1717

18-
public struct RESPError : Error {
19-
let code : String
20-
let message : String
21-
22-
public init(code: String = "ERR", message: String = "Generic Error") {
23-
self.code = code
24-
self.message = message
25-
}
26-
}
27-
2818
public enum RESPValue {
2919
case simpleString(ByteBuffer)
3020
case bulkString (ByteBuffer?)
@@ -33,6 +23,25 @@ public enum RESPValue {
3323
case error (RESPError)
3424
}
3525

26+
public struct RESPError : Error {
27+
28+
public init(code: String = "ERR", message: String = "Generic Error") {
29+
_storage = _Storage(code: code, message: message)
30+
}
31+
32+
public var code : String { return _storage.code }
33+
public var message : String { return _storage.message }
34+
35+
private final class _Storage {
36+
let code : String
37+
let message : String
38+
public init(code: String, message: String) {
39+
self.code = code
40+
self.message = message
41+
}
42+
}
43+
private let _storage : _Storage
44+
}
3645

3746
// MARK: - Initializers
3847

0 commit comments

Comments
 (0)