diff options
author | mustiikhalil <mustii@mmk.one> | 2020-06-11 18:53:32 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-11 08:53:32 -0700 |
commit | 7cb4762a61fc6ac3543558e7e7836985bffa07fe (patch) | |
tree | 860790a097b1416f63882fc3b381c216f932e34e /swift | |
parent | 4e45f7c9e8da64a9601eeba1231079c3ce0a6dc2 (diff) | |
download | flatbuffers-7cb4762a61fc6ac3543558e7e7836985bffa07fe.tar.gz flatbuffers-7cb4762a61fc6ac3543558e7e7836985bffa07fe.tar.bz2 flatbuffers-7cb4762a61fc6ac3543558e7e7836985bffa07fe.zip |
[Swift] Improving reallocation time by using memcpy and moving reallocation code to storage (#5960)
Removes stride
Use capacity - current size to initialize
Fixes memory leak
Updated test code for linux
Diffstat (limited to 'swift')
-rw-r--r-- | swift/Sources/FlatBuffers/ByteBuffer.swift | 44 | ||||
-rw-r--r-- | swift/Sources/FlatBuffers/FlatBufferBuilder.swift | 7 |
2 files changed, 26 insertions, 25 deletions
diff --git a/swift/Sources/FlatBuffers/ByteBuffer.swift b/swift/Sources/FlatBuffers/ByteBuffer.swift index 75ad0750..40b9cd7a 100644 --- a/swift/Sources/FlatBuffers/ByteBuffer.swift +++ b/swift/Sources/FlatBuffers/ByteBuffer.swift @@ -27,6 +27,24 @@ public struct ByteBuffer { func initalize(for size: Int) { memory.initializeMemory(as: UInt8.self, repeating: 0, count: size) } + + /// Reallocates the buffer incase the object to be written doesnt fit in the current buffer + /// - Parameter size: Size of the current object + @usableFromInline internal func reallocate(_ size: UInt32, writerSize: Int, alignment: Int) { + let currentWritingIndex = capacity - writerSize + while capacity <= writerSize + Int(size) { + capacity = capacity << 1 + } + + /// solution take from Apple-NIO + capacity = capacity.convertToPowerofTwo + + let newData = UnsafeMutableRawPointer.allocate(byteCount: capacity, alignment: alignment) + memset(newData, 0, capacity - writerSize) + memcpy(newData.advanced(by: capacity - writerSize), memory.advanced(by: currentWritingIndex), writerSize) + memory.deallocate() + memory = newData + } } @usableFromInline var _storage: Storage @@ -208,31 +226,13 @@ public struct ByteBuffer { /// - Parameter size: size of object @discardableResult @usableFromInline mutating func ensureSpace(size: UInt32) -> UInt32 { - if Int(size) + _writerSize > _storage.capacity { reallocate(size) } + if Int(size) + _writerSize > _storage.capacity { + _storage.reallocate(size, writerSize: _writerSize, alignment: alignment) + } assert(size < FlatBufferMaxSize, "Buffer can't grow beyond 2 Gigabytes") return size } - - /// Reallocates the buffer incase the object to be written doesnt fit in the current buffer - /// - Parameter size: Size of the current object - @usableFromInline mutating internal func reallocate(_ size: UInt32) { - let currentWritingIndex = writerIndex - while _storage.capacity <= _writerSize + Int(size) { - _storage.capacity = _storage.capacity << 1 - } - - /// solution take from Apple-NIO - _storage.capacity = _storage.capacity.convertToPowerofTwo - - let newData = UnsafeMutableRawPointer.allocate(byteCount: _storage.capacity, alignment: alignment) - newData.initializeMemory(as: UInt8.self, repeating: 0, count: _storage.capacity) - newData - .advanced(by: writerIndex) - .copyMemory(from: _storage.memory.advanced(by: currentWritingIndex), byteCount: _writerSize) - _storage.memory.deallocate() - _storage.memory = newData - } - + /// Clears the current size of the buffer mutating public func clearSize() { _writerSize = 0 diff --git a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift index cd2523f9..2501a397 100644 --- a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift +++ b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift @@ -135,7 +135,6 @@ public struct FlatBufferBuilder { return _bb.size } - /// Endtable will let the builder know that the object that's written to it is completed /// /// This would be called after all the elements are serialized, it will add the vtable into the buffer. @@ -156,8 +155,10 @@ public struct FlatBufferBuilder { _bb.write(value: VOffset(tableObjectSize), index: _bb.writerIndex + sizeofVoffset, direct: true) _bb.write(value: VOffset(_max), index: _bb.writerIndex, direct: true) - for index in stride(from: 0, to: _vtableStorage.writtenIndex, by: _vtableStorage.size) { - let loaded = _vtableStorage.load(at: index) + var itr = 0 + while itr < _vtableStorage.writtenIndex { + let loaded = _vtableStorage.load(at: itr) + itr += _vtableStorage.size guard loaded.offset != 0 else { continue } let _index = (_bb.writerIndex + Int(loaded.position)) _bb.write(value: VOffset(vTableOffset - loaded.offset), index: _index, direct: true) |