Source file src/go/types/trie.go
1 // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. 2 // Source: ../../cmd/compile/internal/types2/trie.go 3 4 // Copyright 2026 The Go Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 package types 9 10 import "sort" 11 12 // A trie[V] maps keys to values V, similar to a map. 13 // A key is a list of integers; two keys collide if one of them is a prefix of the other. 14 // For instance, [1, 2] and [1, 2, 3] collide, but [1, 2, 3] and [1, 2, 4] do not. 15 // If all keys have length 1, a trie degenerates into an ordinary map[int]V. 16 type trie[V any] map[int]any // map value is either trie[V] (non-leaf node), or V (leaf node) 17 18 // insert inserts a value with a key into the trie; key must not be empty. 19 // If key doesn't collide with any other key in the trie, insert succeeds 20 // and returns (val, 0). Otherwise, insert fails and returns (alt, n) where 21 // alt is an unspecified but deterministically chosen value with a colliding 22 // key and n is the length > 0 of the common key prefix. The trie is not 23 // changed in this case. 24 func (tr trie[V]) insert(key []int, val V) (V, int) { 25 // A key serves as the path from the trie root to its corresponding value. 26 for l, index := range key { 27 if v, exists := tr[index]; exists { 28 // An entry already exists for this index; check its type to determine collision. 29 switch v := v.(type) { 30 case trie[V]: 31 // Path continues. 32 // Must check this case first in case V is any which would act as catch-all. 33 tr = v 34 case V: 35 // Collision: An existing key ends here. 36 // This means the existing key is a prefix of (or exactly equal to) key. 37 return v, l + 1 38 case nil: 39 // Handle esoteric case where V is any and val is nil. 40 var zero V 41 return zero, l + 1 42 default: 43 panic("trie.insert: invalid entry") 44 } 45 } else { 46 // Path doesn't exist yet, we need to build it. 47 if l == len(key)-1 { 48 // No prefix collision detected; insert val as a new leaf node. 49 tr[index] = val 50 return val, 0 51 } 52 node := make(trie[V]) 53 tr[index] = node 54 tr = node 55 } 56 } 57 58 if len(key) == 0 { 59 panic("trie.insert: key must not be empty") 60 } 61 62 // Collision: path ends here, but the trie continues. 63 // This means key is a prefix of an existing key. 64 // Return a value from the subtrie. 65 for len(tr) != 0 { 66 // see switch above 67 switch v := tr.pickValue().(type) { 68 case trie[V]: 69 tr = v 70 case V: 71 return v, len(key) 72 case nil: 73 var zero V 74 return zero, len(key) 75 default: 76 panic("trie.insert: invalid entry") 77 } 78 } 79 80 panic("trie.insert: unreachable") 81 } 82 83 // pickValue deterministically picks a value of the trie and returns it. 84 // Only called in case of a collision. 85 // The trie must not be empty. 86 func (tr trie[V]) pickValue() any { 87 var keys []int 88 for k := range tr { 89 keys = append(keys, k) 90 } 91 sort.Ints(keys) // guarantee deterministic element pick 92 return tr[keys[0]] 93 } 94