gitlab.com/apertussolutions/u-root@v7.0.0+incompatible/cmds/core/elvish/hashmap/hashmap.go (about)

     1  // Copyright 2018 the u-root 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  // Package hashmap implements persistent hashmap.
     5  package hashmap
     6  
     7  import "log"
     8  
     9  // Equal is the type of a function that reports whether two keys are equal.
    10  type Equal func(k1, k2 interface{}) bool
    11  
    12  // Hash is the type of a function that returns the hash code of a key.
    13  type Hash func(k interface{}) uint32
    14  
    15  // New takes an equality function and a hash function, and returns an empty
    16  // Map.
    17  func New(e Equal, h Hash) Map {
    18  	return &hashMap{m: make(map[interface{}]interface{})}
    19  }
    20  
    21  type hashMap struct {
    22  	m map[interface{}]interface{}
    23  }
    24  
    25  func (m *hashMap) Len() int {
    26  	return len(m.m)
    27  }
    28  
    29  func (m *hashMap) Index(k interface{}) (interface{}, bool) {
    30  	i, ok := m.m[k]
    31  	return i, ok
    32  }
    33  
    34  func (m *hashMap) Assoc(k, v interface{}) Map {
    35  	item, ok := m.m[k]
    36  	if ok {
    37  		log.Panicf("Storing %v at %v want ! ok, got %v", v, k, item)
    38  	}
    39  	n := &hashMap{m: make(map[interface{}]interface{})}
    40  	for k, v := range m.m {
    41  		n.m[k] = v
    42  	}
    43  	n.m[k] = v
    44  	return n
    45  }
    46  
    47  func (m *hashMap) Dissoc(del interface{}) Map {
    48  	n := &hashMap{m: make(map[interface{}]interface{})}
    49  	for k, v := range m.m {
    50  		if k == del {
    51  			continue
    52  		}
    53  		n.m[k] = v
    54  	}
    55  	return n
    56  }
    57  
    58  type kv struct {
    59  	k interface{}
    60  	v interface{}
    61  }
    62  
    63  type iter struct {
    64  	m   *hashMap
    65  	cur *kv
    66  	kvs chan (*kv)
    67  }
    68  
    69  func (i *iter) Elem() (interface{}, interface{}) {
    70  	return i.cur.k, i.cur.v
    71  }
    72  
    73  func (i *iter) HasElem() bool {
    74  	return i.cur != nil
    75  }
    76  
    77  func (i *iter) Next() {
    78  	i.cur = <-i.kvs
    79  }
    80  func (m *hashMap) Iterator() Iterator {
    81  	c := make(chan *kv)
    82  	go func() {
    83  		for k, v := range m.m {
    84  			c <- &kv{k, v}
    85  		}
    86  		close(c)
    87  	}()
    88  	return &iter{m: m, kvs: c, cur: <-c}
    89  }