diff --git a/discover/packets_xdr.go b/discover/packets_xdr.go index b2e5e2e46..4e1cd1740 100644 --- a/discover/packets_xdr.go +++ b/discover/packets_xdr.go @@ -13,10 +13,10 @@ func (o QueryV2) EncodeXDR(w io.Writer) (int, error) { } func (o QueryV2) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o QueryV2) encodeXDR(xw *xdr.Writer) (int, error) { @@ -34,8 +34,8 @@ func (o *QueryV2) DecodeXDR(r io.Reader) error { } func (o *QueryV2) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -51,10 +51,10 @@ func (o AnnounceV2) EncodeXDR(w io.Writer) (int, error) { } func (o AnnounceV2) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o AnnounceV2) encodeXDR(xw *xdr.Writer) (int, error) { @@ -76,8 +76,8 @@ func (o *AnnounceV2) DecodeXDR(r io.Reader) error { } func (o *AnnounceV2) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -101,10 +101,10 @@ func (o Node) EncodeXDR(w io.Writer) (int, error) { } func (o Node) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o Node) encodeXDR(xw *xdr.Writer) (int, error) { @@ -128,8 +128,8 @@ func (o *Node) DecodeXDR(r io.Reader) error { } func (o *Node) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -152,10 +152,10 @@ func (o Address) EncodeXDR(w io.Writer) (int, error) { } func (o Address) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o Address) encodeXDR(xw *xdr.Writer) (int, error) { @@ -173,8 +173,8 @@ func (o *Address) DecodeXDR(r io.Reader) error { } func (o *Address) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } diff --git a/protocol/message_xdr.go b/protocol/message_xdr.go index 95a4bd465..950086ba8 100644 --- a/protocol/message_xdr.go +++ b/protocol/message_xdr.go @@ -13,10 +13,10 @@ func (o IndexMessage) EncodeXDR(w io.Writer) (int, error) { } func (o IndexMessage) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o IndexMessage) encodeXDR(xw *xdr.Writer) (int, error) { @@ -40,8 +40,8 @@ func (o *IndexMessage) DecodeXDR(r io.Reader) error { } func (o *IndexMessage) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -64,10 +64,10 @@ func (o FileInfo) EncodeXDR(w io.Writer) (int, error) { } func (o FileInfo) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o FileInfo) encodeXDR(xw *xdr.Writer) (int, error) { @@ -94,8 +94,8 @@ func (o *FileInfo) DecodeXDR(r io.Reader) error { } func (o *FileInfo) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -121,10 +121,10 @@ func (o BlockInfo) EncodeXDR(w io.Writer) (int, error) { } func (o BlockInfo) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o BlockInfo) encodeXDR(xw *xdr.Writer) (int, error) { @@ -142,8 +142,8 @@ func (o *BlockInfo) DecodeXDR(r io.Reader) error { } func (o *BlockInfo) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -159,10 +159,10 @@ func (o RequestMessage) EncodeXDR(w io.Writer) (int, error) { } func (o RequestMessage) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o RequestMessage) encodeXDR(xw *xdr.Writer) (int, error) { @@ -185,8 +185,8 @@ func (o *RequestMessage) DecodeXDR(r io.Reader) error { } func (o *RequestMessage) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -204,10 +204,10 @@ func (o ClusterConfigMessage) EncodeXDR(w io.Writer) (int, error) { } func (o ClusterConfigMessage) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o ClusterConfigMessage) encodeXDR(xw *xdr.Writer) (int, error) { @@ -242,8 +242,8 @@ func (o *ClusterConfigMessage) DecodeXDR(r io.Reader) error { } func (o *ClusterConfigMessage) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -275,10 +275,10 @@ func (o Repository) EncodeXDR(w io.Writer) (int, error) { } func (o Repository) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o Repository) encodeXDR(xw *xdr.Writer) (int, error) { @@ -302,8 +302,8 @@ func (o *Repository) DecodeXDR(r io.Reader) error { } func (o *Repository) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -326,10 +326,10 @@ func (o Node) EncodeXDR(w io.Writer) (int, error) { } func (o Node) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o Node) encodeXDR(xw *xdr.Writer) (int, error) { @@ -348,8 +348,8 @@ func (o *Node) DecodeXDR(r io.Reader) error { } func (o *Node) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -366,10 +366,10 @@ func (o Option) EncodeXDR(w io.Writer) (int, error) { } func (o Option) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o Option) encodeXDR(xw *xdr.Writer) (int, error) { @@ -390,8 +390,8 @@ func (o *Option) DecodeXDR(r io.Reader) error { } func (o *Option) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } diff --git a/xdr/bench_test.go b/xdr/bench_test.go index 1d6e0a2b3..26dcb29e5 100644 --- a/xdr/bench_test.go +++ b/xdr/bench_test.go @@ -5,25 +5,30 @@ package xdr_test import ( - "bytes" + "io" + "io/ioutil" "testing" ) type XDRBenchStruct struct { - I1 uint64 - I2 uint32 - I3 uint16 - Bs []byte - S string + I1 uint64 + I2 uint32 + I3 uint16 + Bs0 []byte // max:128 + Bs1 []byte + S0 string // max:128 + S1 string } var res []byte // no to be optimized away var s = XDRBenchStruct{ - I1: 42, - I2: 43, - I3: 44, - Bs: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, - S: "Hello World!", + I1: 42, + I2: 43, + I3: 44, + Bs0: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, + Bs1: []byte{11, 12, 13, 14, 15, 16, 17, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + S0: "Hello World! String one.", + S1: "Hello World! String two.", } var e = s.MarshalXDR() @@ -43,15 +48,40 @@ func BenchmarkThisUnmarshal(b *testing.B) { } } -func BenchmarkEncode(b *testing.B) { - bs := make([]byte, 0, 65536) - buf := bytes.NewBuffer(bs) - +func BenchmarkThisEncode(b *testing.B) { for i := 0; i < b.N; i++ { - _, err := s.EncodeXDR(buf) + _, err := s.EncodeXDR(ioutil.Discard) if err != nil { b.Fatal(err) } - buf.Reset() + } +} + +type repeatReader struct { + data []byte +} + +func (r *repeatReader) Read(bs []byte) (n int, err error) { + if len(bs) > len(r.data) { + err = io.EOF + } + n = copy(bs, r.data) + r.data = r.data[n:] + return n, err +} + +func (r *repeatReader) Reset(bs []byte) { + r.data = bs +} + +func BenchmarkThisDecode(b *testing.B) { + rr := &repeatReader{e} + var t XDRBenchStruct + for i := 0; i < b.N; i++ { + err := t.DecodeXDR(rr) + if err != nil { + b.Fatal(err) + } + rr.Reset(e) } } diff --git a/xdr/bench_xdr_test.go b/xdr/bench_xdr_test.go index b016acfaf..3b3702518 100644 --- a/xdr/bench_xdr_test.go +++ b/xdr/bench_xdr_test.go @@ -1,7 +1,3 @@ -// Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved. -// Use of this source code is governed by an MIT-style license that can be -// found in the LICENSE file. - package xdr_test import ( @@ -17,18 +13,26 @@ func (o XDRBenchStruct) EncodeXDR(w io.Writer) (int, error) { } func (o XDRBenchStruct) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) } func (o XDRBenchStruct) encodeXDR(xw *xdr.Writer) (int, error) { xw.WriteUint64(o.I1) xw.WriteUint32(o.I2) xw.WriteUint16(o.I3) - xw.WriteBytes(o.Bs) - xw.WriteString(o.S) + if len(o.Bs0) > 128 { + return xw.Tot(), xdr.ErrElementSizeExceeded + } + xw.WriteBytes(o.Bs0) + xw.WriteBytes(o.Bs1) + if len(o.S0) > 128 { + return xw.Tot(), xdr.ErrElementSizeExceeded + } + xw.WriteString(o.S0) + xw.WriteString(o.S1) return xw.Tot(), xw.Error() } @@ -38,8 +42,8 @@ func (o *XDRBenchStruct) DecodeXDR(r io.Reader) error { } func (o *XDRBenchStruct) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) } @@ -47,7 +51,42 @@ func (o *XDRBenchStruct) decodeXDR(xr *xdr.Reader) error { o.I1 = xr.ReadUint64() o.I2 = xr.ReadUint32() o.I3 = xr.ReadUint16() - o.Bs = xr.ReadBytes() - o.S = xr.ReadString() + o.Bs0 = xr.ReadBytesMax(128) + o.Bs1 = xr.ReadBytes() + o.S0 = xr.ReadStringMax(128) + o.S1 = xr.ReadString() + return xr.Error() +} + +func (o repeatReader) EncodeXDR(w io.Writer) (int, error) { + var xw = xdr.NewWriter(w) + return o.encodeXDR(xw) +} + +func (o repeatReader) MarshalXDR() []byte { + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) + o.encodeXDR(xw) + return []byte(aw) +} + +func (o repeatReader) encodeXDR(xw *xdr.Writer) (int, error) { + xw.WriteBytes(o.data) + return xw.Tot(), xw.Error() +} + +func (o *repeatReader) DecodeXDR(r io.Reader) error { + xr := xdr.NewReader(r) + return o.decodeXDR(xr) +} + +func (o *repeatReader) UnmarshalXDR(bs []byte) error { + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) + return o.decodeXDR(xr) +} + +func (o *repeatReader) decodeXDR(xr *xdr.Reader) error { + o.data = xr.ReadBytes() return xr.Error() } diff --git a/xdr/cmd/coder/main.go b/xdr/cmd/coder/main.go index e90f1a73a..4f3a25c42 100644 --- a/xdr/cmd/coder/main.go +++ b/xdr/cmd/coder/main.go @@ -50,10 +50,10 @@ func (o {{.TypeName}}) EncodeXDR(w io.Writer) (int, error) { }//+n func (o {{.TypeName}}) MarshalXDR() []byte { - var buf bytes.Buffer - var xw = xdr.NewWriter(&buf) + var aw = make(xdr.AppendWriter, 0, 128) + var xw = xdr.NewWriter(&aw) o.encodeXDR(xw) - return buf.Bytes() + return []byte(aw) }//+n func (o {{.TypeName}}) encodeXDR(xw *xdr.Writer) (int, error) { @@ -98,8 +98,8 @@ func (o *{{.TypeName}}) DecodeXDR(r io.Reader) error { }//+n func (o *{{.TypeName}}) UnmarshalXDR(bs []byte) error { - var buf = bytes.NewBuffer(bs) - var xr = xdr.NewReader(buf) + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) return o.decodeXDR(xr) }//+n diff --git a/xdr/reader.go b/xdr/reader.go index b668a6f0b..1e61eafe3 100644 --- a/xdr/reader.go +++ b/xdr/reader.go @@ -17,6 +17,7 @@ type Reader struct { tot int err error b [8]byte + sb []byte last time.Time } @@ -27,11 +28,23 @@ func NewReader(r io.Reader) *Reader { } func (r *Reader) ReadString() string { - return string(r.ReadBytes()) + if r.sb == nil { + r.sb = make([]byte, 64) + } else { + r.sb = r.sb[:cap(r.sb)] + } + r.sb = r.ReadBytesInto(r.sb) + return string(r.sb) } func (r *Reader) ReadStringMax(max int) string { - return string(r.ReadBytesMax(max)) + if r.sb == nil { + r.sb = make([]byte, 64) + } else { + r.sb = r.sb[:cap(r.sb)] + } + r.sb = r.ReadBytesMaxInto(max, r.sb) + return string(r.sb) } func (r *Reader) ReadBytes() []byte { diff --git a/xdr/writer.go b/xdr/writer.go index 3ac552903..4083af794 100644 --- a/xdr/writer.go +++ b/xdr/writer.go @@ -27,6 +27,13 @@ type Writer struct { last time.Time } +type AppendWriter []byte + +func (w *AppendWriter) Write(bs []byte) (int, error) { + *w = append(*w, bs...) + return len(bs), nil +} + func NewWriter(w io.Writer) *Writer { return &Writer{ w: w,