initial commit
This commit is contained in:
		
							
								
								
									
										119
									
								
								map.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								map.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					package cmap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Map represents a map safe for concurrent use
 | 
				
			||||||
 | 
					type Map[K comparable, V any] struct {
 | 
				
			||||||
 | 
						mutex sync.RWMutex
 | 
				
			||||||
 | 
						data  map[K]V
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// New creates a new generic Map
 | 
				
			||||||
 | 
					func New[K comparable, V any]() *Map[K, V] {
 | 
				
			||||||
 | 
						return &Map[K, V]{data: map[K]V{}}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Put puts the key-value pair into m
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Put(key K, value V) {
 | 
				
			||||||
 | 
						m.mutex.Lock()
 | 
				
			||||||
 | 
						defer m.mutex.Unlock()
 | 
				
			||||||
 | 
						m.data[key] = value
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetHas returns the corresponding value for the given key in m
 | 
				
			||||||
 | 
					// as well as a bool indicating if a value was present at all
 | 
				
			||||||
 | 
					func (m *Map[K, V]) GetHas(key K) (V, bool) {
 | 
				
			||||||
 | 
						m.mutex.RLock()
 | 
				
			||||||
 | 
						defer m.mutex.RUnlock()
 | 
				
			||||||
 | 
						value, ok := m.data[key]
 | 
				
			||||||
 | 
						return value, ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get returns the corresponding value for the given key in m
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Get(key K) V {
 | 
				
			||||||
 | 
						value, _ := m.GetHas(key)
 | 
				
			||||||
 | 
						return value
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Has returns a bool indicating if a value was present for the given key
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Has(key K) bool {
 | 
				
			||||||
 | 
						_, ok := m.GetHas(key)
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Delete deletes the key-value pair from m
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Delete(key K) {
 | 
				
			||||||
 | 
						m.mutex.Lock()
 | 
				
			||||||
 | 
						defer m.mutex.Unlock()
 | 
				
			||||||
 | 
						delete(m.data, key)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Count returns the amount of key-value pairs currently stored in m
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Count() int {
 | 
				
			||||||
 | 
						m.mutex.RLock()
 | 
				
			||||||
 | 
						defer m.mutex.RUnlock()
 | 
				
			||||||
 | 
						return len(m.data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Iter calls f for every key-value pair stored in m.
 | 
				
			||||||
 | 
					// Be aware that this locks m for write access
 | 
				
			||||||
 | 
					// as pointer types could be modified in f
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Iter(f func(key K, value V)) {
 | 
				
			||||||
 | 
						m.mutex.Lock()
 | 
				
			||||||
 | 
						defer m.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for key, value := range m.data {
 | 
				
			||||||
 | 
							f(key, value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Keys returns a slice containing all currently stored keys in m.
 | 
				
			||||||
 | 
					// Pointer values are returned as they were received
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Keys() []K {
 | 
				
			||||||
 | 
						m.mutex.RLock()
 | 
				
			||||||
 | 
						defer m.mutex.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						keys := make([]K, 0, len(m.data))
 | 
				
			||||||
 | 
						for key := range m.data {
 | 
				
			||||||
 | 
							keys = append(keys, key)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return keys
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Values returns a slice containing all currently stored values in m.
 | 
				
			||||||
 | 
					// Pointer values are returned as they were received
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Values() []V {
 | 
				
			||||||
 | 
						m.mutex.RLock()
 | 
				
			||||||
 | 
						defer m.mutex.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						values := make([]V, 0, len(m.data))
 | 
				
			||||||
 | 
						for _, value := range m.data {
 | 
				
			||||||
 | 
							values = append(values, value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return values
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Do calls f with the underlying primitive map.
 | 
				
			||||||
 | 
					// Be aware that this locks m for write access
 | 
				
			||||||
 | 
					// so Do can be used for reading as well as modifiying m.
 | 
				
			||||||
 | 
					// After f returns, the map will be shallow-copied in order to prevent
 | 
				
			||||||
 | 
					// clueless programmers from storing the map and modifying it afterwards.
 | 
				
			||||||
 | 
					// If you need that little bit of optimization, use DoUnsafe instead
 | 
				
			||||||
 | 
					func (m *Map[K, V]) Do(f func(m map[K]V)) {
 | 
				
			||||||
 | 
						m.mutex.Lock()
 | 
				
			||||||
 | 
						defer m.mutex.Unlock()
 | 
				
			||||||
 | 
						f(m.data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nm := map[K]V{}
 | 
				
			||||||
 | 
						for key, value := range m.data {
 | 
				
			||||||
 | 
							nm[key] = value
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						m.data = nm
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DoUnsafe behaves like Do but does not create a shallow-copy of m
 | 
				
			||||||
 | 
					func (m *Map[K, V]) DoUnsafe(f func(m map[K]V)) {
 | 
				
			||||||
 | 
						m.mutex.Lock()
 | 
				
			||||||
 | 
						defer m.mutex.Unlock()
 | 
				
			||||||
 | 
						f(m.data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user