// 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 // A mapping is a collection of key-value pairs where the keys are unique. // A zero mapping is empty and ready to use. // A mapping tries to pick a representation that makes [mapping.find] most efficient. type mapping[K comparable, V any] struct { s []entry[K, V] // for few pairs m map[K]V // for many pairs } type entry[K comparable, V any] struct { key K value V } // maxSlice is the maximum number of pairs for which a slice is used. // It is a variable for benchmarking. var maxSlice int = 8 // add adds a key-value pair to the mapping. func (h *mapping[K, V]) add(k K, v V) { if h.m == nil && len(h.s) < maxSlice { h.s = append(h.s, entry[K, V]{k, v}) } else { if h.m == nil { h.m = map[K]V{} for _, e := range h.s { h.m[e.key] = e.value } h.s = nil } h.m[k] = v } } // find returns the value corresponding to the given key. // The second return value is false if there is no value // with that key. func (h *mapping[K, V]) find(k K) (v V, found bool) { if h == nil { return v, false } if h.m != nil { v, found = h.m[k] return v, found } for _, e := range h.s { if e.key == k { return e.value, true } } return v, false } // eachPair calls f for each pair in the mapping. // If f returns false, pairs returns immediately. func (h *mapping[K, V]) eachPair(f func(k K, v V) bool) { if h == nil { return } if h.m != nil { for k, v := range h.m { if !f(k, v) { return } } } else { for _, e := range h.s { if !f(e.key, e.value) { return } } } }