Compare commits

...

4 Commits

Author SHA1 Message Date
Name
f9bd00a6b7
perf(context): optimize getMapFromFormData performance (#4339)
Co-authored-by: 1911860538 <alxps1911@gmail.com>
2025-09-14 07:29:11 +08:00
dependabot[bot]
28172fa682
chore(deps): bump google.golang.org/protobuf from 1.36.6 to 1.36.8 (#4346)
Bumps google.golang.org/protobuf from 1.36.6 to 1.36.8.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-version: 1.36.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-14 07:26:29 +08:00
dependabot[bot]
46150257b3
chore(deps): bump github.com/stretchr/testify from 1.10.0 to 1.11.1 (#4347)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.10.0 to 1.11.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.10.0...v1.11.1)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-version: 1.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-14 07:26:06 +08:00
dependabot[bot]
e7693e67c2
chore(deps): bump actions/setup-go from 5 to 6 (#4351)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-14 07:25:36 +08:00
6 changed files with 108 additions and 14 deletions

View File

@ -20,7 +20,7 @@ jobs:
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: "^1"
- name: Setup golangci-lint
@ -55,7 +55,7 @@ jobs:
GOPROXY: https://proxy.golang.org
steps:
- name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go }}
cache: false

View File

@ -17,7 +17,7 @@ jobs:
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: "^1"
- name: Run GoReleaser

View File

@ -654,14 +654,23 @@ func (c *Context) GetPostFormMap(key string) (map[string]string, bool) {
func getMapFromFormData(m map[string][]string, key string) (map[string]string, bool) {
d := make(map[string]string)
found := false
keyLen := len(key)
for k, v := range m {
if i := strings.IndexByte(k, '['); i >= 1 && k[0:i] == key {
if j := strings.IndexByte(k[i+1:], ']'); j >= 1 {
found = true
d[k[i+1:][:j]] = v[0]
}
if len(k) < keyLen+3 { // key + "[" + at least one char + "]"
continue
}
if k[:keyLen] != key || k[keyLen] != '[' {
continue
}
if j := strings.IndexByte(k[keyLen+1:], ']'); j > 0 {
found = true
d[k[keyLen+1:keyLen+1+j]] = v[0]
}
}
return d, found
}

View File

@ -3554,3 +3554,88 @@ func TestGetMapFromFormData(t *testing.T) {
})
}
}
func BenchmarkGetMapFromFormData(b *testing.B) {
// Test case 1: Small dataset with bracket notation
smallData := map[string][]string{
"ids[a]": {"hi"},
"ids[b]": {"3.14"},
"names[a]": {"mike"},
"names[b]": {"maria"},
}
// Test case 2: Medium dataset with mixed data
mediumData := map[string][]string{
"ids[a]": {"hi"},
"ids[b]": {"3.14"},
"ids[c]": {"test"},
"ids[d]": {"value"},
"names[a]": {"mike"},
"names[b]": {"maria"},
"names[c]": {"john"},
"names[d]": {"jane"},
"other[key1]": {"value1"},
"other[key2]": {"value2"},
"simple": {"data"},
"another": {"info"},
}
// Test case 3: Large dataset with many bracket keys
largeData := make(map[string][]string)
for i := 0; i < 100; i++ {
key := fmt.Sprintf("ids[%d]", i)
largeData[key] = []string{fmt.Sprintf("value%d", i)}
}
for i := 0; i < 50; i++ {
key := fmt.Sprintf("names[%d]", i)
largeData[key] = []string{fmt.Sprintf("name%d", i)}
}
for i := 0; i < 25; i++ {
key := fmt.Sprintf("other[key%d]", i)
largeData[key] = []string{fmt.Sprintf("other%d", i)}
}
// Test case 4: Dataset with many non-matching keys (worst case)
worstCaseData := make(map[string][]string)
for i := 0; i < 100; i++ {
key := fmt.Sprintf("nonmatching%d", i)
worstCaseData[key] = []string{fmt.Sprintf("value%d", i)}
}
worstCaseData["ids[a]"] = []string{"hi"}
worstCaseData["ids[b]"] = []string{"3.14"}
// Test case 5: Dataset with short keys (best case for early exit)
shortKeysData := map[string][]string{
"a": {"value1"},
"b": {"value2"},
"ids[a]": {"hi"},
"ids[b]": {"3.14"},
}
benchmarks := []struct {
name string
data map[string][]string
key string
}{
{"Small_Bracket", smallData, "ids"},
{"Small_Names", smallData, "names"},
{"Medium_Bracket", mediumData, "ids"},
{"Medium_Names", mediumData, "names"},
{"Medium_Other", mediumData, "other"},
{"Large_Bracket", largeData, "ids"},
{"Large_Names", largeData, "names"},
{"Large_Other", largeData, "other"},
{"WorstCase_Bracket", worstCaseData, "ids"},
{"ShortKeys_Bracket", shortKeysData, "ids"},
{"Empty_Key", smallData, "notfound"},
}
for _, bm := range benchmarks {
b.Run(bm.name, func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, _ = getMapFromFormData(bm.data, bm.key)
}
})
}
}

4
go.mod
View File

@ -13,10 +13,10 @@ require (
github.com/modern-go/reflect2 v1.0.2
github.com/pelletier/go-toml/v2 v2.2.4
github.com/quic-go/quic-go v0.54.0
github.com/stretchr/testify v1.10.0
github.com/stretchr/testify v1.11.1
github.com/ugorji/go/codec v1.3.0
golang.org/x/net v0.42.0
google.golang.org/protobuf v1.36.6
google.golang.org/protobuf v1.36.8
)
require (

8
go.sum
View File

@ -57,8 +57,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
@ -82,8 +82,8 @@ golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=