Commit 6a012634 authored by Ben Harper's avatar Ben Harper Committed by Wouter van Oortmerssen

Add CreateByteVector function to Go's builder

This function gets around the inefficiency of populating a [ubyte] vector
byte by byte. Since ubyte vectors are probably the most commonly used type
of generic byte buffer, this seems like a worthwhile thing to create a
fast path for.

Benchmarks show a 6x improvement in throughput on x64.

There is a new test verifying the functionality of the function.

Change-Id: I82e0228ae0f815dd7ea89bf168b8c1925f3ce0d7
parent 44644052
...@@ -259,6 +259,18 @@ func (b *Builder) CreateString(s string) UOffsetT { ...@@ -259,6 +259,18 @@ func (b *Builder) CreateString(s string) UOffsetT {
return b.EndVector(len(x)) return b.EndVector(len(x))
} }
// CreateByteVector writes a ubyte vector
func (b *Builder) CreateByteVector(v []byte) UOffsetT {
b.Prep(int(SizeUOffsetT), len(v)*SizeByte)
l := UOffsetT(len(v))
b.head -= l
copy(b.Bytes[b.head:b.head+l], v)
return b.EndVector(len(v))
}
func (b *Builder) notNested() { func (b *Builder) notNested() {
// Check that no other objects are being built while making this // Check that no other objects are being built while making this
// object. If not, panic: // object. If not, panic:
......
...@@ -90,6 +90,9 @@ func TestAll(t *testing.T) { ...@@ -90,6 +90,9 @@ func TestAll(t *testing.T) {
// some sanity checks: // some sanity checks:
CheckDocExample(generated, off, t.Fatalf) CheckDocExample(generated, off, t.Fatalf)
// Check Builder.CreateByteVector
CheckCreateByteVector(t.Fatalf)
// If the filename of the FlatBuffers file generated by the Java test // If the filename of the FlatBuffers file generated by the Java test
// is given, check that Go code can read it, and that Go code // is given, check that Go code can read it, and that Go code
// generates an identical buffer when used to create the example data: // generates an identical buffer when used to create the example data:
...@@ -1080,6 +1083,25 @@ func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ... ...@@ -1080,6 +1083,25 @@ func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...
_ = example.MonsterEnd(builder) _ = example.MonsterEnd(builder)
} }
func CheckCreateByteVector(fail func(string, ...interface{})) {
raw := [30]byte{}
for i := 0; i < len(raw); i++ {
raw[i] = byte(i)
}
for size := 0; size < len(raw); size++ {
b1 := flatbuffers.NewBuilder(0)
b2 := flatbuffers.NewBuilder(0)
b1.StartVector(1, size, 1)
for i := size - 1; i >= 0; i-- {
b1.PrependByte(raw[i])
}
b1.EndVector(size)
b2.CreateByteVector(raw[:size])
CheckByteEquality(b1.Bytes, b2.Bytes, fail)
}
}
// Include simple random number generator to ensure results will be the // Include simple random number generator to ensure results will be the
// same cross platform. // same cross platform.
// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator // http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment