Skip to content

Commit

Permalink
Optimise reader and writing (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
nrwiersma authored Apr 29, 2019
1 parent 9000dad commit 68c9813
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 12 deletions.
2 changes: 1 addition & 1 deletion codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ type onePtrEncoder struct {
}

func (e *onePtrEncoder) Encode(ptr unsafe.Pointer, w *Writer) {
e.enc.Encode(unsafe.Pointer(&ptr), w)
e.enc.Encode(noescape(unsafe.Pointer(&ptr)), w)
}

func encoderOfType(cfg *frozenConfig, schema Schema, typ reflect2.Type) ValEncoder {
Expand Down
8 changes: 8 additions & 0 deletions noescape.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package avro

import (
"unsafe"
)

//go:linkname noescape runtime.noescape
func noescape(p unsafe.Pointer) unsafe.Pointer
Empty file added noescape.s
Empty file.
17 changes: 12 additions & 5 deletions reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ func (r *Reader) ReadLong() int64 {

// ReadFloat reads a Float from the Reader.
func (r *Reader) ReadFloat() float32 {
buf := make([]byte, 4)
r.Read(buf)
var buf [4]byte
r.Read(buf[:])

float := *(*float32)(unsafe.Pointer(&buf[0]))

Expand All @@ -195,8 +195,8 @@ func (r *Reader) ReadFloat() float32 {

// ReadDouble reads a Double from the Reader.
func (r *Reader) ReadDouble() float64 {
buf := make([]byte, 8)
r.Read(buf)
var buf [8]byte
r.Read(buf[:])

float := *(*float64)(unsafe.Pointer(&buf[0]))

Expand All @@ -220,12 +220,19 @@ func (r *Reader) ReadBytes() []byte {

// ReadString reads a String from the Reader.
func (r *Reader) ReadString() string {
size := r.ReadLong()
size := int(r.ReadLong())
if size < 0 {
r.ReportError("ReadString", "invalid string length")
return ""
}

// The string is entirely in the current buffer, fast path.
if r.head+size < r.tail {
ret := string(r.buf[r.head : r.head+size])
r.head += size
return ret
}

buf := make([]byte, size)
r.Read(buf)

Expand Down
22 changes: 16 additions & 6 deletions writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,16 +172,26 @@ func (w *Writer) WriteBlockHeader(l int64, s int64) {

// WriteBlockCB writes a block using the callback.
func (w *Writer) WriteBlockCB(callback func(w *Writer) int64) int64 {
capturedAt := len(w.buf)
var dummyHeader [18]byte
headerStart := len(w.buf)

// Write dummy header
w.Write(dummyHeader[:])

// Write block data
capturedAt := len(w.buf)
length := callback(w)
size := int64(len(w.buf) - capturedAt)

// Take a reference to the block data
captured := w.buf[capturedAt:len(w.buf)]

captured := make([]byte, len(w.buf)-capturedAt)
copy(captured, w.buf[capturedAt:])
w.buf = w.buf[:capturedAt]
// Rewrite the header
w.buf = w.buf[:headerStart]
w.WriteBlockHeader(length, size)

w.WriteBlockHeader(length, int64(len(captured)))
w.Write(captured)
// Copy the block data back to its position
w.buf = append(w.buf, captured...)

return length
}

0 comments on commit 68c9813

Please sign in to comment.