You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							60 lines
						
					
					
						
							1.2 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							60 lines
						
					
					
						
							1.2 KiB
						
					
					
				
								package util
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"sync"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								// A mostly for read map, which can thread-safely
							 | 
						|
								// initialize the map entries.
							 | 
						|
								type ConcurrentReadMap struct {
							 | 
						|
									sync.RWMutex
							 | 
						|
								
							 | 
						|
									items map[string]interface{}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func NewConcurrentReadMap() *ConcurrentReadMap {
							 | 
						|
									return &ConcurrentReadMap{items: make(map[string]interface{})}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (m *ConcurrentReadMap) initMapEntry(key string, newEntry func() interface{}) (value interface{}) {
							 | 
						|
									m.Lock()
							 | 
						|
									defer m.Unlock()
							 | 
						|
									if value, ok := m.items[key]; ok {
							 | 
						|
										return value
							 | 
						|
									}
							 | 
						|
									value = newEntry()
							 | 
						|
									m.items[key] = value
							 | 
						|
									return value
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (m *ConcurrentReadMap) Get(key string, newEntry func() interface{}) interface{} {
							 | 
						|
									m.RLock()
							 | 
						|
									if value, ok := m.items[key]; ok {
							 | 
						|
										m.RUnlock()
							 | 
						|
										return value
							 | 
						|
									}
							 | 
						|
									m.RUnlock()
							 | 
						|
									return m.initMapEntry(key, newEntry)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (m *ConcurrentReadMap) Find(key string) (interface{}, bool) {
							 | 
						|
									m.RLock()
							 | 
						|
									value, ok := m.items[key]
							 | 
						|
									m.RUnlock()
							 | 
						|
									return value, ok
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (m *ConcurrentReadMap) Items() (itemsCopy []interface{}) {
							 | 
						|
									m.RLock()
							 | 
						|
									for _, i := range m.items {
							 | 
						|
										itemsCopy = append(itemsCopy, i)
							 | 
						|
									}
							 | 
						|
									m.RUnlock()
							 | 
						|
									return itemsCopy
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func (m *ConcurrentReadMap) Delete(key string) {
							 | 
						|
									m.Lock()
							 | 
						|
									delete(m.items, key)
							 | 
						|
									m.Unlock()
							 | 
						|
								}
							 |