@@ -91,6 +91,35 @@ func hashmapMakeUnsafePointer(keySize, valueSize uintptr, sizeHint uintptr, alg
91
91
return (unsafe .Pointer )(hashmapMake (keySize , valueSize , sizeHint , alg ))
92
92
}
93
93
94
+ // Remove all entries from the map, without actually deallocating the space for
95
+ // it. This is used for the clear builtin, and can be used to reuse a map (to
96
+ // avoid extra heap allocations).
97
+ func hashmapClear (m * hashmap ) {
98
+ if m == nil {
99
+ // Nothing to do. According to the spec:
100
+ // > If the map or slice is nil, clear is a no-op.
101
+ return
102
+ }
103
+
104
+ m .count = 0
105
+ numBuckets := uintptr (1 ) << m .bucketBits
106
+ bucketSize := hashmapBucketSize (m )
107
+ for i := uintptr (0 ); i < numBuckets ; i ++ {
108
+ bucket := hashmapBucketAddr (m , m .buckets , i )
109
+ for bucket != nil {
110
+ // Clear the tophash, to mark these keys/values as removed.
111
+ bucket .tophash = [8 ]uint8 {}
112
+
113
+ // Clear the keys and values in the bucket so that the GC won't pin
114
+ // these allocations.
115
+ memzero (unsafe .Add (unsafe .Pointer (bucket ), unsafe .Sizeof (hashmapBucket {})), bucketSize - unsafe .Sizeof (hashmapBucket {}))
116
+
117
+ // Move on to the next bucket in the chain.
118
+ bucket = bucket .next
119
+ }
120
+ }
121
+ }
122
+
94
123
func hashmapKeyEqualAlg (alg hashmapAlgorithm ) func (x , y unsafe.Pointer , n uintptr ) bool {
95
124
switch alg {
96
125
case hashmapAlgorithmBinary :
0 commit comments