Browse Source

codec: refactor decode to move decArrayCannotExpand to dedicated function

Ugorji Nwoke 6 years ago
parent
commit
049e534137
3 changed files with 43 additions and 51 deletions
  1. 27 11
      codec/decode.go
  2. 15 27
      codec/fast-path.generated.go
  3. 1 13
      codec/fast-path.go.tmpl

+ 27 - 11
codec/decode.go

@@ -659,6 +659,10 @@ func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
 }
 
 func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
+	// if f.seq == seqTypeArray {
+	// 	xdebugf("decoder.kSlice: %v, %#v", rv.Type(), rv)
+	// }
+
 	// A slice can be set from a map or array in stream.
 	// This way, the order can be kept (as order is lost with map).
 
@@ -771,21 +775,13 @@ func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 				d.errorf("cannot decode into non-settable slice")
 			}
 		}
-		slh.ElemContainerState(j)
 		// if indefinite, etc, then expand the slice if necessary
 		if j >= rvlen {
 			if f.seq == seqTypeArray {
-				d.arrayCannotExpand(rvlen, j+1)
-				// drain completely and return
-				d.swallow()
-				j++
-				for ; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
-					slh.ElemContainerState(j)
-					d.swallow()
-				}
-				slh.End()
+				decArrayCannotExpand(slh, hasLen, rvlen, j, containerLenS)
 				return
 			}
+			slh.ElemContainerState(j)
 			// rv = reflect.Append(rv, reflect.Zero(rtelem0)) // append logic + varargs
 
 			// expand the slice up to the cap.
@@ -807,13 +803,20 @@ func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 					d.errorf(errmsgExpandSliceCannotChange)
 					return
 				}
-				rvcap = growCap(rvcap, rtelem0Size, rvcap)
+				// rvcap2 := rvcap
+				rvcap = growCap(rvcap, rtelem0Size, 1)
+				// if rvcap < 32 {
+				// 	rvcap = 32
+				// }
+				// xdebugf("%v: growing cap from %v to %v (unit size: %v)", rtelem, rvcap2, rvcap, rtelem0Size)
 				rv9 = reflect.MakeSlice(f.ti.rt, rvcap, rvcap)
 				rvCopySlice(rv9, rv)
 				rv = rv9
 				rvChanged = true
 				rvlen = rvcap
 			}
+		} else {
+			slh.ElemContainerState(j)
 		}
 		rv9 = rvSliceIndex(rv, j, f.ti)
 		if d.h.SliceElementReset {
@@ -1998,3 +2001,16 @@ func fauxUnionReadRawBytes(dr decDriver, d *Decoder, n *fauxUnion, rawToString b
 		n.l = dr.DecodeBytes(nil, false)
 	}
 }
+
+func decArrayCannotExpand(slh decSliceHelper, hasLen bool, lenv, j, containerLenS int) {
+	slh.d.arrayCannotExpand(lenv, j+1)
+	// drain completely and return
+	slh.ElemContainerState(j)
+	slh.d.swallow()
+	j++
+	for ; (hasLen && j < containerLenS) || !(hasLen || slh.d.checkBreak()); j++ {
+		slh.ElemContainerState(j)
+		slh.d.swallow()
+	}
+	slh.End()
+}

+ 15 - 27
codec/fast-path.generated.go

@@ -4264,7 +4264,7 @@ func (fastpathT) DecSliceIntfN(v []interface{}, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -4361,7 +4361,7 @@ func (fastpathT) DecSliceStringN(v []string, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -4458,7 +4458,7 @@ func (fastpathT) DecSliceBytesN(v [][]byte, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -4555,7 +4555,7 @@ func (fastpathT) DecSliceFloat32N(v []float32, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -4652,7 +4652,7 @@ func (fastpathT) DecSliceFloat64N(v []float64, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -4749,7 +4749,7 @@ func (fastpathT) DecSliceUintN(v []uint, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -4846,7 +4846,7 @@ func (fastpathT) DecSliceUint16N(v []uint16, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -4943,7 +4943,7 @@ func (fastpathT) DecSliceUint32N(v []uint32, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -5040,7 +5040,7 @@ func (fastpathT) DecSliceUint64N(v []uint64, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -5137,7 +5137,7 @@ func (fastpathT) DecSliceIntN(v []int, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -5234,7 +5234,7 @@ func (fastpathT) DecSliceInt8N(v []int8, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -5331,7 +5331,7 @@ func (fastpathT) DecSliceInt16N(v []int16, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -5428,7 +5428,7 @@ func (fastpathT) DecSliceInt32N(v []int32, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -5525,7 +5525,7 @@ func (fastpathT) DecSliceInt64N(v []int64, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -5622,7 +5622,7 @@ func (fastpathT) DecSliceBoolN(v []bool, d *Decoder) {
 	hasLen := containerLenS > 0
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		}
 		slh.ElemContainerState(j)
@@ -5630,18 +5630,6 @@ func (fastpathT) DecSliceBoolN(v []bool, d *Decoder) {
 	}
 	slh.End()
 }
-func fastpathDecArrayCannotExpand(slh decSliceHelper, hasLen bool, lenv, j, containerLenS int) {
-	slh.d.arrayCannotExpand(lenv, j+1)
-	slh.ElemContainerState(j)
-	slh.d.swallow()
-	j++
-	for ; (hasLen && j < containerLenS) || !(hasLen || slh.d.checkBreak()); j++ {
-		slh.ElemContainerState(j)
-		slh.d.swallow()
-	}
-	slh.End()
-}
-
 func (d *Decoder) fastpathDecMapStringIntfR(f *codecFnInfo, rv reflect.Value) {
 	containerLen := d.mapStart()
 	if containerLen == decContainerLenNil {

+ 1 - 13
codec/fast-path.go.tmpl

@@ -404,7 +404,7 @@ func (fastpathT) {{ .MethodNamePfx "Dec" false }}N(v []{{ .Elem }}, d *Decoder)
 	for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
 		{{/* // if indefinite, etc, then expand the slice if necessary */ -}}
 		if j >= len(v) {
-			fastpathDecArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
+			decArrayCannotExpand(slh, hasLen, len(v), j, containerLenS)
 			return
 		} 
 		slh.ElemContainerState(j)
@@ -418,18 +418,6 @@ func (fastpathT) {{ .MethodNamePfx "Dec" false }}N(v []{{ .Elem }}, d *Decoder)
 }
 {{end}}{{end}}{{end -}}
 
-func fastpathDecArrayCannotExpand(slh decSliceHelper, hasLen bool, lenv, j, containerLenS int) {
-	slh.d.arrayCannotExpand(lenv, j+1)
-	slh.ElemContainerState(j)
-	slh.d.swallow()
-	j++
-	for ; (hasLen && j < containerLenS) || !(hasLen || slh.d.checkBreak()); j++ {
-		slh.ElemContainerState(j)
-		slh.d.swallow()
-	}
-	slh.End()
-}
-
 {{range .Values}}{{if not .Primitive}}{{if .MapKey -}}
 {{/*
 Maps can change if they are