Skip to content

Commit 1e4b5a1

Browse files
Widen key constraint to 'any' for maps and sets
1 parent 55aabf3 commit 1e4b5a1

File tree

2 files changed

+49
-50
lines changed

2 files changed

+49
-50
lines changed

immutable.go

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ const (
684684
// to generate hashes and check for equality of key values.
685685
//
686686
// It is implemented as an Hash Array Mapped Trie.
687-
type Map[K comparable, V any] struct {
687+
type Map[K, V any] struct {
688688
size int // total number of key/value pairs
689689
root mapNode[K, V] // root node of trie
690690
hasher Hasher[K] // hasher implementation
@@ -693,7 +693,7 @@ type Map[K comparable, V any] struct {
693693
// NewMap returns a new instance of Map. If hasher is nil, a default hasher
694694
// implementation will automatically be chosen based on the first key added.
695695
// Default hasher implementations only exist for int, string, and byte slice types.
696-
func NewMap[K comparable, V any](hasher Hasher[K]) *Map[K, V] {
696+
func NewMap[K, V any](hasher Hasher[K]) *Map[K, V] {
697697
return &Map[K, V]{
698698
hasher: hasher,
699699
}
@@ -814,12 +814,12 @@ func (m *Map[K, V]) Iterator() *MapIterator[K, V] {
814814
}
815815

816816
// MapBuilder represents an efficient builder for creating Maps.
817-
type MapBuilder[K comparable, V any] struct {
817+
type MapBuilder[K, V any] struct {
818818
m *Map[K, V] // current state
819819
}
820820

821821
// NewMapBuilder returns a new instance of MapBuilder.
822-
func NewMapBuilder[K comparable, V any](hasher Hasher[K]) *MapBuilder[K, V] {
822+
func NewMapBuilder[K, V any](hasher Hasher[K]) *MapBuilder[K, V] {
823823
return &MapBuilder[K, V]{m: NewMap[K, V](hasher)}
824824
}
825825

@@ -863,7 +863,7 @@ func (b *MapBuilder[K, V]) Iterator() *MapIterator[K, V] {
863863
}
864864

865865
// mapNode represents any node in the map tree.
866-
type mapNode[K comparable, V any] interface {
866+
type mapNode[K, V any] interface {
867867
get(key K, shift uint, keyHash uint32, h Hasher[K]) (value V, ok bool)
868868
set(key K, value V, shift uint, keyHash uint32, h Hasher[K], mutable bool, resized *bool) mapNode[K, V]
869869
delete(key K, shift uint, keyHash uint32, h Hasher[K], mutable bool, resized *bool) mapNode[K, V]
@@ -876,7 +876,7 @@ var _ mapNode[string, any] = (*mapValueNode[string, any])(nil)
876876
var _ mapNode[string, any] = (*mapHashCollisionNode[string, any])(nil)
877877

878878
// mapLeafNode represents a node that stores a single key hash at the leaf of the map tree.
879-
type mapLeafNode[K comparable, V any] interface {
879+
type mapLeafNode[K, V any] interface {
880880
mapNode[K, V]
881881
keyHashValue() uint32
882882
}
@@ -887,7 +887,7 @@ var _ mapLeafNode[string, any] = (*mapHashCollisionNode[string, any])(nil)
887887
// mapArrayNode is a map node that stores key/value pairs in a slice.
888888
// Entries are stored in insertion order. An array node expands into a bitmap
889889
// indexed node once a given threshold size is crossed.
890-
type mapArrayNode[K comparable, V any] struct {
890+
type mapArrayNode[K, V any] struct {
891891
entries []mapEntry[K, V]
892892
}
893893

@@ -989,7 +989,7 @@ func (n *mapArrayNode[K, V]) delete(key K, shift uint, keyHash uint32, h Hasher[
989989
// mapBitmapIndexedNode represents a map branch node with a variable number of
990990
// node slots and indexed using a bitmap. Indexes for the node slots are
991991
// calculated by counting the number of set bits before the target bit using popcount.
992-
type mapBitmapIndexedNode[K comparable, V any] struct {
992+
type mapBitmapIndexedNode[K, V any] struct {
993993
bitmap uint32
994994
nodes []mapNode[K, V]
995995
}
@@ -1028,7 +1028,7 @@ func (n *mapBitmapIndexedNode[K, V]) set(key K, value V, shift uint, keyHash uin
10281028
if exists {
10291029
newNode = n.nodes[idx].set(key, value, shift+mapNodeBits, keyHash, h, mutable, resized)
10301030
} else {
1031-
newNode = newMapValueNode[K, V](keyHash, key, value)
1031+
newNode = newMapValueNode(keyHash, key, value)
10321032
}
10331033

10341034
// Convert to a hash-array node once we exceed the max bitmap size.
@@ -1135,7 +1135,7 @@ func (n *mapBitmapIndexedNode[K, V]) delete(key K, shift uint, keyHash uint32, h
11351135

11361136
// mapHashArrayNode is a map branch node that stores nodes in a fixed length
11371137
// array. Child nodes are indexed by their index bit segment for the current depth.
1138-
type mapHashArrayNode[K comparable, V any] struct {
1138+
type mapHashArrayNode[K, V any] struct {
11391139
count uint // number of set nodes
11401140
nodes [mapNodeSize]mapNode[K, V] // child node slots, may contain empties
11411141
}
@@ -1231,14 +1231,14 @@ func (n *mapHashArrayNode[K, V]) delete(key K, shift uint, keyHash uint32, h Has
12311231
// mapValueNode represents a leaf node with a single key/value pair.
12321232
// A value node can be converted to a hash collision leaf node if a different
12331233
// key with the same keyHash is inserted.
1234-
type mapValueNode[K comparable, V any] struct {
1234+
type mapValueNode[K, V any] struct {
12351235
keyHash uint32
12361236
key K
12371237
value V
12381238
}
12391239

12401240
// newMapValueNode returns a new instance of mapValueNode.
1241-
func newMapValueNode[K comparable, V any](keyHash uint32, key K, value V) *mapValueNode[K, V] {
1241+
func newMapValueNode[K, V any](keyHash uint32, key K, value V) *mapValueNode[K, V] {
12421242
return &mapValueNode[K, V]{
12431243
keyHash: keyHash,
12441244
key: key,
@@ -1303,7 +1303,7 @@ func (n *mapValueNode[K, V]) delete(key K, shift uint, keyHash uint32, h Hasher[
13031303

13041304
// mapHashCollisionNode represents a leaf node that contains two or more key/value
13051305
// pairs with the same key hash. Single pairs for a hash are stored as value nodes.
1306-
type mapHashCollisionNode[K comparable, V any] struct {
1306+
type mapHashCollisionNode[K, V any] struct {
13071307
keyHash uint32 // key hash for all entries
13081308
entries []mapEntry[K, V]
13091309
}
@@ -1409,7 +1409,7 @@ func (n *mapHashCollisionNode[K, V]) delete(key K, shift uint, keyHash uint32, h
14091409

14101410
// mergeIntoNode merges a key/value pair into an existing node.
14111411
// Caller must verify that node's keyHash is not equal to keyHash.
1412-
func mergeIntoNode[K comparable, V any](node mapLeafNode[K, V], shift uint, keyHash uint32, key K, value V) mapNode[K, V] {
1412+
func mergeIntoNode[K, V any](node mapLeafNode[K, V], shift uint, keyHash uint32, key K, value V) mapNode[K, V] {
14131413
idx1 := (node.keyHashValue() >> shift) & mapNodeMask
14141414
idx2 := (keyHash >> shift) & mapNodeMask
14151415

@@ -1428,14 +1428,14 @@ func mergeIntoNode[K comparable, V any](node mapLeafNode[K, V], shift uint, keyH
14281428
}
14291429

14301430
// mapEntry represents a single key/value pair.
1431-
type mapEntry[K comparable, V any] struct {
1431+
type mapEntry[K, V any] struct {
14321432
key K
14331433
value V
14341434
}
14351435

14361436
// MapIterator represents an iterator over a map's key/value pairs. Although
14371437
// map keys are not sorted, the iterator's order is deterministic.
1438-
type MapIterator[K comparable, V any] struct {
1438+
type MapIterator[K, V any] struct {
14391439
m *Map[K, V] // source map
14401440

14411441
stack [32]mapIteratorElem[K, V] // search stack
@@ -1559,7 +1559,7 @@ func (itr *MapIterator[K, V]) first() {
15591559
}
15601560

15611561
// mapIteratorElem represents a node/index pair in the MapIterator stack.
1562-
type mapIteratorElem[K comparable, V any] struct {
1562+
type mapIteratorElem[K, V any] struct {
15631563
node mapNode[K, V]
15641564
index int
15651565
}
@@ -1573,7 +1573,7 @@ const (
15731573
// is determined by the Comparer used by the map.
15741574
//
15751575
// This map is implemented as a B+tree.
1576-
type SortedMap[K comparable, V any] struct {
1576+
type SortedMap[K, V any] struct {
15771577
size int // total number of key/value pairs
15781578
root sortedMapNode[K, V] // root of b+tree
15791579
comparer Comparer[K]
@@ -1582,7 +1582,7 @@ type SortedMap[K comparable, V any] struct {
15821582
// NewSortedMap returns a new instance of SortedMap. If comparer is nil then
15831583
// a default comparer is set after the first key is inserted. Default comparers
15841584
// exist for int, string, and byte slice keys.
1585-
func NewSortedMap[K comparable, V any](comparer Comparer[K]) *SortedMap[K, V] {
1585+
func NewSortedMap[K, V any](comparer Comparer[K]) *SortedMap[K, V] {
15861586
return &SortedMap[K, V]{
15871587
comparer: comparer,
15881588
}
@@ -1705,12 +1705,12 @@ func (m *SortedMap[K, V]) Iterator() *SortedMapIterator[K, V] {
17051705
}
17061706

17071707
// SortedMapBuilder represents an efficient builder for creating sorted maps.
1708-
type SortedMapBuilder[K comparable, V any] struct {
1708+
type SortedMapBuilder[K, V any] struct {
17091709
m *SortedMap[K, V] // current state
17101710
}
17111711

17121712
// NewSortedMapBuilder returns a new instance of SortedMapBuilder.
1713-
func NewSortedMapBuilder[K comparable, V any](comparer Comparer[K]) *SortedMapBuilder[K, V] {
1713+
func NewSortedMapBuilder[K, V any](comparer Comparer[K]) *SortedMapBuilder[K, V] {
17141714
return &SortedMapBuilder[K, V]{m: NewSortedMap[K, V](comparer)}
17151715
}
17161716

@@ -1754,7 +1754,7 @@ func (b *SortedMapBuilder[K, V]) Iterator() *SortedMapIterator[K, V] {
17541754
}
17551755

17561756
// sortedMapNode represents a branch or leaf node in the sorted map.
1757-
type sortedMapNode[K comparable, V any] interface {
1757+
type sortedMapNode[K, V any] interface {
17581758
minKey() K
17591759
indexOf(key K, c Comparer[K]) int
17601760
get(key K, c Comparer[K]) (value V, ok bool)
@@ -1766,12 +1766,12 @@ var _ sortedMapNode[string, any] = (*sortedMapBranchNode[string, any])(nil)
17661766
var _ sortedMapNode[string, any] = (*sortedMapLeafNode[string, any])(nil)
17671767

17681768
// sortedMapBranchNode represents a branch in the sorted map.
1769-
type sortedMapBranchNode[K comparable, V any] struct {
1769+
type sortedMapBranchNode[K, V any] struct {
17701770
elems []sortedMapBranchElem[K, V]
17711771
}
17721772

17731773
// newSortedMapBranchNode returns a new branch node with the given child nodes.
1774-
func newSortedMapBranchNode[K comparable, V any](children ...sortedMapNode[K, V]) *sortedMapBranchNode[K, V] {
1774+
func newSortedMapBranchNode[K, V any](children ...sortedMapNode[K, V]) *sortedMapBranchNode[K, V] {
17751775
// Fetch min keys for every child.
17761776
elems := make([]sortedMapBranchElem[K, V], len(children))
17771777
for i, child := range children {
@@ -1914,13 +1914,13 @@ func (n *sortedMapBranchNode[K, V]) delete(key K, c Comparer[K], mutable bool, r
19141914
return other
19151915
}
19161916

1917-
type sortedMapBranchElem[K comparable, V any] struct {
1917+
type sortedMapBranchElem[K, V any] struct {
19181918
key K
19191919
node sortedMapNode[K, V]
19201920
}
19211921

19221922
// sortedMapLeafNode represents a leaf node in the sorted map.
1923-
type sortedMapLeafNode[K comparable, V any] struct {
1923+
type sortedMapLeafNode[K, V any] struct {
19241924
entries []mapEntry[K, V]
19251925
}
19261926

@@ -2035,7 +2035,7 @@ func (n *sortedMapLeafNode[K, V]) delete(key K, c Comparer[K], mutable bool, res
20352035

20362036
// SortedMapIterator represents an iterator over a sorted map.
20372037
// Iteration can occur in natural or reverse order based on use of Next() or Prev().
2038-
type SortedMapIterator[K comparable, V any] struct {
2038+
type SortedMapIterator[K, V any] struct {
20392039
m *SortedMap[K, V] // source map
20402040

20412041
stack [32]sortedMapIteratorElem[K, V] // search stack
@@ -2223,13 +2223,13 @@ func (itr *SortedMapIterator[K, V]) seek(key K) {
22232223
}
22242224

22252225
// sortedMapIteratorElem represents node/index pair in the SortedMapIterator stack.
2226-
type sortedMapIteratorElem[K comparable, V any] struct {
2226+
type sortedMapIteratorElem[K, V any] struct {
22272227
node sortedMapNode[K, V]
22282228
index int
22292229
}
22302230

22312231
// Hasher hashes keys and checks them for equality.
2232-
type Hasher[K comparable] interface {
2232+
type Hasher[K any] interface {
22332233
// Computes a hash for key.
22342234
Hash(key K) uint32
22352235

@@ -2238,7 +2238,7 @@ type Hasher[K comparable] interface {
22382238
}
22392239

22402240
// NewHasher returns the built-in hasher for a given key type.
2241-
func NewHasher[K comparable](key K) Hasher[K] {
2241+
func NewHasher[K any](key K) Hasher[K] {
22422242
// Attempt to use non-reflection based hasher first.
22432243
switch (any(key)).(type) {
22442244
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, string:
@@ -2267,7 +2267,7 @@ func hashString(value string) uint32 {
22672267
}
22682268

22692269
// reflectIntHasher implements a reflection-based Hasher for keys.
2270-
type reflectHasher[K comparable] struct{}
2270+
type reflectHasher[K any] struct{}
22712271

22722272
// Hash returns a hash for key.
22732273
func (h *reflectHasher[K]) Hash(key K) uint32 {
@@ -2313,11 +2313,10 @@ func hashUint64(value uint64) uint32 {
23132313
}
23142314

23152315
// defaultHasher implements Hasher.
2316-
type defaultHasher[K comparable] struct{}
2316+
type defaultHasher[K any] struct{}
23172317

23182318
// Hash returns a hash for key.
23192319
func (h *defaultHasher[K]) Hash(key K) uint32 {
2320-
// Attempt to use non-reflection based hasher first.
23212320
switch x := (any(key)).(type) {
23222321
case int:
23232322
return hashUint64(uint64(x))
@@ -2348,13 +2347,13 @@ func (h *defaultHasher[K]) Hash(key K) uint32 {
23482347
}
23492348

23502349
// Equal returns true if a is equal to b. Otherwise returns false.
2351-
// Panics if a and b are not ints.
2350+
// Panics if a and b are not comparable.
23522351
func (h *defaultHasher[K]) Equal(a, b K) bool {
2353-
return a == b
2352+
return any(a) == any(b)
23542353
}
23552354

23562355
// Comparer allows the comparison of two keys for the purpose of sorting.
2357-
type Comparer[K comparable] interface {
2356+
type Comparer[K any] interface {
23582357
// Returns -1 if a is less than b, returns 1 if a is greater than b,
23592358
// and returns 0 if a is equal to b.
23602359
Compare(a, b K) int
@@ -2363,7 +2362,7 @@ type Comparer[K comparable] interface {
23632362
// NewComparer returns the built-in comparer for a given key type.
23642363
// Note that only int-ish and string-ish types are supported, despite the 'comparable' constraint.
23652364
// Attempts to use other types will result in a panic - users should define their own Comparers for these cases.
2366-
func NewComparer[K comparable](key K) Comparer[K] {
2365+
func NewComparer[K any](key K) Comparer[K] {
23672366
// Attempt to use non-reflection based comparer first.
23682367
switch (any(key)).(type) {
23692368
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, string:
@@ -2380,8 +2379,8 @@ func NewComparer[K comparable](key K) Comparer[K] {
23802379
panic(fmt.Sprintf("immutable.NewComparer: must set comparer for %T type", key))
23812380
}
23822381

2383-
// defaultComparer compares two values (int-ish and string-ish types are supported. Implements Comparer.
2384-
type defaultComparer[K comparable] struct{}
2382+
// defaultComparer compares two values (int-ish and string-ish types are supported). Implements Comparer.
2383+
type defaultComparer[K any] struct{}
23852384

23862385
// Compare returns -1 if a is less than b, returns 1 if a is greater than b, and
23872386
// returns 0 if a is equal to b. Panic if a or b is not a string or int* type
@@ -2427,7 +2426,7 @@ func defaultCompare[K constraints.Ordered](i, j K) int {
24272426
}
24282427

24292428
// reflectIntComparer compares two values using reflection. Implements Comparer.
2430-
type reflectComparer[K comparable] struct{}
2429+
type reflectComparer[K any] struct{}
24312430

24322431
// Compare returns -1 if a is less than b, returns 1 if a is greater than b, and
24332432
// returns 0 if a is equal to b. Panic if a or b is not an int-ish or string-ish type.

0 commit comments

Comments
 (0)