// 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 }