github.com/haraldrudell/parl@v0.4.176/pmaps/pmaps2/map.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  // Package pmaps2 contains resusable map types for other parl packages.
     7  package pmaps2
     8  
     9  import "golang.org/x/exp/maps"
    10  
    11  // Map is a reusable promotable Go map
    12  //   - 5 native Go Map functions: Get Put Delete Length Range
    13  //   - convenience functions:
    14  //   - — Clear using fast, scavenging re-create
    15  //   - — Clone using range, optionally appending to provided instance
    16  //   - — these methods require access to the underlying Go map
    17  //   - not thread-safe:
    18  //   - — zero-value delete can be implemented by consumer
    19  //   - — range-Clear with zero-value write can be implemented by consumer
    20  //   - — order methods List and Keys can be implemented by consumer
    21  type Map[K comparable, V any] struct{ goMap map[K]V }
    22  
    23  // NewMap returns a reusable Go Map object
    24  func NewMap[K comparable, V any]() (mapping *Map[K, V]) { return &Map[K, V]{goMap: make(map[K]V)} }
    25  
    26  // Get returns the value mapped by key or the V zero-value otherwise
    27  //   - ok: true if a mapping was found
    28  //   - O(1)
    29  func (m *Map[K, V]) Get(key K) (value V, ok bool) {
    30  	value, ok = m.goMap[key]
    31  	return
    32  }
    33  
    34  // Put create or replaces a mapping
    35  func (m *Map[K, V]) Put(key K, value V) { m.goMap[key] = value }
    36  
    37  // Delete removes mapping for key
    38  //   - if key is not mapped, the map is unchanged.
    39  //   - O(log n)
    40  func (m *Map[K, V]) Delete(key K) { delete(m.goMap, key) }
    41  
    42  // Length returns the number of mappings
    43  func (m *Map[K, V]) Length() (length int) { return len(m.goMap) }
    44  
    45  // Range traverses map bindings
    46  //   - iterates over map until rangeFunc returns false
    47  //   - order is undefined
    48  //   - similar to [sync.Map.Range] func (*sync.Map).Range(f func(key any, value any) bool)
    49  func (m *Map[K, V]) Range(rangeFunc func(key K, value V) (keepGoing bool)) (rangedAll bool) {
    50  	for key, value := range m.goMap {
    51  		if !rangeFunc(key, value) {
    52  			return
    53  		}
    54  	}
    55  	return true
    56  }
    57  
    58  // Clear empties the map
    59  //   - clears by re-initializing the map
    60  //   - when instead ranging and deleting all keys,
    61  //     the unused size of the map is retained
    62  func (m *Map[K, V]) Clear() { m.goMap = make(map[K]V) }
    63  
    64  // Clone returns a shallow clone of the map
    65  //   - mp is an optional pointer to an already allocated map instance
    66  //     to be used and appended to
    67  //   - delegates to [maps.Clone] ranging all keys
    68  func (m *Map[K, V]) Clone(mp ...*Map[K, V]) (clone *Map[K, V]) {
    69  
    70  	// clone should point to a destination instance
    71  	if len(mp) > 0 {
    72  		clone = mp[0]
    73  	}
    74  	if clone == nil {
    75  		clone = &Map[K, V]{}
    76  	}
    77  
    78  	clone.goMap = maps.Clone(m.goMap)
    79  
    80  	return
    81  }