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