Source file src/net/http/mapping_test.go

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package http
     6  
     7  import (
     8  	"cmp"
     9  	"fmt"
    10  	"slices"
    11  	"strconv"
    12  	"testing"
    13  )
    14  
    15  func TestMapping(t *testing.T) {
    16  	var m mapping[int, string]
    17  	for i := 0; i < maxSlice; i++ {
    18  		m.add(i, strconv.Itoa(i))
    19  	}
    20  	if m.m != nil {
    21  		t.Fatal("m.m != nil")
    22  	}
    23  	for i := 0; i < maxSlice; i++ {
    24  		g, _ := m.find(i)
    25  		w := strconv.Itoa(i)
    26  		if g != w {
    27  			t.Fatalf("%d: got %s, want %s", i, g, w)
    28  		}
    29  	}
    30  	m.add(4, "4")
    31  	if m.s != nil {
    32  		t.Fatal("m.s != nil")
    33  	}
    34  	if m.m == nil {
    35  		t.Fatal("m.m == nil")
    36  	}
    37  	g, _ := m.find(4)
    38  	if w := "4"; g != w {
    39  		t.Fatalf("got %s, want %s", g, w)
    40  	}
    41  }
    42  
    43  func TestMappingEachPair(t *testing.T) {
    44  	var m mapping[int, string]
    45  	var want []entry[int, string]
    46  	for i := 0; i < maxSlice*2; i++ {
    47  		v := strconv.Itoa(i)
    48  		m.add(i, v)
    49  		want = append(want, entry[int, string]{i, v})
    50  
    51  	}
    52  
    53  	var got []entry[int, string]
    54  	m.eachPair(func(k int, v string) bool {
    55  		got = append(got, entry[int, string]{k, v})
    56  		return true
    57  	})
    58  	slices.SortFunc(got, func(e1, e2 entry[int, string]) int {
    59  		return cmp.Compare(e1.key, e2.key)
    60  	})
    61  	if !slices.Equal(got, want) {
    62  		t.Errorf("got %v, want %v", got, want)
    63  	}
    64  }
    65  
    66  func BenchmarkFindChild(b *testing.B) {
    67  	key := "articles"
    68  	children := []string{
    69  		"*",
    70  		"cmd.html",
    71  		"code.html",
    72  		"contrib.html",
    73  		"contribute.html",
    74  		"debugging_with_gdb.html",
    75  		"docs.html",
    76  		"effective_go.html",
    77  		"files.log",
    78  		"gccgo_contribute.html",
    79  		"gccgo_install.html",
    80  		"go-logo-black.png",
    81  		"go-logo-blue.png",
    82  		"go-logo-white.png",
    83  		"go1.1.html",
    84  		"go1.2.html",
    85  		"go1.html",
    86  		"go1compat.html",
    87  		"go_faq.html",
    88  		"go_mem.html",
    89  		"go_spec.html",
    90  		"help.html",
    91  		"ie.css",
    92  		"install-source.html",
    93  		"install.html",
    94  		"logo-153x55.png",
    95  		"Makefile",
    96  		"root.html",
    97  		"share.png",
    98  		"sieve.gif",
    99  		"tos.html",
   100  		"articles",
   101  	}
   102  	if len(children) != 32 {
   103  		panic("bad len")
   104  	}
   105  	for _, n := range []int{2, 4, 8, 16, 32} {
   106  		list := children[:n]
   107  		b.Run(fmt.Sprintf("n=%d", n), func(b *testing.B) {
   108  
   109  			b.Run("rep=linear", func(b *testing.B) {
   110  				var entries []entry[string, any]
   111  				for _, c := range list {
   112  					entries = append(entries, entry[string, any]{c, nil})
   113  				}
   114  				b.ResetTimer()
   115  				for i := 0; i < b.N; i++ {
   116  					findChildLinear(key, entries)
   117  				}
   118  			})
   119  			b.Run("rep=map", func(b *testing.B) {
   120  				m := map[string]any{}
   121  				for _, c := range list {
   122  					m[c] = nil
   123  				}
   124  				var x any
   125  				b.ResetTimer()
   126  				for i := 0; i < b.N; i++ {
   127  					x = m[key]
   128  				}
   129  				_ = x
   130  			})
   131  			b.Run(fmt.Sprintf("rep=hybrid%d", maxSlice), func(b *testing.B) {
   132  				var h mapping[string, any]
   133  				for _, c := range list {
   134  					h.add(c, nil)
   135  				}
   136  				var x any
   137  				b.ResetTimer()
   138  				for i := 0; i < b.N; i++ {
   139  					x, _ = h.find(key)
   140  				}
   141  				_ = x
   142  			})
   143  		})
   144  	}
   145  }
   146  
   147  func findChildLinear(key string, entries []entry[string, any]) any {
   148  	for _, e := range entries {
   149  		if key == e.key {
   150  			return e.value
   151  		}
   152  	}
   153  	return nil
   154  }
   155  

View as plain text