diff options
| author | Keith Randall <khr@golang.org> | 2025-06-11 17:14:59 -0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-07-24 09:04:22 -0700 |
| commit | 6505fcbd0aaba2ab39915dcf437f01f1af83cd25 (patch) | |
| tree | 1194ec62192e5453160515cd75ee70586ff52a0c /src/cmd/compile/internal/ssa/sparsemap.go | |
| parent | 14f5eb781231bcd1b892c76e04db559caee59a6a (diff) | |
| download | go-6505fcbd0aaba2ab39915dcf437f01f1af83cd25.tar.xz | |
cmd/compile: use generics for sparse map
So it is easier to reuse this code with different key/value types.
Change-Id: I5a9e669769cf359b32f2fe784594868acdee4d02
Reviewed-on: https://go-review.googlesource.com/c/go/+/681175
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/sparsemap.go')
| -rw-r--r-- | src/cmd/compile/internal/ssa/sparsemap.go | 68 |
1 files changed, 33 insertions, 35 deletions
diff --git a/src/cmd/compile/internal/ssa/sparsemap.go b/src/cmd/compile/internal/ssa/sparsemap.go index 9443c8b4b4..b7363b36eb 100644 --- a/src/cmd/compile/internal/ssa/sparsemap.go +++ b/src/cmd/compile/internal/ssa/sparsemap.go @@ -7,70 +7,60 @@ package ssa // from https://research.swtch.com/sparse // in turn, from Briggs and Torczon -type sparseEntry struct { - key ID - val int32 +// sparseKey needs to be something we can index a slice with. +type sparseKey interface{ ~int | ~int32 } + +type sparseEntry[K sparseKey, V any] struct { + key K + val V } -type sparseMap struct { - dense []sparseEntry +type genericSparseMap[K sparseKey, V any] struct { + dense []sparseEntry[K, V] sparse []int32 } -// newSparseMap returns a sparseMap that can map -// integers between 0 and n-1 to int32s. -func newSparseMap(n int) *sparseMap { - return &sparseMap{dense: nil, sparse: make([]int32, n)} +// newGenericSparseMap returns a sparseMap that can map +// integers between 0 and n-1 to a value type. +func newGenericSparseMap[K sparseKey, V any](n int) *genericSparseMap[K, V] { + return &genericSparseMap[K, V]{dense: nil, sparse: make([]int32, n)} } -func (s *sparseMap) cap() int { +func (s *genericSparseMap[K, V]) cap() int { return len(s.sparse) } -func (s *sparseMap) size() int { +func (s *genericSparseMap[K, V]) size() int { return len(s.dense) } -func (s *sparseMap) contains(k ID) bool { +func (s *genericSparseMap[K, V]) contains(k K) bool { i := s.sparse[k] return i < int32(len(s.dense)) && s.dense[i].key == k } -// get returns the value for key k, or -1 if k does -// not appear in the map. -func (s *sparseMap) get(k ID) int32 { +// get returns the value for key k, or the zero V +// if k does not appear in the map. +func (s *genericSparseMap[K, V]) get(k K) V { i := s.sparse[k] if i < int32(len(s.dense)) && s.dense[i].key == k { return s.dense[i].val } - return -1 + var v V + return v } -func (s *sparseMap) set(k ID, v int32) { +func (s *genericSparseMap[K, V]) set(k K, v V) { i := s.sparse[k] if i < int32(len(s.dense)) && s.dense[i].key == k { s.dense[i].val = v return } - s.dense = append(s.dense, sparseEntry{k, v}) - s.sparse[k] = int32(len(s.dense)) - 1 -} - -// setBit sets the v'th bit of k's value, where 0 <= v < 32 -func (s *sparseMap) setBit(k ID, v uint) { - if v >= 32 { - panic("bit index too large.") - } - i := s.sparse[k] - if i < int32(len(s.dense)) && s.dense[i].key == k { - s.dense[i].val |= 1 << v - return - } - s.dense = append(s.dense, sparseEntry{k, 1 << v}) + s.dense = append(s.dense, sparseEntry[K, V]{k, v}) s.sparse[k] = int32(len(s.dense)) - 1 } -func (s *sparseMap) remove(k ID) { +func (s *genericSparseMap[K, V]) remove(k K) { i := s.sparse[k] if i < int32(len(s.dense)) && s.dense[i].key == k { y := s.dense[len(s.dense)-1] @@ -80,10 +70,18 @@ func (s *sparseMap) remove(k ID) { } } -func (s *sparseMap) clear() { +func (s *genericSparseMap[K, V]) clear() { s.dense = s.dense[:0] } -func (s *sparseMap) contents() []sparseEntry { +func (s *genericSparseMap[K, V]) contents() []sparseEntry[K, V] { return s.dense } + +type sparseMap = genericSparseMap[ID, int32] + +// newSparseMap returns a sparseMap that can map +// integers between 0 and n-1 to int32s. +func newSparseMap(n int) *sparseMap { + return newGenericSparseMap[ID, int32](n) +} |
