github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/syntax/testdata/map.go (about)

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package orderedmap provides an ordered map, implemented as a binary tree.
     6  package orderedmap
     7  
     8  import "chans"
     9  
    10  // Map is an ordered map.
    11  type Map[K, V any] struct {
    12  	root    *node[K, V]
    13  	compare func(K, K) int
    14  }
    15  
    16  // node is the type of a node in the binary tree.
    17  type node[K, V any] struct {
    18  	key         K
    19  	val         V
    20  	left, right *node[K, V]
    21  }
    22  
    23  // New returns a new map.
    24  func New[K, V any](compare func(K, K) int) *Map[K, V] {
    25          return &Map[K, V]{compare: compare}
    26  }
    27  
    28  // find looks up key in the map, and returns either a pointer
    29  // to the node holding key, or a pointer to the location where
    30  // such a node would go.
    31  func (m *Map[K, V]) find(key K) **node[K, V] {
    32  	pn := &m.root
    33  	for *pn != nil {
    34  		switch cmp := m.compare(key, (*pn).key); {
    35  		case cmp < 0:
    36  			pn = &(*pn).left
    37  		case cmp > 0:
    38  			pn = &(*pn).right
    39  		default:
    40  			return pn
    41  		}
    42  	}
    43  	return pn
    44  }
    45  
    46  // Insert inserts a new key/value into the map.
    47  // If the key is already present, the value is replaced.
    48  // Returns true if this is a new key, false if already present.
    49  func (m *Map[K, V]) Insert(key K, val V) bool {
    50  	pn := m.find(key)
    51  	if *pn != nil {
    52  		(*pn).val = val
    53  		return false
    54  	}
    55          *pn = &node[K, V]{key: key, val: val}
    56  	return true
    57  }
    58  
    59  // Find returns the value associated with a key, or zero if not present.
    60  // The found result reports whether the key was found.
    61  func (m *Map[K, V]) Find(key K) (V, bool) {
    62  	pn := m.find(key)
    63  	if *pn == nil {
    64  		var zero V // see the discussion of zero values, above
    65  		return zero, false
    66  	}
    67  	return (*pn).val, true
    68  }
    69  
    70  // keyValue is a pair of key and value used when iterating.
    71  type keyValue[K, V any] struct {
    72  	key K
    73  	val V
    74  }
    75  
    76  // InOrder returns an iterator that does an in-order traversal of the map.
    77  func (m *Map[K, V]) InOrder() *Iterator[K, V] {
    78  	sender, receiver := chans.Ranger[keyValue[K, V]]()
    79  	var f func(*node[K, V]) bool
    80  	f = func(n *node[K, V]) bool {
    81  		if n == nil {
    82  			return true
    83  		}
    84  		// Stop sending values if sender.Send returns false,
    85  		// meaning that nothing is listening at the receiver end.
    86  		return f(n.left) &&
    87                          sender.Send(keyValue[K, V]{n.key, n.val}) &&
    88  			f(n.right)
    89  	}
    90  	go func() {
    91  		f(m.root)
    92  		sender.Close()
    93  	}()
    94  	return &Iterator[K, V]{receiver}
    95  }
    96  
    97  // Iterator is used to iterate over the map.
    98  type Iterator[K, V any] struct {
    99  	r *chans.Receiver[keyValue[K, V]]
   100  }
   101  
   102  // Next returns the next key and value pair, and a boolean indicating
   103  // whether they are valid or whether we have reached the end.
   104  func (it *Iterator[K, V]) Next() (K, V, bool) {
   105  	keyval, ok := it.r.Next()
   106  	if !ok {
   107  		var zerok K
   108  		var zerov V
   109  		return zerok, zerov, false
   110  	}
   111  	return keyval.key, keyval.val, true
   112  }