github.com/influx6/npkg@v0.8.8/nstorage/plain/string_map.go (about)

     1  package plain
     2  
     3  import "sync"
     4  
     5  // SafeStringMap defines an implementation which is a safe concurrent
     6  // string map value store
     7  //
     8  // It provides a safe, concurrently usable implementation with
     9  // blazing read and write speed.
    10  type SafeStringMap struct {
    11  	Capacity uint
    12  	lock     sync.RWMutex
    13  	cache    map[string]string
    14  }
    15  
    16  // NewStringMap returns a new instance of a SafeStringMap.
    17  func NewSafeStringMap(capacity uint) *SafeStringMap {
    18  	var sm SafeStringMap
    19  	sm.Capacity = capacity
    20  	return &sm
    21  }
    22  
    23  // Has returns true/false giving value exits for key.
    24  func (m *SafeStringMap) Has(k string) bool {
    25  	var exists bool
    26  	m.GetMany(func(values map[string]string) {
    27  		_, exists = values[k]
    28  	})
    29  	return exists
    30  }
    31  
    32  // Get returns giving value for key.
    33  func (m *SafeStringMap) Get(k string) (value string) {
    34  	m.GetMany(func(values map[string]string) {
    35  		value = values[k]
    36  	})
    37  	return
    38  }
    39  
    40  // GetMany allows retrieval of many keys from underline map.
    41  //
    42  // WARNING: Never modify the map, ever.
    43  func (m *SafeStringMap) GetMany(fn func(map[string]string)) {
    44  	m.init()
    45  
    46  	m.lock.RLock()
    47  	fn(m.cache)
    48  	m.lock.RUnlock()
    49  }
    50  
    51  // Set adds giving key into underline map.
    52  func (m *SafeStringMap) Set(k string, value string) {
    53  	m.SetMany(func(values map[string]string) {
    54  		values[k] = value
    55  	})
    56  }
    57  
    58  // SetMany adds giving key into underline map.
    59  func (m *SafeStringMap) SetMany(fn func(map[string]string)) {
    60  	m.init()
    61  
    62  	m.lock.Lock()
    63  	fn(m.cache)
    64  	m.lock.Unlock()
    65  }
    66  
    67  func (m *SafeStringMap) init() {
    68  	m.lock.Lock()
    69  	if m.cache != nil {
    70  		m.lock.Unlock()
    71  		return
    72  	}
    73  
    74  	defer m.lock.Unlock()
    75  	if m.Capacity == 0 {
    76  		m.Capacity = 10
    77  	}
    78  	m.cache = make(map[string]string, m.Capacity)
    79  }
    80  
    81  // StringMap defines an implementation which during initial
    82  // loading stores all key and value pairs.
    83  //
    84  // It provides a safe, concurrently usable implementation with
    85  // blazing read and write speed.
    86  type StringMap struct {
    87  	Capacity uint
    88  	lock     sync.RWMutex
    89  	cache    map[string]string
    90  }
    91  
    92  // NewStringMap returns a new instance of a StringMap.
    93  func NewStringMap(capacity uint) *StringMap {
    94  	var sm StringMap
    95  	sm.Capacity = capacity
    96  	return &sm
    97  }
    98  
    99  // Has returns true/false giving value exits for key.
   100  func (m *StringMap) Has(k string) bool {
   101  	var exists bool
   102  	m.GetMany(func(values map[string]string) {
   103  		_, exists = values[k]
   104  	})
   105  	return exists
   106  }
   107  
   108  // Get returns giving value for key.
   109  func (m *StringMap) Get(k string) (value string) {
   110  	m.GetMany(func(values map[string]string) {
   111  		value = values[k]
   112  	})
   113  	return
   114  }
   115  
   116  // GetMany allows retrieval of many keys from underline map.
   117  //
   118  // WARNING: Never modify the map, ever.
   119  func (m *StringMap) GetMany(fn func(map[string]string)) {
   120  	m.init()
   121  
   122  	fn(m.cache)
   123  }
   124  
   125  // Set adds giving key into underline map.
   126  func (m *StringMap) Set(k string, value string) {
   127  	m.SetMany(func(values map[string]string) {
   128  		values[k] = value
   129  	})
   130  }
   131  
   132  // SetMany adds giving key into underline map.
   133  func (m *StringMap) SetMany(fn func(map[string]string)) {
   134  	m.init()
   135  	fn(m.cache)
   136  }
   137  
   138  func (m *StringMap) init() {
   139  	if m.cache != nil {
   140  		return
   141  	}
   142  
   143  	if m.Capacity == 0 {
   144  		m.Capacity = 10
   145  	}
   146  	m.cache = make(map[string]string, m.Capacity)
   147  }