mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-01 19:58:15 +00:00
[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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user