github.com/git-amp/amp-sdk-go@v0.7.5/stdlib/bufs/map.go (about)

     1  package bufs
     2  
     3  import (
     4  	"bytes"
     5  	"hash/maphash"
     6  )
     7  
     8  type MapEntry interface {
     9  	MapKey() []byte
    10  }
    11  
    12  type BufMap struct {
    13  	hashMap map[uint64]MapEntry
    14  	hasher  maphash.Hash
    15  }
    16  
    17  func NewBufMap() BufMap {
    18  	return BufMap{
    19  		hashMap: make(map[uint64]MapEntry),
    20  	}
    21  }
    22  
    23  // Returns the entry having a matching key (or nil)
    24  func (m *BufMap) Get(key []byte) MapEntry {
    25  	existing, _ := m.get(key)
    26  	return existing
    27  }
    28  
    29  // Returns the entry being replaced (or nil)
    30  func (m *BufMap) Put(entry MapEntry) MapEntry {
    31  	existing, atHash := m.get(entry.MapKey())
    32  
    33  	m.hashMap[atHash] = entry
    34  	return existing
    35  }
    36  
    37  // Removes and returns the entry having a matching key (or nil)
    38  func (m *BufMap) Remove(key []byte) MapEntry {
    39  	existing, atHash := m.get(key)
    40  
    41  	if existing != nil {
    42  		delete(m.hashMap, atHash)
    43  	}
    44  	return existing
    45  }
    46  
    47  func (m *BufMap) get(key []byte) (entry MapEntry, atHash uint64) {
    48  	m.hasher.Reset()
    49  	m.hasher.Write(key)
    50  	atHash = m.hasher.Sum64()
    51  
    52  	var found bool
    53  	entry, found = m.hashMap[atHash]
    54  	for found {
    55  		if bytes.Equal(entry.MapKey(), key) {
    56  			return
    57  		}
    58  		atHash++
    59  		entry, found = m.hashMap[atHash]
    60  	}
    61  
    62  	return nil, atHash
    63  }