mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 02:27:48 +00:00
compiler, runtime: implement delete builtin
This commit is contained in:
@@ -158,6 +158,41 @@ func hashmapGet(m *hashmap, key unsafe.Pointer, value unsafe.Pointer, hash uint3
|
||||
memzero(value, uintptr(m.valueSize))
|
||||
}
|
||||
|
||||
// Delete a given key from the map. No-op when the key does not exist in the
|
||||
// map.
|
||||
//go:nobounds
|
||||
func hashmapDelete(m *hashmap, key unsafe.Pointer, hash uint32, keyEqual func(x, y unsafe.Pointer, n uintptr) bool) {
|
||||
numBuckets := uintptr(1) << m.bucketBits
|
||||
bucketNumber := (uintptr(hash) & (numBuckets - 1))
|
||||
bucketSize := unsafe.Sizeof(hashmapBucket{}) + uintptr(m.keySize)*8 + uintptr(m.valueSize)*8
|
||||
bucketAddr := uintptr(m.buckets) + bucketSize*bucketNumber
|
||||
bucket := (*hashmapBucket)(unsafe.Pointer(bucketAddr))
|
||||
|
||||
tophash := uint8(hash >> 24)
|
||||
if tophash < 1 {
|
||||
// 0 means empty slot, so make it bigger.
|
||||
tophash += 1
|
||||
}
|
||||
|
||||
// Try to find the key.
|
||||
for bucket != nil {
|
||||
for i := uintptr(0); i < 8; i++ {
|
||||
slotKeyOffset := unsafe.Sizeof(hashmapBucket{}) + uintptr(m.keySize)*uintptr(i)
|
||||
slotKey := unsafe.Pointer(uintptr(unsafe.Pointer(bucket)) + slotKeyOffset)
|
||||
if bucket.tophash[i] == tophash {
|
||||
// This could be the key we're looking for.
|
||||
if keyEqual(key, slotKey, uintptr(m.keySize)) {
|
||||
// Found the key, delete it.
|
||||
bucket.tophash[i] = 0
|
||||
m.count--
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
bucket = bucket.next
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over a hashmap.
|
||||
//go:nobounds
|
||||
func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) bool {
|
||||
@@ -209,6 +244,11 @@ func hashmapBinaryGet(m *hashmap, key, value unsafe.Pointer) {
|
||||
hashmapGet(m, key, value, hash, memequal)
|
||||
}
|
||||
|
||||
func hashmapBinaryDelete(m *hashmap, key unsafe.Pointer) {
|
||||
hash := hashmapHash(key, uintptr(m.keySize))
|
||||
hashmapDelete(m, key, hash, memequal)
|
||||
}
|
||||
|
||||
// Hashmap with string keys (a common case).
|
||||
|
||||
func hashmapStringEqual(x, y unsafe.Pointer, n uintptr) bool {
|
||||
@@ -229,3 +269,8 @@ func hashmapStringGet(m *hashmap, key string, value unsafe.Pointer) {
|
||||
hash := hashmapStringHash(key)
|
||||
hashmapGet(m, unsafe.Pointer(&key), value, hash, hashmapStringEqual)
|
||||
}
|
||||
|
||||
func hashmapStringDelete(m *hashmap, key string) {
|
||||
hash := hashmapStringHash(key)
|
||||
hashmapDelete(m, unsafe.Pointer(&key), hash, hashmapStringEqual)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user