github.com/cilium/cilium@v1.16.2/pkg/container/bitlpm/unsigned.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package bitlpm
     5  
     6  import (
     7  	"fmt"
     8  	"math/bits"
     9  	"unsafe"
    10  )
    11  
    12  // Unsigned represents all types that have an underlying
    13  // unsigned integer type, excluding uintptr and uint.
    14  type Unsigned interface {
    15  	~uint8 | ~uint16 | ~uint32 | ~uint64
    16  }
    17  
    18  // UintTrie uses all unsigned integer types
    19  // except for uintptr and uint.
    20  type UintTrie[K Unsigned, V any] struct {
    21  	trie    Trie[Key[K], V]
    22  	keySize uint
    23  }
    24  
    25  // NewUintTrie represents a Trie with a key of any
    26  // uint type.
    27  func NewUintTrie[K Unsigned, T any]() *UintTrie[K, T] {
    28  	var k K
    29  	size := uint(unsafe.Sizeof(k))
    30  	return &UintTrie[K, T]{
    31  		trie:    NewTrie[K, T](size * 8),
    32  		keySize: size,
    33  	}
    34  }
    35  
    36  func (tu *UintTrie[K, T]) getKey(k K) Key[K] {
    37  	switch tu.keySize {
    38  	case 1:
    39  		return unsignedKey8[K](k)
    40  	case 2:
    41  		return unsignedKey16[K](k)
    42  	case 4:
    43  		return unsignedKey32[K](k)
    44  	case 8:
    45  		return unsignedKey64[K](k)
    46  	}
    47  	panic(fmt.Sprintf("unexpected key size of %d", unsafe.Sizeof(k)))
    48  }
    49  
    50  func (ut *UintTrie[K, T]) Upsert(prefix uint, k K, value T) {
    51  	ut.trie.Upsert(prefix, ut.getKey(k), value)
    52  }
    53  
    54  func (ut *UintTrie[K, T]) Delete(prefix uint, k K) bool {
    55  	return ut.trie.Delete(prefix, ut.getKey(k))
    56  }
    57  
    58  func (ut *UintTrie[K, T]) ExactLookup(prefix uint, k K) (T, bool) {
    59  	return ut.trie.ExactLookup(prefix, ut.getKey(k))
    60  }
    61  
    62  func (ut *UintTrie[K, T]) LongestPrefixMatch(k K) (T, bool) {
    63  	return ut.trie.LongestPrefixMatch(ut.getKey(k))
    64  }
    65  
    66  func (ut *UintTrie[K, T]) Ancestors(prefix uint, k K, fn func(prefix uint, key K, value T) bool) {
    67  	ut.trie.Ancestors(prefix, ut.getKey(k), func(prefix uint, k Key[K], v T) bool {
    68  		return fn(prefix, k.Value(), v)
    69  	})
    70  }
    71  
    72  func (ut *UintTrie[K, T]) Descendants(prefix uint, k K, fn func(prefix uint, key K, value T) bool) {
    73  	ut.trie.Descendants(prefix, ut.getKey(k), func(prefix uint, k Key[K], v T) bool {
    74  		return fn(prefix, k.Value(), v)
    75  	})
    76  }
    77  
    78  func (ut *UintTrie[K, T]) Len() uint {
    79  	return ut.trie.Len()
    80  }
    81  
    82  func (ut *UintTrie[K, T]) ForEach(fn func(prefix uint, key K, value T) bool) {
    83  	ut.trie.ForEach(func(prefix uint, k Key[K], v T) bool {
    84  		return fn(prefix, k.Value(), v)
    85  	})
    86  }
    87  
    88  type unsignedKey8[U Unsigned] uint8
    89  
    90  func (u unsignedKey8[U]) CommonPrefix(v U) uint {
    91  	return uint(bits.LeadingZeros8(uint8(U(u) ^ v)))
    92  }
    93  
    94  func (u unsignedKey8[U]) BitValueAt(i uint) uint8 {
    95  	if u&(1<<(7-i)) == 0 {
    96  		return 0
    97  	}
    98  	return 1
    99  }
   100  
   101  func (u unsignedKey8[U]) Value() U {
   102  	return U(u)
   103  }
   104  
   105  type unsignedKey16[U Unsigned] uint16
   106  
   107  func (u unsignedKey16[U]) CommonPrefix(v U) uint {
   108  	return uint(bits.LeadingZeros16(uint16(u) ^ uint16(v)))
   109  }
   110  
   111  func (u unsignedKey16[U]) BitValueAt(i uint) uint8 {
   112  	if u&(1<<(15-i)) == 0 {
   113  		return 0
   114  	}
   115  	return 1
   116  }
   117  
   118  func (u unsignedKey16[U]) Value() U {
   119  	return U(u)
   120  }
   121  
   122  type unsignedKey32[U Unsigned] uint32
   123  
   124  func (u unsignedKey32[U]) CommonPrefix(v U) uint {
   125  	return uint(bits.LeadingZeros32(uint32(u) ^ uint32(v)))
   126  }
   127  
   128  func (u unsignedKey32[U]) BitValueAt(i uint) uint8 {
   129  	if u&(1<<(31-i)) == 0 {
   130  		return 0
   131  	}
   132  	return 1
   133  }
   134  
   135  func (u unsignedKey32[U]) Value() U {
   136  	return U(u)
   137  }
   138  
   139  type unsignedKey64[U Unsigned] uint64
   140  
   141  func (u unsignedKey64[U]) CommonPrefix(v U) uint {
   142  	return uint(bits.LeadingZeros64(uint64(u) ^ uint64(v)))
   143  }
   144  
   145  func (u unsignedKey64[U]) BitValueAt(i uint) uint8 {
   146  	if u&(1<<(63-i)) == 0 {
   147  		return 0
   148  	}
   149  	return 1
   150  }
   151  
   152  func (u unsignedKey64[U]) Value() U {
   153  	return U(u)
   154  }