summaryrefslogtreecommitdiff
path: root/swift
diff options
context:
space:
mode:
authormustiikhalil <mustii@mmk.one>2020-06-11 18:53:32 +0300
committerGitHub <noreply@github.com>2020-06-11 08:53:32 -0700
commit7cb4762a61fc6ac3543558e7e7836985bffa07fe (patch)
tree860790a097b1416f63882fc3b381c216f932e34e /swift
parent4e45f7c9e8da64a9601eeba1231079c3ce0a6dc2 (diff)
downloadflatbuffers-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.swift44
-rw-r--r--swift/Sources/FlatBuffers/FlatBufferBuilder.swift7
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)