go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/experiments/matchmaker/pkg/sim/lookup.go (about)

     1  /*
     2  
     3  Copyright (c) 2024 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package sim
     9  
    10  import "math/rand"
    11  
    12  // NewLookup returns a new lookup from a given array of elements..
    13  func NewLookup[K comparable, V KeyProvider[K]](values []V) Lookup[K, V] {
    14  	output := make(Lookup[K, V])
    15  	for _, v := range values {
    16  		output.Add(v)
    17  	}
    18  	return output
    19  }
    20  
    21  // Lookup is a helper for maps that constrains the elements
    22  // to types that can report their own keys.
    23  type Lookup[K comparable, V KeyProvider[K]] map[K]V
    24  
    25  type KeyProvider[K comparable] interface {
    26  	Key() K
    27  }
    28  
    29  func (l Lookup[K, V]) HasKey(k K) (ok bool) {
    30  	_, ok = l[k]
    31  	return
    32  }
    33  
    34  func (l Lookup[K, V]) Has(v V) (ok bool) {
    35  	_, ok = l[v.Key()]
    36  	return
    37  }
    38  
    39  func (l Lookup[K, V]) Add(v V) {
    40  	l[v.Key()] = v
    41  }
    42  
    43  func (l Lookup[K, V]) Del(v V) {
    44  	delete(l, v.Key())
    45  }
    46  
    47  func (l Lookup[K, V]) Keys() (out []K) {
    48  	out = make([]K, 0, len(l))
    49  	for k := range l {
    50  		out = append(out, k)
    51  	}
    52  	return
    53  }
    54  
    55  // Copy returns a copy of the lookup.
    56  func (l Lookup[K, V]) Copy() Lookup[K, V] {
    57  	output := make(Lookup[K, V], len(l))
    58  	for k, v := range l {
    59  		output[k] = v
    60  	}
    61  	return output
    62  }
    63  
    64  // PopRandom removes a random element from the lookup and returns it.
    65  func (l Lookup[K, V]) PopRandom(_ *rand.Rand) (v V, ok bool) {
    66  	if len(l) == 0 {
    67  		return
    68  	}
    69  	var key K
    70  	for key, v = range l {
    71  		break
    72  	}
    73  	ok = true
    74  	delete(l, key)
    75  	return
    76  }