github.com/webx-top/com@v1.2.12/safemap.go (about)

     1  package com
     2  
     3  import (
     4  	"sync"
     5  )
     6  
     7  type SafeMap struct {
     8  	lock *sync.RWMutex
     9  	bm   map[interface{}]interface{}
    10  }
    11  
    12  func NewSafeMap() *SafeMap {
    13  	return &SafeMap{
    14  		lock: new(sync.RWMutex),
    15  		bm:   make(map[interface{}]interface{}),
    16  	}
    17  }
    18  
    19  //Get from maps return the k's value
    20  func (m *SafeMap) Get(k interface{}) interface{} {
    21  	m.lock.RLock()
    22  	defer m.lock.RUnlock()
    23  	if val, ok := m.bm[k]; ok {
    24  		return val
    25  	}
    26  	return nil
    27  }
    28  
    29  // Set maps the given key and value. Returns false
    30  // if the key is already in the map and changes nothing.
    31  func (m *SafeMap) Set(k interface{}, v interface{}) bool {
    32  	m.lock.Lock()
    33  	defer m.lock.Unlock()
    34  	if val, ok := m.bm[k]; !ok {
    35  		m.bm[k] = v
    36  	} else if val != v {
    37  		m.bm[k] = v
    38  	} else {
    39  		return false
    40  	}
    41  	return true
    42  }
    43  
    44  // Check returns true if k is exist in the map.
    45  func (m *SafeMap) Check(k interface{}) bool {
    46  	m.lock.RLock()
    47  	defer m.lock.RUnlock()
    48  	if _, ok := m.bm[k]; !ok {
    49  		return false
    50  	}
    51  	return true
    52  }
    53  
    54  func (m *SafeMap) Delete(k interface{}) {
    55  	m.lock.Lock()
    56  	defer m.lock.Unlock()
    57  	delete(m.bm, k)
    58  }
    59  
    60  func (m *SafeMap) Items() map[interface{}]interface{} {
    61  	m.lock.RLock()
    62  	defer m.lock.RUnlock()
    63  	return m.bm
    64  }
    65  
    66  func NewOrderlySafeMap() *OrderlySafeMap {
    67  	return &OrderlySafeMap{
    68  		SafeMap: NewSafeMap(),
    69  		keys:    make([]interface{}, 0),
    70  	}
    71  }
    72  
    73  type OrderlySafeMap struct {
    74  	*SafeMap
    75  	keys   []interface{} // map keys
    76  	values []interface{} // map values
    77  }
    78  
    79  func (m *OrderlySafeMap) Set(k interface{}, v interface{}) bool {
    80  	m.lock.Lock()
    81  	defer m.lock.Unlock()
    82  	if val, ok := m.bm[k]; !ok {
    83  		m.bm[k] = v
    84  		m.keys = append(m.keys, k)
    85  	} else if val != v {
    86  		m.bm[k] = v
    87  	} else {
    88  		return false
    89  	}
    90  	return true
    91  }
    92  
    93  func (m *OrderlySafeMap) Delete(k interface{}) {
    94  	m.lock.Lock()
    95  	defer m.lock.Unlock()
    96  	delete(m.bm, k)
    97  	endIndex := len(m.keys) - 1
    98  	for index, mapKey := range m.keys {
    99  		if mapKey != k {
   100  			continue
   101  		}
   102  		if index == endIndex {
   103  			m.keys = m.keys[0:index]
   104  			break
   105  		}
   106  		if index == 0 {
   107  			m.keys = m.keys[1:]
   108  			break
   109  		}
   110  		m.keys = append(m.keys[0:index], m.keys[index+1:]...)
   111  		break
   112  	}
   113  }
   114  
   115  func (m *OrderlySafeMap) Keys() []interface{} {
   116  	m.lock.Lock()
   117  	defer m.lock.Unlock()
   118  	return m.keys
   119  }
   120  
   121  func (m *OrderlySafeMap) Values(force ...bool) []interface{} {
   122  	m.lock.Lock()
   123  	defer m.lock.Unlock()
   124  	if (len(force) == 0 || !force[0]) && m.values != nil {
   125  		return m.values
   126  	}
   127  	m.values = []interface{}{}
   128  	for _, mapKey := range m.keys {
   129  		m.values = append(m.values, m.bm[mapKey])
   130  	}
   131  	return m.values
   132  }
   133  
   134  func (m *OrderlySafeMap) VisitAll(callback func(int, interface{}, interface{})) {
   135  	m.lock.Lock()
   136  	for index, mapKey := range m.keys {
   137  		callback(index, mapKey, m.bm[mapKey])
   138  	}
   139  	m.lock.Unlock()
   140  }