Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid unnecessary memory allocations in decodeMapFromStruct #188

Merged
merged 1 commit into from May 1, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 18 additions & 30 deletions mapstructure.go
Expand Up @@ -840,42 +840,31 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
}

tagValue := f.Tag.Get(d.config.TagName)
tagParts := strings.Split(tagValue, ",")

// If "omitempty" is specified in the tag, it ignores empty values.
omitempty := false
for _, tag := range tagParts[1:] {
if tag == "omitempty" {
omitempty = true
break
}
}
if omitempty && isEmptyValue(v) {
continue
}

// Determine the name of the key in the map
keyName := f.Name
if tagParts[0] != "" {
if tagParts[0] == "-" {
continue
}
keyName = tagParts[0]
}

// If Squash is set in the config, we squash the field down.
squash := d.config.Squash && v.Kind() == reflect.Struct
// If "squash" is specified in the tag, we squash the field down.
if !squash {
for _, tag := range tagParts[1:] {
if tag == "squash" {
squash = true
break
}
// Determine the name of the key in the map
if index := strings.Index(tagValue, ","); index != -1 {
if tagValue[:index] == "-" {
continue;
}
// If "omitempty" is specified in the tag, it ignores empty values.
if strings.Index(tagValue[index + 1:], "omitempty") != -1 && isEmptyValue(v) {
continue
}

// If "squash" is specified in the tag, we squash the field down.
squash = !squash && strings.Index(tagValue[index + 1:], "squash") != -1
if squash && v.Kind() != reflect.Struct {
return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
}
keyName = tagValue[:index]
} else if len(tagValue) > 0 {
if tagValue == "-" {
continue
}
keyName = tagValue
}

switch v.Kind() {
Expand Down Expand Up @@ -1226,9 +1215,8 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
}

// Build our field
fieldCurrent := field{fieldType, structVal.Field(i)}
if remain {
remainField = &fieldCurrent
remainField = &field{fieldType, structVal.Field(i)}
} else {
// Normal struct field, store it away
fields = append(fields, field{fieldType, structVal.Field(i)})
Expand Down