// Copyright 2025 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by buf.build/go/hyperpb/internal/tools/hyperstencil. DO NOT EDIT.

package swiss

import (
	"buf.build/go/hyperpb/internal/debug"
	"buf.build/go/hyperpb/internal/xunsafe"
	"bytes"
	"math/rand/v2"
	"unsafe"
)

func InitU8xU8(t *Table[uint8, uint8], len int, from *Table[uint8, uint8], extract func(uint8) []byte) *Table[uint8, uint8] {
	_ = (*Table[uint8, uint8]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU8xU8(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU8xU8(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU32xU8(t *Table[uint32, uint8], len int, from *Table[uint32, uint8], extract func(uint32) []byte) *Table[uint32, uint8] {
	_ = (*Table[uint32, uint8]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU32xU8(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU32xU8(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU64xU8(t *Table[uint64, uint8], len int, from *Table[uint64, uint8], extract func(uint64) []byte) *Table[uint64, uint8] {
	_ = (*Table[uint64, uint8]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU64xU8(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU64xU8(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU8xU32(t *Table[uint8, uint32], len int, from *Table[uint8, uint32], extract func(uint8) []byte) *Table[uint8, uint32] {
	_ = (*Table[uint8, uint32]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU8xU32(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU8xU32(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU32xU32(t *Table[uint32, uint32], len int, from *Table[uint32, uint32], extract func(uint32) []byte) *Table[uint32, uint32] {
	_ = (*Table[uint32, uint32]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU32xU32(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU32xU32(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU64xU32(t *Table[uint64, uint32], len int, from *Table[uint64, uint32], extract func(uint64) []byte) *Table[uint64, uint32] {
	_ = (*Table[uint64, uint32]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU64xU32(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU64xU32(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU8xU64(t *Table[uint8, uint64], len int, from *Table[uint8, uint64], extract func(uint8) []byte) *Table[uint8, uint64] {
	_ = (*Table[uint8, uint64]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU8xU64(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU8xU64(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU32xU64(t *Table[uint32, uint64], len int, from *Table[uint32, uint64], extract func(uint32) []byte) *Table[uint32, uint64] {
	_ = (*Table[uint32, uint64]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU32xU64(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU32xU64(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU64xU64(t *Table[uint64, uint64], len int, from *Table[uint64, uint64], extract func(uint64) []byte) *Table[uint64, uint64] {
	_ = (*Table[uint64, uint64]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU64xU64(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU64xU64(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU8xP(t *Table[uint8, unsafe.Pointer], len int, from *Table[uint8, unsafe.Pointer], extract func(uint8) []byte) *Table[uint8, unsafe.Pointer] {
	_ = (*Table[uint8, unsafe.Pointer]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU8xP(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU8xP(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU32xP(t *Table[uint32, unsafe.Pointer], len int, from *Table[uint32, unsafe.Pointer], extract func(uint32) []byte) *Table[uint32, unsafe.Pointer] {
	_ = (*Table[uint32, unsafe.Pointer]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU32xP(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU32xP(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}
func InitU64xP(t *Table[uint64, unsafe.Pointer], len int, from *Table[uint64, unsafe.Pointer], extract func(uint64) []byte) *Table[uint64, unsafe.Pointer] {
	_ = (*Table[uint64, unsafe.Pointer]).Init
	t.soft, t.hard = loadFactor(len)
	if debug.Enabled {
		t.log("resize", "newLen: %d:%d:%d, from: %s", len, t.soft, t.hard, from.Dump())
		defer func() {
			t.log("resized", "%s", t.Dump())
		}()
	}

	t.seed = hash(rand.Uint64())

	if from == nil || from.len == 0 {
		return t
	}

	ctrl1 := from.ctrl()
	keys1 := from.keys()
	vals1 := from.values()

	ctrl2 := xunsafe.Cast[xunsafe.VLA[byte]](t.ctrl())
	keys2 := t.keys()
	vals2 := t.values()

	if extract == nil {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range ctrlSize {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := *keys1.Get(n)
				h := t.seed.u64(zext(k))
				idx, occupied := searchU64xP(t, h, k)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	} else {
		for i := 0; ; i++ {
			debug.Assert(i < int(t.hard)/ctrlSize, "infinite loop during copy")

			ctrl := *ctrl1.Get(i)
			for j := range 8 {
				var ok bool
				ctrl, ok = ctrl.next()
				if !ok {
					continue
				}

				n := i*ctrlSize + j
				k := extract(*keys1.Get(n))
				h := t.seed.bytes(k)
				idx, occupied := searchFuncU64xP(t, h, k, extract)
				debug.Assert(!occupied, "fwo keys mapped to one slot")

				mirrored := t.mirrorIndex(idx)
				*ctrl2.Get(idx) = h.h2()
				*ctrl2.Get(mirrored) = h.h2()
				*keys2.Get(idx) = *keys1.Get(n)
				*vals2.Get(idx) = *vals1.Get(n)
				t.len++

				if t.len == from.len {
					return t
				}
			}
		}
	}
}

func InsertU8xU8(t *Table[uint8, uint8], k uint8, extract func(uint8) []byte) *uint8 {
	_ = (*Table[uint8, uint8]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU8xU8(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU8xU8(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint8](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint8](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU32xU8(t *Table[uint32, uint8], k uint32, extract func(uint32) []byte) *uint8 {
	_ = (*Table[uint32, uint8]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU32xU8(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU32xU8(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint32](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint8](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU64xU8(t *Table[uint64, uint8], k uint64, extract func(uint64) []byte) *uint8 {
	_ = (*Table[uint64, uint8]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU64xU8(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU64xU8(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint64](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint8](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU8xU32(t *Table[uint8, uint32], k uint8, extract func(uint8) []byte) *uint32 {
	_ = (*Table[uint8, uint32]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU8xU32(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU8xU32(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint8](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint32](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU32xU32(t *Table[uint32, uint32], k uint32, extract func(uint32) []byte) *uint32 {
	_ = (*Table[uint32, uint32]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU32xU32(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU32xU32(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint32](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint32](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU64xU32(t *Table[uint64, uint32], k uint64, extract func(uint64) []byte) *uint32 {
	_ = (*Table[uint64, uint32]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU64xU32(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU64xU32(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint64](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint32](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU8xU64(t *Table[uint8, uint64], k uint8, extract func(uint8) []byte) *uint64 {
	_ = (*Table[uint8, uint64]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU8xU64(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU8xU64(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint8](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint64](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU32xU64(t *Table[uint32, uint64], k uint32, extract func(uint32) []byte) *uint64 {
	_ = (*Table[uint32, uint64]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU32xU64(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU32xU64(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint32](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint64](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU64xU64(t *Table[uint64, uint64], k uint64, extract func(uint64) []byte) *uint64 {
	_ = (*Table[uint64, uint64]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU64xU64(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU64xU64(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint64](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[uint64](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU8xP(t *Table[uint8, unsafe.Pointer], k uint8, extract func(uint8) []byte) *unsafe.Pointer {
	_ = (*Table[uint8, unsafe.Pointer]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU8xP(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU8xP(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint8](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[unsafe.Pointer](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU32xP(t *Table[uint32, unsafe.Pointer], k uint32, extract func(uint32) []byte) *unsafe.Pointer {
	_ = (*Table[uint32, unsafe.Pointer]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU32xP(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU32xP(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint32](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[unsafe.Pointer](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}
func InsertU64xP(t *Table[uint64, unsafe.Pointer], k uint64, extract func(uint64) []byte) *unsafe.Pointer {
	_ = (*Table[uint64, unsafe.Pointer]).Insert
	if t.len == t.soft {
		return nil
	}

	var idx int
	var occupied bool
	var h hash
	if extract == nil {
		h = t.seed.u64(zext(k))
		idx, occupied = searchU64xP(t, h, k)
	} else {
		k := extract(k)
		h = t.seed.bytes(k)
		idx, occupied = searchFuncU64xP(t, h, k, extract)
	}

	ctrl := xunsafe.Beyond[ctrl](t)
	last := ctrl.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint64](last)
	last2 := keys.Get(int(t.hard) - 1)
	values := xunsafe.Beyond[unsafe.Pointer](last2)

	if !occupied {
		mirrored := t.mirrorIndex(idx)
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(idx) = h.h2()
		*xunsafe.Cast[xunsafe.VLA[byte]](ctrl).Get(mirrored) = h.h2()
		*keys.Get(idx) = k
		t.len++
	}
	return values.Get(idx)
}

func searchU8xU8(t *Table[uint8, uint8], h hash, k uint8) (idx int, occupied bool) {
	_ = (*Table[uint8, uint8]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint8](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU32xU8(t *Table[uint32, uint8], h hash, k uint32) (idx int, occupied bool) {
	_ = (*Table[uint32, uint8]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint32](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU64xU8(t *Table[uint64, uint8], h hash, k uint64) (idx int, occupied bool) {
	_ = (*Table[uint64, uint8]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint64](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU8xU32(t *Table[uint8, uint32], h hash, k uint8) (idx int, occupied bool) {
	_ = (*Table[uint8, uint32]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint8](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU32xU32(t *Table[uint32, uint32], h hash, k uint32) (idx int, occupied bool) {
	_ = (*Table[uint32, uint32]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint32](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU64xU32(t *Table[uint64, uint32], h hash, k uint64) (idx int, occupied bool) {
	_ = (*Table[uint64, uint32]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint64](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU8xU64(t *Table[uint8, uint64], h hash, k uint8) (idx int, occupied bool) {
	_ = (*Table[uint8, uint64]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint8](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU32xU64(t *Table[uint32, uint64], h hash, k uint32) (idx int, occupied bool) {
	_ = (*Table[uint32, uint64]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint32](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU64xU64(t *Table[uint64, uint64], h hash, k uint64) (idx int, occupied bool) {
	_ = (*Table[uint64, uint64]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint64](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU8xP(t *Table[uint8, unsafe.Pointer], h hash, k uint8) (idx int, occupied bool) {
	_ = (*Table[uint8, unsafe.Pointer]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint8](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU32xP(t *Table[uint32, unsafe.Pointer], h hash, k uint32) (idx int, occupied bool) {
	_ = (*Table[uint32, unsafe.Pointer]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint32](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchU64xP(t *Table[uint64, unsafe.Pointer], h hash, k uint64) (idx int, occupied bool) {
	_ = (*Table[uint64, unsafe.Pointer]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[uint64](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}

func searchFuncU8xU8(t *Table[uint8, uint8], h hash, k []byte, extract func(uint8) []byte) (idx int, occupied bool) {
	_ = (*Table[uint8, uint8]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU32xU8(t *Table[uint32, uint8], h hash, k []byte, extract func(uint32) []byte) (idx int, occupied bool) {
	_ = (*Table[uint32, uint8]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU64xU8(t *Table[uint64, uint8], h hash, k []byte, extract func(uint64) []byte) (idx int, occupied bool) {
	_ = (*Table[uint64, uint8]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU8xU32(t *Table[uint8, uint32], h hash, k []byte, extract func(uint8) []byte) (idx int, occupied bool) {
	_ = (*Table[uint8, uint32]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU32xU32(t *Table[uint32, uint32], h hash, k []byte, extract func(uint32) []byte) (idx int, occupied bool) {
	_ = (*Table[uint32, uint32]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU64xU32(t *Table[uint64, uint32], h hash, k []byte, extract func(uint64) []byte) (idx int, occupied bool) {
	_ = (*Table[uint64, uint32]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU8xU64(t *Table[uint8, uint64], h hash, k []byte, extract func(uint8) []byte) (idx int, occupied bool) {
	_ = (*Table[uint8, uint64]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU32xU64(t *Table[uint32, uint64], h hash, k []byte, extract func(uint32) []byte) (idx int, occupied bool) {
	_ = (*Table[uint32, uint64]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU64xU64(t *Table[uint64, uint64], h hash, k []byte, extract func(uint64) []byte) (idx int, occupied bool) {
	_ = (*Table[uint64, uint64]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU8xP(t *Table[uint8, unsafe.Pointer], h hash, k []byte, extract func(uint8) []byte) (idx int, occupied bool) {
	_ = (*Table[uint8, unsafe.Pointer]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU32xP(t *Table[uint32, unsafe.Pointer], h hash, k []byte, extract func(uint32) []byte) (idx int, occupied bool) {
	_ = (*Table[uint32, unsafe.Pointer]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func searchFuncU64xP(t *Table[uint64, unsafe.Pointer], h hash, k []byte, extract func(uint64) []byte) (idx int, occupied bool) {
	_ = (*Table[uint64, unsafe.Pointer]).searchFunc
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	keys := t.keys()
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := extract(*keys.Get(n))
					t.log("checking", "%x == %x", k, k2)
					if bytes.Equal(k, k2) {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
func LookupI32xU32(t *Table[int32, uint32], k int32) *uint32 {
	_ = (*Table[int32, uint32]).Lookup
	h := t.seed.u64(zext(k))
	idx, occupied := searchI32xU32(t, h, k)
	if !occupied {
		return nil
	}
	return t.values().Get(idx)
}
func LookupU32xU32(t *Table[uint32, uint32], k uint32) *uint32 {
	_ = (*Table[uint32, uint32]).Lookup
	h := t.seed.u64(zext(k))
	idx, occupied := searchU32xU32(t, h, k)
	if !occupied {
		return nil
	}
	return t.values().Get(idx)
}

func LookupFuncU32xU32(t *Table[uint32, uint32], k []byte, extract func(uint32) []byte) *uint32 {
	_ = (*Table[uint32, uint32]).LookupFunc
	h := t.seed.bytes(k)
	idx, occupied := searchFuncU32xU32(t, h, k, extract)
	if !occupied {
		return nil
	}
	return t.values().Get(idx)
}
func LookupU64xU32(t *Table[uint64, uint32], k uint64) *uint32 {
	_ = (*Table[uint64, uint32]).Lookup
	h := t.seed.u64(zext(k))
	idx, occupied := searchU64xU32(t, h, k)
	if !occupied {
		return nil
	}
	return t.values().Get(idx)
}

func searchI32xU32(t *Table[int32, uint32], h hash, k int32) (idx int, occupied bool) {
	_ = (*Table[int32, uint32]).search
	t.log("search", "h: %v, k: %v", h, k)

	h2 := broadcast(h.h2())
	empty := broadcast(empty)

	p := newProber(xunsafe.Beyond[ctrl](t), int(t.hard), h)
	ctrls := xunsafe.Beyond[ctrl](t)
	last := ctrls.Get(int(t.hard) / ctrlSize)
	keys := xunsafe.Beyond[int32](last)
	len := 0
	for {

		debug.Assert(p.i <= p.mask, "full table: %#v", p)
		len++

		var i int
		var ctrl ctrl
		p, i, ctrl = p.next()

		mask := ctrl.matches(h2)
		t.log("matching", "i: %v, ctrl: %v, h2: %v, mask: %v", i, ctrl, h2, mask)
		if mask.nonempty() {
			n := i
			for j := range ctrlSize {
				var eq bool
				mask, eq = mask.next()
				if eq {
					n &= int(t.hard) - 1
					k2 := *keys.Get(n)
					t.log("checking", "%v == %v", k, k2)
					if k == k2 {
						t.log("found occupied", "%v,%v = %v", i, j, n)
						t.recordProbeSeq(len)
						return n, true
					}
				}
				n++
			}
		}

		j := ctrl.first(empty)
		if j < ctrlSize {
			n := i + j
			t.log("found vacant", "%v,%v = %v", i, j, n)
			t.recordProbeSeq(len)
			return n & (int(t.hard) - 1), false
		}
	}
}
