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

🐛 utils: fix EqualFold and docs #1833

Merged
merged 2 commits into from Mar 23, 2022
Merged
Show file tree
Hide file tree
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
23 changes: 11 additions & 12 deletions utils/bytes.go
Expand Up @@ -4,15 +4,15 @@

package utils

// ToLowerBytes is the equivalent of bytes.ToLower
// ToLowerBytes converts ascii slice to lower-case
func ToLowerBytes(b []byte) []byte {
for i := 0; i < len(b); i++ {
b[i] = toLowerTable[b[i]]
}
return b
}

// ToUpperBytes is the equivalent of bytes.ToUpper
// ToUpperBytes converts ascii slice to upper-case
func ToUpperBytes(b []byte) []byte {
for i := 0; i < len(b); i++ {
b[i] = toUpperTable[b[i]]
Expand Down Expand Up @@ -55,16 +55,15 @@ func TrimBytes(b []byte, cutset byte) []byte {
return b[i : j+1]
}

// EqualFold the equivalent of bytes.EqualFold
func EqualFoldBytes(b, s []byte) (equals bool) {
n := len(b)
equals = n == len(s)
if equals {
for i := 0; i < n; i++ {
if equals = b[i]|0x20 == s[i]|0x20; !equals {
break
}
// EqualFoldBytes tests ascii slices for equality case-insensitively
func EqualFoldBytes(b, s []byte) bool {
if len(b) != len(s) {
return false
}
for i := len(b) - 1; i >= 0; i-- {
if toUpperTable[b[i]] != toUpperTable[s[i]] {
return false
}
}
return
return true
}
23 changes: 12 additions & 11 deletions utils/bytes_test.go
Expand Up @@ -24,20 +24,20 @@ func Test_ToLowerBytes(t *testing.T) {
}

func Benchmark_ToLowerBytes(b *testing.B) {
path := []byte("/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts")
path := []byte(largeStr)
want := []byte(lowerStr)
var res []byte

b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToLowerBytes(path)
}
AssertEqual(b, bytes.Equal(UnsafeBytes("/repos/gofiber/fiber/issues/187643/comments"), res), true)
AssertEqual(b, bytes.Equal(want, res), true)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = bytes.ToLower(path)
}
AssertEqual(b, bytes.Equal(UnsafeBytes("/repos/gofiber/fiber/issues/187643/comments"), res), true)
AssertEqual(b, bytes.Equal(want, res), true)
})
}

Expand All @@ -56,20 +56,20 @@ func Test_ToUpperBytes(t *testing.T) {
}

func Benchmark_ToUpperBytes(b *testing.B) {
path := []byte("/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts")
path := []byte(largeStr)
want := []byte(upperStr)
var res []byte

b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToUpperBytes(path)
}
AssertEqual(b, bytes.Equal(UnsafeBytes("/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS"), res), true)
AssertEqual(b, bytes.Equal(want, res), true)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = bytes.ToUpper(path)
}
AssertEqual(b, bytes.Equal(UnsafeBytes("/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS"), res), true)
AssertEqual(b, bytes.Equal(want, res), true)
})
}

Expand Down Expand Up @@ -182,10 +182,9 @@ func Benchmark_TrimBytes(b *testing.B) {
}

func Benchmark_EqualFoldBytes(b *testing.B) {
left := []byte("/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts")
right := []byte("/RePos/goFiber/Fiber/issues/187643/COMMENTS")
left := []byte(upperStr)
right := []byte(lowerStr)
var res bool

b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = EqualFoldBytes(left, right)
Expand All @@ -210,6 +209,8 @@ func Test_EqualFoldBytes(t *testing.T) {
AssertEqual(t, false, res)
res = EqualFoldBytes([]byte("/dddddd"), []byte("eeeeee"))
AssertEqual(t, false, res)
res = EqualFoldBytes([]byte("\na"), []byte("*A"))
AssertEqual(t, false, res)
res = EqualFoldBytes([]byte("/MY3/NAME/IS/:PARAM/*"), []byte("/my3/name/is/:param/*"))
AssertEqual(t, true, res)
res = EqualFoldBytes([]byte("/MY4/NAME/IS/:PARAM/*"), []byte("/my4/nAME/IS/:param/*"))
Expand Down
23 changes: 11 additions & 12 deletions utils/strings.go
Expand Up @@ -4,7 +4,7 @@

package utils

// ToLower is the equivalent of strings.ToLower
// ToLower converts ascii string to lower-case
func ToLower(b string) string {
res := make([]byte, len(b))
copy(res, b)
Expand All @@ -15,7 +15,7 @@ func ToLower(b string) string {
return UnsafeString(res)
}

// ToUpper is the equivalent of strings.ToUpper
// ToUpper converts ascii string to upper-case
func ToUpper(b string) string {
res := make([]byte, len(b))
copy(res, b)
Expand Down Expand Up @@ -61,16 +61,15 @@ func TrimRight(s string, cutset byte) string {
return s[:lenStr]
}

// EqualFold the equivalent of strings.EqualFold
efectn marked this conversation as resolved.
Show resolved Hide resolved
func EqualFold(b, s string) (equals bool) {
n := len(b)
equals = n == len(s)
if equals {
for i := 0; i < n; i++ {
if equals = b[i]|0x20 == s[i]|0x20; !equals {
break
}
// EqualFold tests ascii strings for equality case-insensitively
func EqualFold(b, s string) bool {
if len(b) != len(s) {
return false
}
for i := len(b) - 1; i >= 0; i-- {
if toUpperTable[b[i]] != toUpperTable[s[i]] {
return false
}
}
return
return true
}
34 changes: 18 additions & 16 deletions utils/strings_test.go
Expand Up @@ -15,21 +15,25 @@ func Test_ToUpper(t *testing.T) {
AssertEqual(t, "/MY/NAME/IS/:PARAM/*", res)
}

const (
largeStr = "/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts/RePos/GoFiBer/FibEr/iSsues/CoMmEnts"
upperStr = "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS/REPOS/GOFIBER/FIBER/ISSUES/COMMENTS"
lowerStr = "/repos/gofiber/fiber/issues/187643/comments/repos/gofiber/fiber/issues/comments"
)

func Benchmark_ToUpper(b *testing.B) {
path := "/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts"
var res string

b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToUpper(path)
res = ToUpper(largeStr)
}
AssertEqual(b, "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS", res)
AssertEqual(b, upperStr, res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.ToUpper(path)
res = strings.ToUpper(largeStr)
}
AssertEqual(b, "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS", res)
AssertEqual(b, upperStr, res)
})
}

Expand All @@ -48,19 +52,18 @@ func Test_ToLower(t *testing.T) {
}

func Benchmark_ToLower(b *testing.B) {
path := "/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts"
var res string
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToLower(path)
res = ToLower(largeStr)
}
AssertEqual(b, "/repos/gofiber/fiber/issues/187643/comments", res)
AssertEqual(b, lowerStr, res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.ToLower(path)
res = strings.ToLower(largeStr)
}
AssertEqual(b, "/repos/gofiber/fiber/issues/187643/comments", res)
AssertEqual(b, lowerStr, res)
})
}

Expand Down Expand Up @@ -180,19 +183,16 @@ func Benchmark_Trim(b *testing.B) {

// go test -v -run=^$ -bench=Benchmark_EqualFold -benchmem -count=4
func Benchmark_EqualFold(b *testing.B) {
left := "/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts"
right := "/RePos/goFiber/Fiber/issues/187643/COMMENTS"
var res bool

b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = EqualFold(left, right)
res = EqualFold(upperStr, lowerStr)
}
AssertEqual(b, true, res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.EqualFold(left, right)
res = strings.EqualFold(upperStr, lowerStr)
}
AssertEqual(b, true, res)
})
Expand All @@ -208,6 +208,8 @@ func Test_EqualFold(t *testing.T) {
AssertEqual(t, false, res)
res = EqualFold("/dddddd", "eeeeee")
AssertEqual(t, false, res)
res = EqualFold("\na", "*A")
AssertEqual(t, false, res)
res = EqualFold("/MY3/NAME/IS/:PARAM/*", "/my3/name/is/:param/*")
AssertEqual(t, true, res)
res = EqualFold("/MY4/NAME/IS/:PARAM/*", "/my4/nAME/IS/:param/*")
Expand Down