Skip to content

Commit 9fe1bce

Browse files
committed
itoa
1 parent 9011f20 commit 9fe1bce

File tree

1 file changed

+51
-13
lines changed

1 file changed

+51
-13
lines changed

Sources/NIORedis/RESPChannelHandler.swift

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

0 commit comments

Comments
 (0)