@@ -17,6 +17,7 @@ type V3Encoder struct {
1717 out io.Writer
1818 varintbuf * [binary .MaxVarintLen64 + 1 ]byte
1919 sync.Mutex
20+ typeCache map [string ]map [string ]int
2021}
2122
2223var v3StreamHeader = []byte {version3 , 1 << 7 }
@@ -32,6 +33,7 @@ func NewV3Encoder(out io.Writer, isStream bool) *V3Encoder {
3233 return & V3Encoder {
3334 out : out ,
3435 varintbuf : & [binary .MaxVarintLen64 + 1 ]byte {},
36+ typeCache : map [string ]map [string ]int {},
3537 }
3638}
3739
@@ -42,6 +44,7 @@ func Encodev3(d interface{}, out io.Writer) error {
4244 enc := & V3Encoder {
4345 out : out ,
4446 varintbuf : & [binary .MaxVarintLen64 + 1 ]byte {},
47+ typeCache : map [string ]map [string ]int {},
4548 }
4649 //We dont have to lock/unlock since we know we are the only one witha acces
4750 return enc .encodeValuev3 (d , v3.Key {})
@@ -256,7 +259,15 @@ func (enc *V3Encoder) encodeValuev3(d interface{}, k v3.Key) error {
256259 }
257260 value .Vtype = v3 .BytesT
258261 } else if kind == reflect .Struct {
259- usableFields := getStructFields (val )
262+ name := val .Type ().String ()
263+ var usableFields map [string ]int
264+ if v , ok := enc .typeCache [name ]; ok {
265+ usableFields = v
266+ } else {
267+ usableFields = getStructFields (val )
268+ enc .typeCache [name ] = usableFields
269+ }
270+
260271 value .Childrenn = uint64 (len (usableFields ))
261272 value .Vtype = v3 .MapT
262273 alreadyEncoded = true
@@ -300,6 +311,7 @@ type V3Decoder struct {
300311 isStream bool
301312 didDecode bool
302313 in v3.Reader
314+ typeCache map [string ]map [string ]int
303315 sync.Mutex
304316}
305317
@@ -308,8 +320,9 @@ type V3Decoder struct {
308320//Initializing the decoder blocks until at least the first 2 bytes are read.
309321func NewV3Decoder (in v3.Reader , init bool ) * V3Decoder {
310322 dec := V3Decoder {
311- didInit : ! init ,
312- in : in ,
323+ didInit : ! init ,
324+ in : in ,
325+ typeCache : map [string ]map [string ]int {},
313326 }
314327 if init {
315328 dec .Init ()
@@ -543,7 +556,7 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
543556 }
544557 case v3 .Int64T :
545558 val := v3 .Int64FromBytes (v .Value )
546- if e .Kind () != reflect .Int64 || e .Kind () != reflect .Int {
559+ if e .Kind () != reflect .Int64 && e .Kind () != reflect .Int {
547560 if e .Kind () != reflect .Interface || e .Type ().NumMethod () != 0 {
548561 return errors .New ("TT: cannot unmarshal int64 into " + e .Kind ().String () + " Go type" )
549562 }
@@ -647,7 +660,7 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
647660 if v , ok := k .([]byte ); ok {
648661 m [string (v )] = key .Interface ()
649662 } else {
650- m [k ] = key .Interface ()
663+ m [v ] = key .Interface ()
651664 }
652665 }
653666 e .Set (reflect .ValueOf (m ))
@@ -660,9 +673,15 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
660673 }
661674
662675 var err error
663- value := reflect .New ( e . Type (). Elem ()). Elem ()
676+ var value reflect.Value
664677 key := reflect .New (e .Type ().Key ()).Elem ()
665678
679+ ValueKind := e .Type ().Elem ().Kind ()
680+ shouldReplace := ValueKind == reflect .Array || ValueKind == reflect .Slice || ValueKind == reflect .Map
681+
682+ if ! shouldReplace {
683+ value = reflect .New (e .Type ().Elem ()).Elem ()
684+ }
666685 for i := uint64 (0 ); i < children ; i ++ {
667686 v .FromBytes (dec .in )
668687 * yetToRead += v .Childrenn - 1
@@ -671,16 +690,26 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
671690 if err != nil {
672691 return err
673692 }
693+ if shouldReplace {
694+ value = reflect .New (e .Type ().Elem ()).Elem ()
695+ }
674696 err = dec .decodeValuev3 (v , value , yetToRead )
675697 if err != nil {
676698 return err
677699 }
678-
679700 e .SetMapIndex (key , value )
680701 }
681702 } else if e .Kind () == reflect .Struct {
703+
682704 children := v .Childrenn
683- usableFields := getStructFields (e )
705+ name := e .Type ().String ()
706+ var usableFields map [string ]int
707+ if v , ok := dec .typeCache [name ]; ok {
708+ usableFields = v
709+ } else {
710+ usableFields = getStructFields (e )
711+ dec .typeCache [name ] = usableFields
712+ }
684713
685714 for i := uint64 (0 ); i < children ; i ++ {
686715 v .FromBytes (dec .in )
@@ -727,6 +756,8 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
727756 len := e .Len ()
728757 if len < int (children ) {
729758 e .Set (reflect .MakeSlice (e .Type (), int (children ), int (children )))
759+ } else if len > int (children ) {
760+ e .SetLen (int (children ))
730761 }
731762 for i := 0 ; i < int (children ); i ++ {
732763 v .FromBytes (dec .in )
@@ -745,11 +776,19 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
745776 //if all special cases fail we fall back to []interface{}
746777 arr := make ([]interface {}, children )
747778 var err error
748- value := reflect .New (reflect .TypeOf (arr ).Elem ()).Elem ()
779+ var value reflect.Value
780+ ValueKind := e .Type ().Elem ().Kind ()
781+ shouldReplace := ValueKind == reflect .Array || ValueKind == reflect .Slice || ValueKind == reflect .Map
749782
783+ if ! shouldReplace {
784+ value = reflect .New (e .Type ().Elem ()).Elem ()
785+ }
750786 for i := 0 ; i < int (children ); i ++ {
751787 v .FromBytes (dec .in )
752788 * yetToRead += v .Childrenn - 1
789+ if shouldReplace {
790+ value = reflect .New (e .Type ().Elem ()).Elem ()
791+ }
753792
754793 err = dec .decodeValuev3 (v , value , yetToRead )
755794 if err != nil {
0 commit comments