]> Cypherpunks repositories - gostls13.git/commitdiff
internal/runtime/maps: clean up put slot calls
authorkhr@golang.org <khr@golang.org>
Thu, 31 Oct 2024 17:42:23 +0000 (10:42 -0700)
committerKeith Randall <khr@golang.org>
Fri, 1 Nov 2024 20:11:10 +0000 (20:11 +0000)
Use matchEmptyOrDeleted instead of matchEmpty.
Streamline the code a bit.
TODO: replicate in all the _fast files.
Change-Id: I4df16a13a19df3aaae0c42e0c12f20552f08ead6
Reviewed-on: https://go-review.googlesource.com/c/go/+/624055
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/internal/runtime/maps/runtime_fast32_swiss.go
src/internal/runtime/maps/runtime_fast64_swiss.go
src/internal/runtime/maps/runtime_faststr_swiss.go
src/internal/runtime/maps/table.go

index a61257d5de9b3e71e94d4544460775365726d66f..84c85772f490c20bf6238c767482886ede886e6c 100644 (file)
@@ -256,58 +256,49 @@ outer:
 
                        // No existing slot for this key in this group. Is this the end
                        // of the probe sequence?
-                       match = g.ctrls().matchEmpty()
-                       if match != 0 {
-                               // Finding an empty slot means we've reached the end of
-                               // the probe sequence.
-
-                               var i uintptr
-
-                               // If we found a deleted slot along the way, we
-                               // can replace it without consuming growthLeft.
-                               if firstDeletedGroup.data != nil {
-                                       g = firstDeletedGroup
-                                       i = firstDeletedSlot
-                                       t.growthLeft++ // will be decremented below to become a no-op.
-                               } else {
-                                       // Otherwise, use the empty slot.
-                                       i = match.first()
+                       match = g.ctrls().matchEmptyOrDeleted()
+                       if match == 0 {
+                               continue // nothing but filled slots. Keep probing.
+                       }
+                       i := match.first()
+                       if g.ctrls().get(i) == ctrlDeleted {
+                               // There are some deleted slots. Remember
+                               // the first one, and keep probing.
+                               if firstDeletedGroup.data == nil {
+                                       firstDeletedGroup = g
+                                       firstDeletedSlot = i
                                }
+                               continue
+                       }
+                       // We've found an empty slot, which means we've reached the end of
+                       // the probe sequence.
 
-                               // If there is room left to grow, just insert the new entry.
-                               if t.growthLeft > 0 {
-                                       slotKey := g.key(typ, i)
-                                       *(*uint32)(slotKey) = key
+                       // If we found a deleted slot along the way, we can
+                       // replace it without consuming growthLeft.
+                       if firstDeletedGroup.data != nil {
+                               g = firstDeletedGroup
+                               i = firstDeletedSlot
+                               t.growthLeft++ // will be decremented below to become a no-op.
+                       }
 
-                                       slotElem = g.elem(typ, i)
+                       // If there is room left to grow, just insert the new entry.
+                       if t.growthLeft > 0 {
+                               slotKey := g.key(typ, i)
+                               *(*uint32)(slotKey) = key
 
-                                       g.ctrls().set(i, ctrl(h2(hash)))
-                                       t.growthLeft--
-                                       t.used++
-                                       m.used++
+                               slotElem = g.elem(typ, i)
 
-                                       t.checkInvariants(typ, m)
-                                       break outer
-                               }
+                               g.ctrls().set(i, ctrl(h2(hash)))
+                               t.growthLeft--
+                               t.used++
+                               m.used++
 
-                               t.rehash(typ, m)
-                               continue outer
+                               t.checkInvariants(typ, m)
+                               break outer
                        }
 
-                       // No empty slots in this group. Check for a deleted
-                       // slot, which we'll use if we don't find a match later
-                       // in the probe sequence.
-                       //
-                       // We only need to remember a single deleted slot.
-                       if firstDeletedGroup.data == nil {
-                               // Since we already checked for empty slots
-                               // above, matches here must be deleted slots.
-                               match = g.ctrls().matchEmptyOrDeleted()
-                               if match != 0 {
-                                       firstDeletedGroup = g
-                                       firstDeletedSlot = match.first()
-                               }
-                       }
+                       t.rehash(typ, m)
+                       continue outer
                }
        }
 
@@ -397,58 +388,49 @@ outer:
 
                        // No existing slot for this key in this group. Is this the end
                        // of the probe sequence?
-                       match = g.ctrls().matchEmpty()
-                       if match != 0 {
-                               // Finding an empty slot means we've reached the end of
-                               // the probe sequence.
-
-                               var i uintptr
-
-                               // If we found a deleted slot along the way, we
-                               // can replace it without consuming growthLeft.
-                               if firstDeletedGroup.data != nil {
-                                       g = firstDeletedGroup
-                                       i = firstDeletedSlot
-                                       t.growthLeft++ // will be decremented below to become a no-op.
-                               } else {
-                                       // Otherwise, use the empty slot.
-                                       i = match.first()
+                       match = g.ctrls().matchEmptyOrDeleted()
+                       if match == 0 {
+                               continue // nothing but filled slots. Keep probing.
+                       }
+                       i := match.first()
+                       if g.ctrls().get(i) == ctrlDeleted {
+                               // There are some deleted slots. Remember
+                               // the first one, and keep probing.
+                               if firstDeletedGroup.data == nil {
+                                       firstDeletedGroup = g
+                                       firstDeletedSlot = i
                                }
+                               continue
+                       }
+                       // We've found an empty slot, which means we've reached the end of
+                       // the probe sequence.
 
-                               // If there is room left to grow, just insert the new entry.
-                               if t.growthLeft > 0 {
-                                       slotKey := g.key(typ, i)
-                                       *(*unsafe.Pointer)(slotKey) = key
+                       // If we found a deleted slot along the way, we can
+                       // replace it without consuming growthLeft.
+                       if firstDeletedGroup.data != nil {
+                               g = firstDeletedGroup
+                               i = firstDeletedSlot
+                               t.growthLeft++ // will be decremented below to become a no-op.
+                       }
 
-                                       slotElem = g.elem(typ, i)
+                       // If there is room left to grow, just insert the new entry.
+                       if t.growthLeft > 0 {
+                               slotKey := g.key(typ, i)
+                               *(*unsafe.Pointer)(slotKey) = key
 
-                                       g.ctrls().set(i, ctrl(h2(hash)))
-                                       t.growthLeft--
-                                       t.used++
-                                       m.used++
+                               slotElem = g.elem(typ, i)
 
-                                       t.checkInvariants(typ, m)
-                                       break outer
-                               }
+                               g.ctrls().set(i, ctrl(h2(hash)))
+                               t.growthLeft--
+                               t.used++
+                               m.used++
 
-                               t.rehash(typ, m)
-                               continue outer
+                               t.checkInvariants(typ, m)
+                               break outer
                        }
 
-                       // No empty slots in this group. Check for a deleted
-                       // slot, which we'll use if we don't find a match later
-                       // in the probe sequence.
-                       //
-                       // We only need to remember a single deleted slot.
-                       if firstDeletedGroup.data == nil {
-                               // Since we already checked for empty slots
-                               // above, matches here must be deleted slots.
-                               match = g.ctrls().matchEmptyOrDeleted()
-                               if match != 0 {
-                                       firstDeletedGroup = g
-                                       firstDeletedSlot = match.first()
-                               }
-                       }
+                       t.rehash(typ, m)
+                       continue outer
                }
        }
 
index 85e9b7a392dca3c25601d5ff1ce68f31572691fc..7c9ce87cdce5a68ee5f7183a32af6505f702a149 100644 (file)
@@ -255,58 +255,49 @@ outer:
 
                        // No existing slot for this key in this group. Is this the end
                        // of the probe sequence?
-                       match = g.ctrls().matchEmpty()
-                       if match != 0 {
-                               // Finding an empty slot means we've reached the end of
-                               // the probe sequence.
-
-                               var i uintptr
-
-                               // If we found a deleted slot along the way, we
-                               // can replace it without consuming growthLeft.
-                               if firstDeletedGroup.data != nil {
-                                       g = firstDeletedGroup
-                                       i = firstDeletedSlot
-                                       t.growthLeft++ // will be decremented below to become a no-op.
-                               } else {
-                                       // Otherwise, use the empty slot.
-                                       i = match.first()
+                       match = g.ctrls().matchEmptyOrDeleted()
+                       if match == 0 {
+                               continue // nothing but filled slots. Keep probing.
+                       }
+                       i := match.first()
+                       if g.ctrls().get(i) == ctrlDeleted {
+                               // There are some deleted slots. Remember
+                               // the first one, and keep probing.
+                               if firstDeletedGroup.data == nil {
+                                       firstDeletedGroup = g
+                                       firstDeletedSlot = i
                                }
+                               continue
+                       }
+                       // We've found an empty slot, which means we've reached the end of
+                       // the probe sequence.
 
-                               // If there is room left to grow, just insert the new entry.
-                               if t.growthLeft > 0 {
-                                       slotKey := g.key(typ, i)
-                                       *(*uint64)(slotKey) = key
+                       // If we found a deleted slot along the way, we can
+                       // replace it without consuming growthLeft.
+                       if firstDeletedGroup.data != nil {
+                               g = firstDeletedGroup
+                               i = firstDeletedSlot
+                               t.growthLeft++ // will be decremented below to become a no-op.
+                       }
 
-                                       slotElem = g.elem(typ, i)
+                       // If there is room left to grow, just insert the new entry.
+                       if t.growthLeft > 0 {
+                               slotKey := g.key(typ, i)
+                               *(*uint64)(slotKey) = key
 
-                                       g.ctrls().set(i, ctrl(h2(hash)))
-                                       t.growthLeft--
-                                       t.used++
-                                       m.used++
+                               slotElem = g.elem(typ, i)
 
-                                       t.checkInvariants(typ, m)
-                                       break outer
-                               }
+                               g.ctrls().set(i, ctrl(h2(hash)))
+                               t.growthLeft--
+                               t.used++
+                               m.used++
 
-                               t.rehash(typ, m)
-                               continue outer
+                               t.checkInvariants(typ, m)
+                               break outer
                        }
 
-                       // No empty slots in this group. Check for a deleted
-                       // slot, which we'll use if we don't find a match later
-                       // in the probe sequence.
-                       //
-                       // We only need to remember a single deleted slot.
-                       if firstDeletedGroup.data == nil {
-                               // Since we already checked for empty slots
-                               // above, matches here must be deleted slots.
-                               match = g.ctrls().matchEmptyOrDeleted()
-                               if match != 0 {
-                                       firstDeletedGroup = g
-                                       firstDeletedSlot = match.first()
-                               }
-                       }
+                       t.rehash(typ, m)
+                       continue outer
                }
        }
 
@@ -435,58 +426,49 @@ outer:
 
                        // No existing slot for this key in this group. Is this the end
                        // of the probe sequence?
-                       match = g.ctrls().matchEmpty()
-                       if match != 0 {
-                               // Finding an empty slot means we've reached the end of
-                               // the probe sequence.
-
-                               var i uintptr
-
-                               // If we found a deleted slot along the way, we
-                               // can replace it without consuming growthLeft.
-                               if firstDeletedGroup.data != nil {
-                                       g = firstDeletedGroup
-                                       i = firstDeletedSlot
-                                       t.growthLeft++ // will be decremented below to become a no-op.
-                               } else {
-                                       // Otherwise, use the empty slot.
-                                       i = match.first()
+                       match = g.ctrls().matchEmptyOrDeleted()
+                       if match == 0 {
+                               continue // nothing but filled slots. Keep probing.
+                       }
+                       i := match.first()
+                       if g.ctrls().get(i) == ctrlDeleted {
+                               // There are some deleted slots. Remember
+                               // the first one, and keep probing.
+                               if firstDeletedGroup.data == nil {
+                                       firstDeletedGroup = g
+                                       firstDeletedSlot = i
                                }
+                               continue
+                       }
+                       // We've found an empty slot, which means we've reached the end of
+                       // the probe sequence.
 
-                               // If there is room left to grow, just insert the new entry.
-                               if t.growthLeft > 0 {
-                                       slotKey := g.key(typ, i)
-                                       *(*unsafe.Pointer)(slotKey) = key
+                       // If we found a deleted slot along the way, we can
+                       // replace it without consuming growthLeft.
+                       if firstDeletedGroup.data != nil {
+                               g = firstDeletedGroup
+                               i = firstDeletedSlot
+                               t.growthLeft++ // will be decremented below to become a no-op.
+                       }
 
-                                       slotElem = g.elem(typ, i)
+                       // If there is room left to grow, just insert the new entry.
+                       if t.growthLeft > 0 {
+                               slotKey := g.key(typ, i)
+                               *(*unsafe.Pointer)(slotKey) = key
 
-                                       g.ctrls().set(i, ctrl(h2(hash)))
-                                       t.growthLeft--
-                                       t.used++
-                                       m.used++
+                               slotElem = g.elem(typ, i)
 
-                                       t.checkInvariants(typ, m)
-                                       break outer
-                               }
+                               g.ctrls().set(i, ctrl(h2(hash)))
+                               t.growthLeft--
+                               t.used++
+                               m.used++
 
-                               t.rehash(typ, m)
-                               continue outer
+                               t.checkInvariants(typ, m)
+                               break outer
                        }
 
-                       // No empty slots in this group. Check for a deleted
-                       // slot, which we'll use if we don't find a match later
-                       // in the probe sequence.
-                       //
-                       // We only need to remember a single deleted slot.
-                       if firstDeletedGroup.data == nil {
-                               // Since we already checked for empty slots
-                               // above, matches here must be deleted slots.
-                               match = g.ctrls().matchEmptyOrDeleted()
-                               if match != 0 {
-                                       firstDeletedGroup = g
-                                       firstDeletedSlot = match.first()
-                               }
-                       }
+                       t.rehash(typ, m)
+                       continue outer
                }
        }
 
index b7f88ab1ef86c6773900d91995e21927b86d1d0e..ab0213ba3350e0c99eacf176383f3e87820d83b4 100644 (file)
@@ -275,58 +275,49 @@ outer:
 
                        // No existing slot for this key in this group. Is this the end
                        // of the probe sequence?
-                       match = g.ctrls().matchEmpty()
-                       if match != 0 {
-                               // Finding an empty slot means we've reached the end of
-                               // the probe sequence.
-
-                               var i uintptr
-
-                               // If we found a deleted slot along the way, we
-                               // can replace it without consuming growthLeft.
-                               if firstDeletedGroup.data != nil {
-                                       g = firstDeletedGroup
-                                       i = firstDeletedSlot
-                                       t.growthLeft++ // will be decremented below to become a no-op.
-                               } else {
-                                       // Otherwise, use the empty slot.
-                                       i = match.first()
+                       match = g.ctrls().matchEmptyOrDeleted()
+                       if match == 0 {
+                               continue // nothing but filled slots. Keep probing.
+                       }
+                       i := match.first()
+                       if g.ctrls().get(i) == ctrlDeleted {
+                               // There are some deleted slots. Remember
+                               // the first one, and keep probing.
+                               if firstDeletedGroup.data == nil {
+                                       firstDeletedGroup = g
+                                       firstDeletedSlot = i
                                }
+                               continue
+                       }
+                       // We've found an empty slot, which means we've reached the end of
+                       // the probe sequence.
 
-                               // If there is room left to grow, just insert the new entry.
-                               if t.growthLeft > 0 {
-                                       slotKey := g.key(typ, i)
-                                       *(*string)(slotKey) = key
+                       // If we found a deleted slot along the way, we can
+                       // replace it without consuming growthLeft.
+                       if firstDeletedGroup.data != nil {
+                               g = firstDeletedGroup
+                               i = firstDeletedSlot
+                               t.growthLeft++ // will be decremented below to become a no-op.
+                       }
 
-                                       slotElem = g.elem(typ, i)
+                       // If there is room left to grow, just insert the new entry.
+                       if t.growthLeft > 0 {
+                               slotKey := g.key(typ, i)
+                               *(*string)(slotKey) = key
 
-                                       g.ctrls().set(i, ctrl(h2(hash)))
-                                       t.growthLeft--
-                                       t.used++
-                                       m.used++
+                               slotElem = g.elem(typ, i)
 
-                                       t.checkInvariants(typ, m)
-                                       break outer
-                               }
+                               g.ctrls().set(i, ctrl(h2(hash)))
+                               t.growthLeft--
+                               t.used++
+                               m.used++
 
-                               t.rehash(typ, m)
-                               continue outer
+                               t.checkInvariants(typ, m)
+                               break outer
                        }
 
-                       // No empty slots in this group. Check for a deleted
-                       // slot, which we'll use if we don't find a match later
-                       // in the probe sequence.
-                       //
-                       // We only need to remember a single deleted slot.
-                       if firstDeletedGroup.data == nil {
-                               // Since we already checked for empty slots
-                               // above, matches here must be deleted slots.
-                               match = g.ctrls().matchEmptyOrDeleted()
-                               if match != 0 {
-                                       firstDeletedGroup = g
-                                       firstDeletedSlot = match.first()
-                               }
-                       }
+                       t.rehash(typ, m)
+                       continue outer
                }
        }
 
index 8eb4a38c07ac374face4436aa38157e6d0050c75..494ede79111d654bae7b27db4c7e966cce21d092 100644 (file)
@@ -155,7 +155,7 @@ func (t *table) Get(typ *abi.SwissMapType, m *Map, key unsafe.Pointer) (unsafe.P
        //   without hashing.
        // - String keys could do quick checks of a few bytes before hashing.
        hash := typ.Hasher(key, m.seed)
-       _, elem, ok := t.getWithKey(typ, hash, key)
+       _, elem, ok := t.getWithKey(typ, hash, key)
        return elem, ok
 }
 
@@ -306,68 +306,59 @@ func (t *table) PutSlot(typ *abi.SwissMapType, m *Map, hash uintptr, key unsafe.
 
                // No existing slot for this key in this group. Is this the end
                // of the probe sequence?
-               match = g.ctrls().matchEmpty()
-               if match != 0 {
-                       // Finding an empty slot means we've reached the end of
-                       // the probe sequence.
-
-                       var i uintptr
-
-                       // If we found a deleted slot along the way, we can
-                       // replace it without consuming growthLeft.
-                       if firstDeletedGroup.data != nil {
-                               g = firstDeletedGroup
-                               i = firstDeletedSlot
-                               t.growthLeft++ // will be decremented below to become a no-op.
-                       } else {
-                               // Otherwise, use the empty slot.
-                               i = match.first()
+               match = g.ctrls().matchEmptyOrDeleted()
+               if match == 0 {
+                       continue // nothing but filled slots. Keep probing.
+               }
+               i := match.first()
+               if g.ctrls().get(i) == ctrlDeleted {
+                       // There are some deleted slots. Remember
+                       // the first one, and keep probing.
+                       if firstDeletedGroup.data == nil {
+                               firstDeletedGroup = g
+                               firstDeletedSlot = i
                        }
+                       continue
+               }
+               // We've found an empty slot, which means we've reached the end of
+               // the probe sequence.
+
+               // If we found a deleted slot along the way, we can
+               // replace it without consuming growthLeft.
+               if firstDeletedGroup.data != nil {
+                       g = firstDeletedGroup
+                       i = firstDeletedSlot
+                       t.growthLeft++ // will be decremented below to become a no-op.
+               }
 
-                       // If there is room left to grow, just insert the new entry.
-                       if t.growthLeft > 0 {
-                               slotKey := g.key(typ, i)
-                               if typ.IndirectKey() {
-                                       kmem := newobject(typ.Key)
-                                       *(*unsafe.Pointer)(slotKey) = kmem
-                                       slotKey = kmem
-                               }
-                               typedmemmove(typ.Key, slotKey, key)
-
-                               slotElem := g.elem(typ, i)
-                               if typ.IndirectElem() {
-                                       emem := newobject(typ.Elem)
-                                       *(*unsafe.Pointer)(slotElem) = emem
-                                       slotElem = emem
-                               }
-
-                               g.ctrls().set(i, ctrl(h2(hash)))
-                               t.growthLeft--
-                               t.used++
-                               m.used++
+               // If there is room left to grow, just insert the new entry.
+               if t.growthLeft > 0 {
+                       slotKey := g.key(typ, i)
+                       if typ.IndirectKey() {
+                               kmem := newobject(typ.Key)
+                               *(*unsafe.Pointer)(slotKey) = kmem
+                               slotKey = kmem
+                       }
+                       typedmemmove(typ.Key, slotKey, key)
 
-                               t.checkInvariants(typ, m)
-                               return slotElem, true
+                       slotElem := g.elem(typ, i)
+                       if typ.IndirectElem() {
+                               emem := newobject(typ.Elem)
+                               *(*unsafe.Pointer)(slotElem) = emem
+                               slotElem = emem
                        }
 
-                       t.rehash(typ, m)
-                       return nil, false
-               }
+                       g.ctrls().set(i, ctrl(h2(hash)))
+                       t.growthLeft--
+                       t.used++
+                       m.used++
 
-               // No empty slots in this group. Check for a deleted
-               // slot, which we'll use if we don't find a match later
-               // in the probe sequence.
-               //
-               // We only need to remember a single deleted slot.
-               if firstDeletedGroup.data == nil {
-                       // Since we already checked for empty slots
-                       // above, matches here must be deleted slots.
-                       match = g.ctrls().matchEmptyOrDeleted()
-                       if match != 0 {
-                               firstDeletedGroup = g
-                               firstDeletedSlot = match.first()
-                       }
+                       t.checkInvariants(typ, m)
+                       return slotElem, true
                }
+
+               t.rehash(typ, m)
+               return nil, false
        }
 }