blob: 0aed9d9e318c0ae8a5eb27a3fcd9fdf64b97a515 [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http
import (
"cmp"
"fmt"
"slices"
"strconv"
"testing"
)
func TestMapping(t *testing.T) {
var m mapping[int, string]
for i := 0; i < maxSlice; i++ {
m.add(i, strconv.Itoa(i))
}
if m.m != nil {
t.Fatal("m.m != nil")
}
for i := 0; i < maxSlice; i++ {
g, _ := m.find(i)
w := strconv.Itoa(i)
if g != w {
t.Fatalf("%d: got %s, want %s", i, g, w)
}
}
m.add(4, "4")
if m.s != nil {
t.Fatal("m.s != nil")
}
if m.m == nil {
t.Fatal("m.m == nil")
}
g, _ := m.find(4)
if w := "4"; g != w {
t.Fatalf("got %s, want %s", g, w)
}
}
func TestMappingEachPair(t *testing.T) {
var m mapping[int, string]
var want []entry[int, string]
for i := 0; i < maxSlice*2; i++ {
v := strconv.Itoa(i)
m.add(i, v)
want = append(want, entry[int, string]{i, v})
}
var got []entry[int, string]
m.eachPair(func(k int, v string) bool {
got = append(got, entry[int, string]{k, v})
return true
})
slices.SortFunc(got, func(e1, e2 entry[int, string]) int {
return cmp.Compare(e1.key, e2.key)
})
if !slices.Equal(got, want) {
t.Errorf("got %v, want %v", got, want)
}
}
func BenchmarkFindChild(b *testing.B) {
key := "articles"
children := []string{
"*",
"cmd.html",
"code.html",
"contrib.html",
"contribute.html",
"debugging_with_gdb.html",
"docs.html",
"effective_go.html",
"files.log",
"gccgo_contribute.html",
"gccgo_install.html",
"go-logo-black.png",
"go-logo-blue.png",
"go-logo-white.png",
"go1.1.html",
"go1.2.html",
"go1.html",
"go1compat.html",
"go_faq.html",
"go_mem.html",
"go_spec.html",
"help.html",
"ie.css",
"install-source.html",
"install.html",
"logo-153x55.png",
"Makefile",
"root.html",
"share.png",
"sieve.gif",
"tos.html",
"articles",
}
if len(children) != 32 {
panic("bad len")
}
for _, n := range []int{2, 4, 8, 16, 32} {
list := children[:n]
b.Run(fmt.Sprintf("n=%d", n), func(b *testing.B) {
b.Run("rep=linear", func(b *testing.B) {
var entries []entry[string, any]
for _, c := range list {
entries = append(entries, entry[string, any]{c, nil})
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
findChildLinear(key, entries)
}
})
b.Run("rep=map", func(b *testing.B) {
m := map[string]any{}
for _, c := range list {
m[c] = nil
}
var x any
b.ResetTimer()
for i := 0; i < b.N; i++ {
x = m[key]
}
_ = x
})
b.Run(fmt.Sprintf("rep=hybrid%d", maxSlice), func(b *testing.B) {
var h mapping[string, any]
for _, c := range list {
h.add(c, nil)
}
var x any
b.ResetTimer()
for i := 0; i < b.N; i++ {
x, _ = h.find(key)
}
_ = x
})
})
}
}
func findChildLinear(key string, entries []entry[string, any]) any {
for _, e := range entries {
if key == e.key {
return e.value
}
}
return nil
}