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 5package http 6 7// A mapping is a collection of key-value pairs where the keys are unique. 8// A zero mapping is empty and ready to use. 9// A mapping tries to pick a representation that makes [mapping.find] most efficient. 10type mapping[K comparable, V any] struct { 11 s []entry[K, V] // for few pairs 12 m map[K]V // for many pairs 13} 14 15type entry[K comparable, V any] struct { 16 key K 17 value V 18} 19 20// maxSlice is the maximum number of pairs for which a slice is used. 21// It is a variable for benchmarking. 22var maxSlice int = 8 23 24// add adds a key-value pair to the mapping. 25func (h *mapping[K, V]) add(k K, v V) { 26 if h.m == nil && len(h.s) < maxSlice { 27 h.s = append(h.s, entry[K, V]{k, v}) 28 } else { 29 if h.m == nil { 30 h.m = map[K]V{} 31 for _, e := range h.s { 32 h.m[e.key] = e.value 33 } 34 h.s = nil 35 } 36 h.m[k] = v 37 } 38} 39 40// find returns the value corresponding to the given key. 41// The second return value is false if there is no value 42// with that key. 43func (h *mapping[K, V]) find(k K) (v V, found bool) { 44 if h == nil { 45 return v, false 46 } 47 if h.m != nil { 48 v, found = h.m[k] 49 return v, found 50 } 51 for _, e := range h.s { 52 if e.key == k { 53 return e.value, true 54 } 55 } 56 return v, false 57} 58 59// eachPair calls f for each pair in the mapping. 60// If f returns false, pairs returns immediately. 61func (h *mapping[K, V]) eachPair(f func(k K, v V) bool) { 62 if h == nil { 63 return 64 } 65 if h.m != nil { 66 for k, v := range h.m { 67 if !f(k, v) { 68 return 69 } 70 } 71 } else { 72 for _, e := range h.s { 73 if !f(e.key, e.value) { 74 return 75 } 76 } 77 } 78} 79