[wip] protocol

Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
Anton Nesterov 2024-08-13 02:29:27 +02:00
parent 42ab71e964
commit c08aa3e104
No known key found for this signature in database
GPG key ID: 59121E8AE2851FB5
11 changed files with 848 additions and 1 deletions

View file

@ -3,18 +3,29 @@ module l12.xyz/dal/tests
go 1.22.6 go 1.22.6
require l12.xyz/dal/builder v0.0.0 require l12.xyz/dal/builder v0.0.0
replace l12.xyz/dal/builder v0.0.0 => ../builder replace l12.xyz/dal/builder v0.0.0 => ../builder
replace l12.xyz/dal/utils v0.0.0 => ../utils replace l12.xyz/dal/utils v0.0.0 => ../utils
require l12.xyz/dal/adapter v0.0.0 require l12.xyz/dal/adapter v0.0.0
require l12.xyz/dal/proto v0.0.0
require (
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect
github.com/tinylib/msgp v1.2.0 // indirect
)
replace l12.xyz/dal/adapter v0.0.0 => ../adapter replace l12.xyz/dal/adapter v0.0.0 => ../adapter
replace l12.xyz/dal/proto v0.0.0 => ../proto
replace l12.xyz/dal/filters v0.0.0 => ../filters replace l12.xyz/dal/filters v0.0.0 => ../filters
require ( require (
github.com/mattn/go-sqlite3 v1.14.22 github.com/mattn/go-sqlite3 v1.14.22
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
l12.xyz/dal/utils v0.0.0 // indirect
l12.xyz/dal/filters v0.0.0 // indirect l12.xyz/dal/filters v0.0.0 // indirect
l12.xyz/dal/utils v0.0.0 // indirect
) )

View file

@ -1,4 +1,8 @@
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 h1:jYi87L8j62qkXzaYHAQAhEapgukhenIMZRBKTNRLHJ4=
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/tinylib/msgp v1.2.0 h1:0uKB/662twsVBpYUPbokj4sTSKhWFKB7LopO2kWK8lY=
github.com/tinylib/msgp v1.2.0/go.mod h1:2vIGs3lcUo8izAATNobrCHevYZC/LMsJtw4JPiYPHro=

View file

@ -0,0 +1,32 @@
package tests
import (
"os"
"testing"
_ "github.com/mattn/go-sqlite3"
"l12.xyz/dal/adapter"
"l12.xyz/dal/proto"
)
func TestProtoMessagePack(t *testing.T) {
message, err := os.ReadFile("proto_test.msgpack")
if err != nil {
t.Fatalf("failed to read file: %v", err)
}
req := proto.Request{}
req.UnmarshalMsg(message)
query, err := req.Parse(adapter.SQLite{})
if err != nil {
t.Fatalf("failed to parse query: %v", err)
}
db := "database.sqlite"
if query.Db != db {
t.Fatalf("expected db %s, got %s", db, query.Db)
}
expr := "SELECT * FROM data WHERE a = ? AND b > ?"
if query.Expression != expr {
t.Fatalf("expected expression %s, got %s", expr, query.Expression)
}
//fmt.Println(q)
}

View file

@ -0,0 +1 @@
いdbッdatabase.sqliteィcommands窒ヲmethod「In、args側dataえmethod、Find、args曹。a。b▲$gt

View file

@ -0,0 +1,20 @@
import { encode } from "https://deno.land/x/msgpack@v1.2/mod.ts";
const Query = {
"db": "database.sqlite",
"commands": [
{"method": "In", "args": ["data"]},
{
"method": "Find",
"args": [{
"a": 1,
"b": {
"$gt": 2,
},
}]
},
],
};
const encoded: Uint8Array = encode(Query);
Deno.writeFileSync("proto_test.msgpack", encoded);

View file

@ -16,6 +16,9 @@ func FromJson[T IFilter](data interface{}) *T {
} }
} }
m, ok := data.(Filter) m, ok := data.(Filter)
if !ok {
m, ok = data.(map[string]interface{})
}
if ok { if ok {
s, err := json.Marshal(m) s, err := json.Marshal(m)
if err != nil { if err != nil {

24
pkg/proto/go.mod Normal file
View file

@ -0,0 +1,24 @@
module l12.xyz/dal/proto
go 1.22.6
require l12.xyz/dal/builder v0.0.0
replace l12.xyz/dal/builder v0.0.0 => ../builder
require github.com/tinylib/msgp v1.2.0
require github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect
replace l12.xyz/dal/utils v0.0.0 => ../utils
replace l12.xyz/dal/adapter v0.0.0 => ../adapter
replace l12.xyz/dal/filters v0.0.0 => ../filters
require (
github.com/pkg/errors v0.9.1 // indirect
l12.xyz/dal/adapter v0.0.0 // indirect
l12.xyz/dal/filters v0.0.0 // indirect
l12.xyz/dal/utils v0.0.0 // indirect
)

6
pkg/proto/go.sum Normal file
View file

@ -0,0 +1,6 @@
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 h1:jYi87L8j62qkXzaYHAQAhEapgukhenIMZRBKTNRLHJ4=
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/tinylib/msgp v1.2.0 h1:0uKB/662twsVBpYUPbokj4sTSKhWFKB7LopO2kWK8lY=
github.com/tinylib/msgp v1.2.0/go.mod h1:2vIGs3lcUo8izAATNobrCHevYZC/LMsJtw4JPiYPHro=

42
pkg/proto/request.go Normal file
View file

@ -0,0 +1,42 @@
package proto
import (
"fmt"
"reflect"
"l12.xyz/dal/adapter"
"l12.xyz/dal/builder"
)
//go:generate msgp
type BuildCmd struct {
Method string `msg:"method"`
Args []interface{} `msg:"args"`
}
type Request struct {
Db string `msg:"db"`
Commands []BuildCmd `msg:"commands"`
}
func (q *Request) Parse(dialect adapter.Dialect) (adapter.Query, error) {
b := builder.New(dialect)
for _, cmd := range q.Commands {
method := reflect.ValueOf(b).MethodByName(cmd.Method)
if !method.IsValid() {
return adapter.Query{}, fmt.Errorf("method %s not found", cmd.Method)
}
args := make([]reflect.Value, len(cmd.Args))
for i, arg := range cmd.Args {
args[i] = reflect.ValueOf(arg)
}
method.Call(args)
}
expr, data := b.Sql()
return adapter.Query{
Db: q.Db,
Expression: expr,
Data: data,
}, nil
}

468
pkg/proto/request_gen.go Normal file
View file

@ -0,0 +1,468 @@
package proto
// Code generated by github.com/tinylib/msgp DO NOT EDIT.
import (
"github.com/tinylib/msgp/msgp"
)
// DecodeMsg implements msgp.Decodable
func (z *BuildCmd) DecodeMsg(dc *msgp.Reader) (err error) {
var field []byte
_ = field
var zb0001 uint32
zb0001, err = dc.ReadMapHeader()
if err != nil {
err = msgp.WrapError(err)
return
}
for zb0001 > 0 {
zb0001--
field, err = dc.ReadMapKeyPtr()
if err != nil {
err = msgp.WrapError(err)
return
}
switch msgp.UnsafeString(field) {
case "method":
z.Method, err = dc.ReadString()
if err != nil {
err = msgp.WrapError(err, "Method")
return
}
case "args":
var zb0002 uint32
zb0002, err = dc.ReadArrayHeader()
if err != nil {
err = msgp.WrapError(err, "Args")
return
}
if cap(z.Args) >= int(zb0002) {
z.Args = (z.Args)[:zb0002]
} else {
z.Args = make([]interface{}, zb0002)
}
for za0001 := range z.Args {
z.Args[za0001], err = dc.ReadIntf()
if err != nil {
err = msgp.WrapError(err, "Args", za0001)
return
}
}
default:
err = dc.Skip()
if err != nil {
err = msgp.WrapError(err)
return
}
}
}
return
}
// EncodeMsg implements msgp.Encodable
func (z *BuildCmd) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 2
// write "method"
err = en.Append(0x82, 0xa6, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64)
if err != nil {
return
}
err = en.WriteString(z.Method)
if err != nil {
err = msgp.WrapError(err, "Method")
return
}
// write "args"
err = en.Append(0xa4, 0x61, 0x72, 0x67, 0x73)
if err != nil {
return
}
err = en.WriteArrayHeader(uint32(len(z.Args)))
if err != nil {
err = msgp.WrapError(err, "Args")
return
}
for za0001 := range z.Args {
err = en.WriteIntf(z.Args[za0001])
if err != nil {
err = msgp.WrapError(err, "Args", za0001)
return
}
}
return
}
// MarshalMsg implements msgp.Marshaler
func (z *BuildCmd) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// map header, size 2
// string "method"
o = append(o, 0x82, 0xa6, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64)
o = msgp.AppendString(o, z.Method)
// string "args"
o = append(o, 0xa4, 0x61, 0x72, 0x67, 0x73)
o = msgp.AppendArrayHeader(o, uint32(len(z.Args)))
for za0001 := range z.Args {
o, err = msgp.AppendIntf(o, z.Args[za0001])
if err != nil {
err = msgp.WrapError(err, "Args", za0001)
return
}
}
return
}
// UnmarshalMsg implements msgp.Unmarshaler
func (z *BuildCmd) UnmarshalMsg(bts []byte) (o []byte, err error) {
var field []byte
_ = field
var zb0001 uint32
zb0001, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
for zb0001 > 0 {
zb0001--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
switch msgp.UnsafeString(field) {
case "method":
z.Method, bts, err = msgp.ReadStringBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Method")
return
}
case "args":
var zb0002 uint32
zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Args")
return
}
if cap(z.Args) >= int(zb0002) {
z.Args = (z.Args)[:zb0002]
} else {
z.Args = make([]interface{}, zb0002)
}
for za0001 := range z.Args {
z.Args[za0001], bts, err = msgp.ReadIntfBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Args", za0001)
return
}
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
}
}
o = bts
return
}
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *BuildCmd) Msgsize() (s int) {
s = 1 + 7 + msgp.StringPrefixSize + len(z.Method) + 5 + msgp.ArrayHeaderSize
for za0001 := range z.Args {
s += msgp.GuessSize(z.Args[za0001])
}
return
}
// DecodeMsg implements msgp.Decodable
func (z *Request) DecodeMsg(dc *msgp.Reader) (err error) {
var field []byte
_ = field
var zb0001 uint32
zb0001, err = dc.ReadMapHeader()
if err != nil {
err = msgp.WrapError(err)
return
}
for zb0001 > 0 {
zb0001--
field, err = dc.ReadMapKeyPtr()
if err != nil {
err = msgp.WrapError(err)
return
}
switch msgp.UnsafeString(field) {
case "db":
z.Db, err = dc.ReadString()
if err != nil {
err = msgp.WrapError(err, "Db")
return
}
case "commands":
var zb0002 uint32
zb0002, err = dc.ReadArrayHeader()
if err != nil {
err = msgp.WrapError(err, "Commands")
return
}
if cap(z.Commands) >= int(zb0002) {
z.Commands = (z.Commands)[:zb0002]
} else {
z.Commands = make([]BuildCmd, zb0002)
}
for za0001 := range z.Commands {
var zb0003 uint32
zb0003, err = dc.ReadMapHeader()
if err != nil {
err = msgp.WrapError(err, "Commands", za0001)
return
}
for zb0003 > 0 {
zb0003--
field, err = dc.ReadMapKeyPtr()
if err != nil {
err = msgp.WrapError(err, "Commands", za0001)
return
}
switch msgp.UnsafeString(field) {
case "method":
z.Commands[za0001].Method, err = dc.ReadString()
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Method")
return
}
case "args":
var zb0004 uint32
zb0004, err = dc.ReadArrayHeader()
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Args")
return
}
if cap(z.Commands[za0001].Args) >= int(zb0004) {
z.Commands[za0001].Args = (z.Commands[za0001].Args)[:zb0004]
} else {
z.Commands[za0001].Args = make([]interface{}, zb0004)
}
for za0002 := range z.Commands[za0001].Args {
z.Commands[za0001].Args[za0002], err = dc.ReadIntf()
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Args", za0002)
return
}
}
default:
err = dc.Skip()
if err != nil {
err = msgp.WrapError(err, "Commands", za0001)
return
}
}
}
}
default:
err = dc.Skip()
if err != nil {
err = msgp.WrapError(err)
return
}
}
}
return
}
// EncodeMsg implements msgp.Encodable
func (z *Request) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 2
// write "db"
err = en.Append(0x82, 0xa2, 0x64, 0x62)
if err != nil {
return
}
err = en.WriteString(z.Db)
if err != nil {
err = msgp.WrapError(err, "Db")
return
}
// write "commands"
err = en.Append(0xa8, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73)
if err != nil {
return
}
err = en.WriteArrayHeader(uint32(len(z.Commands)))
if err != nil {
err = msgp.WrapError(err, "Commands")
return
}
for za0001 := range z.Commands {
// map header, size 2
// write "method"
err = en.Append(0x82, 0xa6, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64)
if err != nil {
return
}
err = en.WriteString(z.Commands[za0001].Method)
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Method")
return
}
// write "args"
err = en.Append(0xa4, 0x61, 0x72, 0x67, 0x73)
if err != nil {
return
}
err = en.WriteArrayHeader(uint32(len(z.Commands[za0001].Args)))
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Args")
return
}
for za0002 := range z.Commands[za0001].Args {
err = en.WriteIntf(z.Commands[za0001].Args[za0002])
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Args", za0002)
return
}
}
}
return
}
// MarshalMsg implements msgp.Marshaler
func (z *Request) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// map header, size 2
// string "db"
o = append(o, 0x82, 0xa2, 0x64, 0x62)
o = msgp.AppendString(o, z.Db)
// string "commands"
o = append(o, 0xa8, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73)
o = msgp.AppendArrayHeader(o, uint32(len(z.Commands)))
for za0001 := range z.Commands {
// map header, size 2
// string "method"
o = append(o, 0x82, 0xa6, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64)
o = msgp.AppendString(o, z.Commands[za0001].Method)
// string "args"
o = append(o, 0xa4, 0x61, 0x72, 0x67, 0x73)
o = msgp.AppendArrayHeader(o, uint32(len(z.Commands[za0001].Args)))
for za0002 := range z.Commands[za0001].Args {
o, err = msgp.AppendIntf(o, z.Commands[za0001].Args[za0002])
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Args", za0002)
return
}
}
}
return
}
// UnmarshalMsg implements msgp.Unmarshaler
func (z *Request) UnmarshalMsg(bts []byte) (o []byte, err error) {
var field []byte
_ = field
var zb0001 uint32
zb0001, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
for zb0001 > 0 {
zb0001--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
switch msgp.UnsafeString(field) {
case "db":
z.Db, bts, err = msgp.ReadStringBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Db")
return
}
case "commands":
var zb0002 uint32
zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Commands")
return
}
if cap(z.Commands) >= int(zb0002) {
z.Commands = (z.Commands)[:zb0002]
} else {
z.Commands = make([]BuildCmd, zb0002)
}
for za0001 := range z.Commands {
var zb0003 uint32
zb0003, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Commands", za0001)
return
}
for zb0003 > 0 {
zb0003--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "Commands", za0001)
return
}
switch msgp.UnsafeString(field) {
case "method":
z.Commands[za0001].Method, bts, err = msgp.ReadStringBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Method")
return
}
case "args":
var zb0004 uint32
zb0004, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Args")
return
}
if cap(z.Commands[za0001].Args) >= int(zb0004) {
z.Commands[za0001].Args = (z.Commands[za0001].Args)[:zb0004]
} else {
z.Commands[za0001].Args = make([]interface{}, zb0004)
}
for za0002 := range z.Commands[za0001].Args {
z.Commands[za0001].Args[za0002], bts, err = msgp.ReadIntfBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Commands", za0001, "Args", za0002)
return
}
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
err = msgp.WrapError(err, "Commands", za0001)
return
}
}
}
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
}
}
o = bts
return
}
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *Request) Msgsize() (s int) {
s = 1 + 3 + msgp.StringPrefixSize + len(z.Db) + 9 + msgp.ArrayHeaderSize
for za0001 := range z.Commands {
s += 1 + 7 + msgp.StringPrefixSize + len(z.Commands[za0001].Method) + 5 + msgp.ArrayHeaderSize
for za0002 := range z.Commands[za0001].Args {
s += msgp.GuessSize(z.Commands[za0001].Args[za0002])
}
}
return
}

View file

@ -0,0 +1,236 @@
package proto
// Code generated by github.com/tinylib/msgp DO NOT EDIT.
import (
"bytes"
"testing"
"github.com/tinylib/msgp/msgp"
)
func TestMarshalUnmarshalBuildCmd(t *testing.T) {
v := BuildCmd{}
bts, err := v.MarshalMsg(nil)
if err != nil {
t.Fatal(err)
}
left, err := v.UnmarshalMsg(bts)
if err != nil {
t.Fatal(err)
}
if len(left) > 0 {
t.Errorf("%d bytes left over after UnmarshalMsg(): %q", len(left), left)
}
left, err = msgp.Skip(bts)
if err != nil {
t.Fatal(err)
}
if len(left) > 0 {
t.Errorf("%d bytes left over after Skip(): %q", len(left), left)
}
}
func BenchmarkMarshalMsgBuildCmd(b *testing.B) {
v := BuildCmd{}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
v.MarshalMsg(nil)
}
}
func BenchmarkAppendMsgBuildCmd(b *testing.B) {
v := BuildCmd{}
bts := make([]byte, 0, v.Msgsize())
bts, _ = v.MarshalMsg(bts[0:0])
b.SetBytes(int64(len(bts)))
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
bts, _ = v.MarshalMsg(bts[0:0])
}
}
func BenchmarkUnmarshalBuildCmd(b *testing.B) {
v := BuildCmd{}
bts, _ := v.MarshalMsg(nil)
b.ReportAllocs()
b.SetBytes(int64(len(bts)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := v.UnmarshalMsg(bts)
if err != nil {
b.Fatal(err)
}
}
}
func TestEncodeDecodeBuildCmd(t *testing.T) {
v := BuildCmd{}
var buf bytes.Buffer
msgp.Encode(&buf, &v)
m := v.Msgsize()
if buf.Len() > m {
t.Log("WARNING: TestEncodeDecodeBuildCmd Msgsize() is inaccurate")
}
vn := BuildCmd{}
err := msgp.Decode(&buf, &vn)
if err != nil {
t.Error(err)
}
buf.Reset()
msgp.Encode(&buf, &v)
err = msgp.NewReader(&buf).Skip()
if err != nil {
t.Error(err)
}
}
func BenchmarkEncodeBuildCmd(b *testing.B) {
v := BuildCmd{}
var buf bytes.Buffer
msgp.Encode(&buf, &v)
b.SetBytes(int64(buf.Len()))
en := msgp.NewWriter(msgp.Nowhere)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
v.EncodeMsg(en)
}
en.Flush()
}
func BenchmarkDecodeBuildCmd(b *testing.B) {
v := BuildCmd{}
var buf bytes.Buffer
msgp.Encode(&buf, &v)
b.SetBytes(int64(buf.Len()))
rd := msgp.NewEndlessReader(buf.Bytes(), b)
dc := msgp.NewReader(rd)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := v.DecodeMsg(dc)
if err != nil {
b.Fatal(err)
}
}
}
func TestMarshalUnmarshalRequest(t *testing.T) {
v := Request{}
bts, err := v.MarshalMsg(nil)
if err != nil {
t.Fatal(err)
}
left, err := v.UnmarshalMsg(bts)
if err != nil {
t.Fatal(err)
}
if len(left) > 0 {
t.Errorf("%d bytes left over after UnmarshalMsg(): %q", len(left), left)
}
left, err = msgp.Skip(bts)
if err != nil {
t.Fatal(err)
}
if len(left) > 0 {
t.Errorf("%d bytes left over after Skip(): %q", len(left), left)
}
}
func BenchmarkMarshalMsgRequest(b *testing.B) {
v := Request{}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
v.MarshalMsg(nil)
}
}
func BenchmarkAppendMsgRequest(b *testing.B) {
v := Request{}
bts := make([]byte, 0, v.Msgsize())
bts, _ = v.MarshalMsg(bts[0:0])
b.SetBytes(int64(len(bts)))
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
bts, _ = v.MarshalMsg(bts[0:0])
}
}
func BenchmarkUnmarshalRequest(b *testing.B) {
v := Request{}
bts, _ := v.MarshalMsg(nil)
b.ReportAllocs()
b.SetBytes(int64(len(bts)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := v.UnmarshalMsg(bts)
if err != nil {
b.Fatal(err)
}
}
}
func TestEncodeDecodeRequest(t *testing.T) {
v := Request{}
var buf bytes.Buffer
msgp.Encode(&buf, &v)
m := v.Msgsize()
if buf.Len() > m {
t.Log("WARNING: TestEncodeDecodeRequest Msgsize() is inaccurate")
}
vn := Request{}
err := msgp.Decode(&buf, &vn)
if err != nil {
t.Error(err)
}
buf.Reset()
msgp.Encode(&buf, &v)
err = msgp.NewReader(&buf).Skip()
if err != nil {
t.Error(err)
}
}
func BenchmarkEncodeRequest(b *testing.B) {
v := Request{}
var buf bytes.Buffer
msgp.Encode(&buf, &v)
b.SetBytes(int64(buf.Len()))
en := msgp.NewWriter(msgp.Nowhere)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
v.EncodeMsg(en)
}
en.Flush()
}
func BenchmarkDecodeRequest(b *testing.B) {
v := Request{}
var buf bytes.Buffer
msgp.Encode(&buf, &v)
b.SetBytes(int64(buf.Len()))
rd := msgp.NewEndlessReader(buf.Bytes(), b)
dc := msgp.NewReader(rd)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := v.DecodeMsg(dc)
if err != nil {
b.Fatal(err)
}
}
}