mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
gob: keep free lists of encoder and decoder states.
Avoids 3 mallocs in a round trip encoding/decoding a struct. R=rsc, rsc1 CC=golang-dev https://golang.org/cl/4278052
This commit is contained in:
parent
bcd747204d
commit
eb864e92db
5 changed files with 86 additions and 40 deletions
|
|
@ -50,7 +50,7 @@ func testError(t *testing.T) {
|
|||
func TestUintCodec(t *testing.T) {
|
||||
defer testError(t)
|
||||
b := new(bytes.Buffer)
|
||||
encState := newEncoderState(nil, b)
|
||||
encState := newEncoderState(b)
|
||||
for _, tt := range encodeT {
|
||||
b.Reset()
|
||||
encState.encodeUint(tt.x)
|
||||
|
|
@ -58,7 +58,7 @@ func TestUintCodec(t *testing.T) {
|
|||
t.Errorf("encodeUint: %#x encode: expected % x got % x", tt.x, tt.b, b.Bytes())
|
||||
}
|
||||
}
|
||||
decState := newDecodeState(nil, b)
|
||||
decState := newDecodeState(b)
|
||||
for u := uint64(0); ; u = (u + 1) * 7 {
|
||||
b.Reset()
|
||||
encState.encodeUint(u)
|
||||
|
|
@ -75,9 +75,9 @@ func TestUintCodec(t *testing.T) {
|
|||
func verifyInt(i int64, t *testing.T) {
|
||||
defer testError(t)
|
||||
var b = new(bytes.Buffer)
|
||||
encState := newEncoderState(nil, b)
|
||||
encState := newEncoderState(b)
|
||||
encState.encodeInt(i)
|
||||
decState := newDecodeState(nil, b)
|
||||
decState := newDecodeState(b)
|
||||
decState.buf = make([]byte, 8)
|
||||
j := decState.decodeInt()
|
||||
if i != j {
|
||||
|
|
@ -111,9 +111,16 @@ var complexResult = []byte{0x07, 0xFE, 0x31, 0x40, 0xFE, 0x33, 0x40}
|
|||
// The result of encoding "hello" with field number 7
|
||||
var bytesResult = []byte{0x07, 0x05, 'h', 'e', 'l', 'l', 'o'}
|
||||
|
||||
func newencoderState(b *bytes.Buffer) *encoderState {
|
||||
func newDecodeState(buf *bytes.Buffer) *decoderState {
|
||||
d := new(decoderState)
|
||||
d.b = buf
|
||||
d.buf = make([]byte, uint64Size)
|
||||
return d
|
||||
}
|
||||
|
||||
func newEncoderState(b *bytes.Buffer) *encoderState {
|
||||
b.Reset()
|
||||
state := newEncoderState(nil, b)
|
||||
state := &encoderState{enc: nil, b: b}
|
||||
state.fieldnum = -1
|
||||
return state
|
||||
}
|
||||
|
|
@ -127,7 +134,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
{
|
||||
data := struct{ a bool }{true}
|
||||
instr := &encInstr{encBool, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(boolResult, b.Bytes()) {
|
||||
t.Errorf("bool enc instructions: expected % x got % x", boolResult, b.Bytes())
|
||||
|
|
@ -139,7 +146,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a int }{17}
|
||||
instr := &encInstr{encInt, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(signedResult, b.Bytes()) {
|
||||
t.Errorf("int enc instructions: expected % x got % x", signedResult, b.Bytes())
|
||||
|
|
@ -151,7 +158,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a uint }{17}
|
||||
instr := &encInstr{encUint, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(unsignedResult, b.Bytes()) {
|
||||
t.Errorf("uint enc instructions: expected % x got % x", unsignedResult, b.Bytes())
|
||||
|
|
@ -163,7 +170,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a int8 }{17}
|
||||
instr := &encInstr{encInt8, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(signedResult, b.Bytes()) {
|
||||
t.Errorf("int8 enc instructions: expected % x got % x", signedResult, b.Bytes())
|
||||
|
|
@ -175,7 +182,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a uint8 }{17}
|
||||
instr := &encInstr{encUint8, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(unsignedResult, b.Bytes()) {
|
||||
t.Errorf("uint8 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
|
||||
|
|
@ -187,7 +194,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a int16 }{17}
|
||||
instr := &encInstr{encInt16, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(signedResult, b.Bytes()) {
|
||||
t.Errorf("int16 enc instructions: expected % x got % x", signedResult, b.Bytes())
|
||||
|
|
@ -199,7 +206,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a uint16 }{17}
|
||||
instr := &encInstr{encUint16, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(unsignedResult, b.Bytes()) {
|
||||
t.Errorf("uint16 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
|
||||
|
|
@ -211,7 +218,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a int32 }{17}
|
||||
instr := &encInstr{encInt32, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(signedResult, b.Bytes()) {
|
||||
t.Errorf("int32 enc instructions: expected % x got % x", signedResult, b.Bytes())
|
||||
|
|
@ -223,7 +230,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a uint32 }{17}
|
||||
instr := &encInstr{encUint32, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(unsignedResult, b.Bytes()) {
|
||||
t.Errorf("uint32 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
|
||||
|
|
@ -235,7 +242,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a int64 }{17}
|
||||
instr := &encInstr{encInt64, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(signedResult, b.Bytes()) {
|
||||
t.Errorf("int64 enc instructions: expected % x got % x", signedResult, b.Bytes())
|
||||
|
|
@ -247,7 +254,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a uint64 }{17}
|
||||
instr := &encInstr{encUint64, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(unsignedResult, b.Bytes()) {
|
||||
t.Errorf("uint64 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
|
||||
|
|
@ -259,7 +266,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a float32 }{17}
|
||||
instr := &encInstr{encFloat32, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(floatResult, b.Bytes()) {
|
||||
t.Errorf("float32 enc instructions: expected % x got % x", floatResult, b.Bytes())
|
||||
|
|
@ -271,7 +278,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a float64 }{17}
|
||||
instr := &encInstr{encFloat64, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(floatResult, b.Bytes()) {
|
||||
t.Errorf("float64 enc instructions: expected % x got % x", floatResult, b.Bytes())
|
||||
|
|
@ -283,7 +290,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a []byte }{[]byte("hello")}
|
||||
instr := &encInstr{encUint8Array, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(bytesResult, b.Bytes()) {
|
||||
t.Errorf("bytes enc instructions: expected % x got % x", bytesResult, b.Bytes())
|
||||
|
|
@ -295,7 +302,7 @@ func TestScalarEncInstructions(t *testing.T) {
|
|||
b.Reset()
|
||||
data := struct{ a string }{"hello"}
|
||||
instr := &encInstr{encString, 6, 0, 0}
|
||||
state := newencoderState(b)
|
||||
state := newEncoderState(b)
|
||||
instr.op(instr, state, unsafe.Pointer(&data))
|
||||
if !bytes.Equal(bytesResult, b.Bytes()) {
|
||||
t.Errorf("string enc instructions: expected % x got % x", bytesResult, b.Bytes())
|
||||
|
|
@ -315,7 +322,7 @@ func execDec(typ string, instr *decInstr, state *decoderState, t *testing.T, p u
|
|||
|
||||
func newDecodeStateFromData(data []byte) *decoderState {
|
||||
b := bytes.NewBuffer(data)
|
||||
state := newDecodeState(nil, b)
|
||||
state := newDecodeState(b)
|
||||
state.fieldnum = -1
|
||||
return state
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue