Skip to content

Commit 42a0d6d

Browse files
Dean KarnDean Karn
authored andcommitted
some minor perf with recursion
1 parent 7c2b5d8 commit 42a0d6d

File tree

1 file changed

+62
-27
lines changed

1 file changed

+62
-27
lines changed

util.go

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
// underlying value and it's kind.
1212
func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (reflect.Value, reflect.Kind, bool) {
1313

14+
BEGIN:
1415
switch current.Kind() {
1516
case reflect.Ptr:
1617

@@ -20,7 +21,8 @@ func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (re
2021
return current, reflect.Ptr, nullable
2122
}
2223

23-
return v.extractTypeInternal(current.Elem(), nullable)
24+
current = current.Elem()
25+
goto BEGIN
2426

2527
case reflect.Interface:
2628

@@ -30,7 +32,8 @@ func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (re
3032
return current, reflect.Interface, nullable
3133
}
3234

33-
return v.extractTypeInternal(current.Elem(), nullable)
35+
current = current.Elem()
36+
goto BEGIN
3437

3538
case reflect.Invalid:
3639
return current, reflect.Invalid, nullable
@@ -40,7 +43,8 @@ func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (re
4043
if v.v.hasCustomFuncs {
4144

4245
if fn, ok := v.v.customFuncs[current.Type()]; ok {
43-
return v.extractTypeInternal(reflect.ValueOf(fn(current)), nullable)
46+
current = reflect.ValueOf(fn(current))
47+
goto BEGIN
4448
}
4549
}
4650

@@ -53,23 +57,24 @@ func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (re
5357
//
5458
// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
5559
// could not be retrieved because it didn't exist.
56-
func (v *validate) getStructFieldOKInternal(current reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) {
60+
func (v *validate) getStructFieldOKInternal(val reflect.Value, namespace string) (current reflect.Value, kind reflect.Kind, found bool) {
5761

58-
current, kind, _ := v.ExtractType(current)
62+
BEGIN:
63+
current, kind, _ = v.ExtractType(val)
5964

6065
if kind == reflect.Invalid {
61-
return current, kind, false
66+
return
6267
}
6368

6469
if namespace == "" {
65-
return current, kind, true
70+
found = true
71+
return
6672
}
6773

6874
switch kind {
6975

7076
case reflect.Ptr, reflect.Interface:
71-
72-
return current, kind, false
77+
return
7378

7479
case reflect.Struct:
7580

@@ -95,9 +100,9 @@ func (v *validate) getStructFieldOKInternal(current reflect.Value, namespace str
95100
ns = namespace[bracketIdx:]
96101
}
97102

98-
current = current.FieldByName(fld)
99-
100-
return v.getStructFieldOKInternal(current, ns)
103+
val = current.FieldByName(fld)
104+
namespace = ns
105+
goto BEGIN
101106
}
102107

103108
case reflect.Array, reflect.Slice:
@@ -118,7 +123,9 @@ func (v *validate) getStructFieldOKInternal(current reflect.Value, namespace str
118123
}
119124
}
120125

121-
return v.getStructFieldOKInternal(current.Index(arrIdx), namespace[startIdx:])
126+
val = current.Index(arrIdx)
127+
namespace = namespace[startIdx:]
128+
goto BEGIN
122129

123130
case reflect.Map:
124131
idx := strings.Index(namespace, leftBracket) + 1
@@ -137,48 +144,76 @@ func (v *validate) getStructFieldOKInternal(current reflect.Value, namespace str
137144
switch current.Type().Key().Kind() {
138145
case reflect.Int:
139146
i, _ := strconv.Atoi(key)
140-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
147+
val = current.MapIndex(reflect.ValueOf(i))
148+
namespace = namespace[endIdx+1:]
149+
141150
case reflect.Int8:
142151
i, _ := strconv.ParseInt(key, 10, 8)
143-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(int8(i))), namespace[endIdx+1:])
152+
val = current.MapIndex(reflect.ValueOf(int8(i)))
153+
namespace = namespace[endIdx+1:]
154+
144155
case reflect.Int16:
145156
i, _ := strconv.ParseInt(key, 10, 16)
146-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(int16(i))), namespace[endIdx+1:])
157+
val = current.MapIndex(reflect.ValueOf(int16(i)))
158+
namespace = namespace[endIdx+1:]
159+
147160
case reflect.Int32:
148161
i, _ := strconv.ParseInt(key, 10, 32)
149-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(int32(i))), namespace[endIdx+1:])
162+
val = current.MapIndex(reflect.ValueOf(int32(i)))
163+
namespace = namespace[endIdx+1:]
164+
150165
case reflect.Int64:
151166
i, _ := strconv.ParseInt(key, 10, 64)
152-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
167+
val = current.MapIndex(reflect.ValueOf(i))
168+
namespace = namespace[endIdx+1:]
169+
153170
case reflect.Uint:
154171
i, _ := strconv.ParseUint(key, 10, 0)
155-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(uint(i))), namespace[endIdx+1:])
172+
val = current.MapIndex(reflect.ValueOf(uint(i)))
173+
namespace = namespace[endIdx+1:]
174+
156175
case reflect.Uint8:
157176
i, _ := strconv.ParseUint(key, 10, 8)
158-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(uint8(i))), namespace[endIdx+1:])
177+
val = current.MapIndex(reflect.ValueOf(uint8(i)))
178+
namespace = namespace[endIdx+1:]
179+
159180
case reflect.Uint16:
160181
i, _ := strconv.ParseUint(key, 10, 16)
161-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(uint16(i))), namespace[endIdx+1:])
182+
val = current.MapIndex(reflect.ValueOf(uint16(i)))
183+
namespace = namespace[endIdx+1:]
184+
162185
case reflect.Uint32:
163186
i, _ := strconv.ParseUint(key, 10, 32)
164-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(uint32(i))), namespace[endIdx+1:])
187+
val = current.MapIndex(reflect.ValueOf(uint32(i)))
188+
namespace = namespace[endIdx+1:]
189+
165190
case reflect.Uint64:
166191
i, _ := strconv.ParseUint(key, 10, 64)
167-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:])
192+
val = current.MapIndex(reflect.ValueOf(i))
193+
namespace = namespace[endIdx+1:]
194+
168195
case reflect.Float32:
169196
f, _ := strconv.ParseFloat(key, 32)
170-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(float32(f))), namespace[endIdx+1:])
197+
val = current.MapIndex(reflect.ValueOf(float32(f)))
198+
namespace = namespace[endIdx+1:]
199+
171200
case reflect.Float64:
172201
f, _ := strconv.ParseFloat(key, 64)
173-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(f)), namespace[endIdx+1:])
202+
val = current.MapIndex(reflect.ValueOf(f))
203+
namespace = namespace[endIdx+1:]
204+
174205
case reflect.Bool:
175206
b, _ := strconv.ParseBool(key)
176-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(b)), namespace[endIdx+1:])
207+
val = current.MapIndex(reflect.ValueOf(b))
208+
namespace = namespace[endIdx+1:]
177209

178210
// reflect.Type = string
179211
default:
180-
return v.getStructFieldOKInternal(current.MapIndex(reflect.ValueOf(key)), namespace[endIdx+1:])
212+
val = current.MapIndex(reflect.ValueOf(key))
213+
namespace = namespace[endIdx+1:]
181214
}
215+
216+
goto BEGIN
182217
}
183218

184219
// if got here there was more namespace, cannot go any deeper

0 commit comments

Comments
 (0)