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
|
|
@ -31,18 +31,29 @@ type decoderState struct {
|
|||
b *bytes.Buffer
|
||||
fieldnum int // the last field number read.
|
||||
buf []byte
|
||||
next *decoderState // for free list
|
||||
}
|
||||
|
||||
// We pass the bytes.Buffer separately for easier testing of the infrastructure
|
||||
// without requiring a full Decoder.
|
||||
func newDecodeState(dec *Decoder, buf *bytes.Buffer) *decoderState {
|
||||
d := new(decoderState)
|
||||
d.dec = dec
|
||||
func (dec *Decoder) newDecoderState(buf *bytes.Buffer) *decoderState {
|
||||
d := dec.freeList
|
||||
if d == nil {
|
||||
d = new(decoderState)
|
||||
d.dec = dec
|
||||
} else {
|
||||
dec.freeList = d.next
|
||||
}
|
||||
d.b = buf
|
||||
d.buf = make([]byte, uint64Size)
|
||||
return d
|
||||
}
|
||||
|
||||
func (dec *Decoder) freeDecoderState(d *decoderState) {
|
||||
d.next = dec.freeList
|
||||
dec.freeList = d
|
||||
}
|
||||
|
||||
func overflow(name string) os.ErrorString {
|
||||
return os.ErrorString(`value for "` + name + `" out of range`)
|
||||
}
|
||||
|
|
@ -445,7 +456,7 @@ func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, p uintptr)
|
|||
indir = int(ut.decIndir)
|
||||
}
|
||||
p = allocate(ut.base, p, indir)
|
||||
state := newDecodeState(dec, &dec.buf)
|
||||
state := dec.newDecoderState(&dec.buf)
|
||||
state.fieldnum = singletonField
|
||||
basep := p
|
||||
delta := int(state.decodeUint())
|
||||
|
|
@ -458,6 +469,7 @@ func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, p uintptr)
|
|||
ptr = decIndirect(ptr, instr.indir)
|
||||
}
|
||||
instr.op(instr, state, ptr)
|
||||
dec.freeDecoderState(state)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -468,7 +480,7 @@ func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, p uintptr)
|
|||
// from the user's value, not from the innards of an engine.
|
||||
func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, p uintptr, indir int) (err os.Error) {
|
||||
p = allocate(ut.base.(*reflect.StructType), p, indir)
|
||||
state := newDecodeState(dec, &dec.buf)
|
||||
state := dec.newDecoderState(&dec.buf)
|
||||
state.fieldnum = -1
|
||||
basep := p
|
||||
for state.b.Len() > 0 {
|
||||
|
|
@ -492,12 +504,13 @@ func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, p uintptr,
|
|||
instr.op(instr, state, p)
|
||||
state.fieldnum = fieldnum
|
||||
}
|
||||
dec.freeDecoderState(state)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ignoreStruct discards the data for a struct with no destination.
|
||||
func (dec *Decoder) ignoreStruct(engine *decEngine) (err os.Error) {
|
||||
state := newDecodeState(dec, &dec.buf)
|
||||
state := dec.newDecoderState(&dec.buf)
|
||||
state.fieldnum = -1
|
||||
for state.b.Len() > 0 {
|
||||
delta := int(state.decodeUint())
|
||||
|
|
@ -515,13 +528,14 @@ func (dec *Decoder) ignoreStruct(engine *decEngine) (err os.Error) {
|
|||
instr.op(instr, state, unsafe.Pointer(nil))
|
||||
state.fieldnum = fieldnum
|
||||
}
|
||||
dec.freeDecoderState(state)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ignoreSingle discards the data for a top-level non-struct value with no
|
||||
// destination. It's used when calling Decode with a nil value.
|
||||
func (dec *Decoder) ignoreSingle(engine *decEngine) (err os.Error) {
|
||||
state := newDecodeState(dec, &dec.buf)
|
||||
state := dec.newDecoderState(&dec.buf)
|
||||
state.fieldnum = singletonField
|
||||
delta := int(state.decodeUint())
|
||||
if delta != 0 {
|
||||
|
|
@ -529,6 +543,7 @@ func (dec *Decoder) ignoreSingle(engine *decEngine) (err os.Error) {
|
|||
}
|
||||
instr := &engine.instr[singletonField]
|
||||
instr.op(instr, state, unsafe.Pointer(nil))
|
||||
dec.freeDecoderState(state)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue