github.com/sandwich-go/boost@v1.3.29/xcontainer/templates/syncmap/syncmap.go (about)

     1  // syncmap 提供了一个同步的映射实现,允许安全并发的访问
     2  package syncmap
     3  
     4  import (
     5  	"sort"
     6  	"sync"
     7  )
     8  
     9  //template type SyncMap(KType,VType)
    10  
    11  type KType string
    12  type VType interface{}
    13  
    14  // SyncMap 定义并发安全的映射,使用 sync.Map 来实现
    15  type SyncMap struct {
    16  	sm     sync.Map
    17  	locker sync.RWMutex
    18  }
    19  
    20  // NewSyncMap 构造函数,返回一个新的 SyncMap
    21  func NewSyncMap() *SyncMap {
    22  	return &SyncMap{}
    23  }
    24  
    25  // Keys 获取映射中的所有键,返回一个 Key 类型的切片
    26  func (s *SyncMap) Keys() (ret []KType) {
    27  	s.sm.Range(func(key, value interface{}) bool {
    28  		ret = append(ret, key.(KType))
    29  		return true
    30  	})
    31  	return ret
    32  }
    33  
    34  // Len 获取映射中键值对的数量
    35  func (s *SyncMap) Len() (c int) {
    36  	s.sm.Range(func(key, value interface{}) bool {
    37  		c++
    38  		return true
    39  	})
    40  	return c
    41  }
    42  
    43  // Contains 检查映射中是否包含指定键
    44  func (s *SyncMap) Contains(key KType) (ok bool) {
    45  	_, ok = s.Load(key)
    46  	return
    47  }
    48  
    49  // Get 获取映射中的值
    50  func (s *SyncMap) Get(key KType) (value VType) {
    51  	value, _ = s.Load(key)
    52  	return
    53  }
    54  
    55  // Load 获取映射中的值和是否成功加载的标志
    56  func (s *SyncMap) Load(key KType) (value VType, loaded bool) {
    57  	if v, ok := s.sm.Load(key); ok {
    58  		return v.(VType), true
    59  	}
    60  	return
    61  }
    62  
    63  // DeleteMultiple 删除映射中的多个键
    64  func (s *SyncMap) DeleteMultiple(keys ...KType) {
    65  	for _, k := range keys {
    66  		s.sm.Delete(k)
    67  	}
    68  }
    69  
    70  // Clear 清空映射
    71  func (s *SyncMap) Clear() {
    72  	s.sm.Range(func(key, value interface{}) bool {
    73  		s.sm.Delete(key)
    74  		return true
    75  	})
    76  }
    77  
    78  // Delete 删除映射中的值
    79  func (s *SyncMap) Delete(key KType) { s.sm.Delete(key) }
    80  
    81  // Store 往映射中存储一个键值对
    82  func (s *SyncMap) Store(key KType, val VType) { s.sm.Store(key, val) }
    83  
    84  // LoadAndDelete 获取映射中的值,并将其从映射中删除
    85  func (s *SyncMap) LoadAndDelete(key KType) (value VType, loaded bool) {
    86  	if v, ok := s.sm.LoadAndDelete(key); ok {
    87  		return v.(VType), true
    88  	}
    89  	return
    90  }
    91  
    92  // GetOrSetFuncErrorLock 函数根据key查找值,如果key存在则返回对应的值,否则用cf函数计算得到一个新的值,存储到 SyncMap 中并返回。
    93  // 如果执行cf函数时出错,则返回error。
    94  // 函数内部使用读写锁实现并发安全
    95  func (s *SyncMap) GetOrSetFuncErrorLock(key KType, cf func(key KType) (VType, error)) (value VType, loaded bool, err error) {
    96  	return s.LoadOrStoreFuncErrorLock(key, cf)
    97  }
    98  
    99  // LoadOrStoreFuncErrorLock 函数根据key查找值,如果key存在则返回对应的值,否则用cf函数计算得到一个新的值,存储到 SyncMap 中并返回。
   100  // 如果执行cf函数时出错,则返回error。
   101  // 函数内部使用读写锁实现并发安全
   102  func (s *SyncMap) LoadOrStoreFuncErrorLock(key KType, cf func(key KType) (VType, error)) (value VType, loaded bool, err error) {
   103  	if v, ok := s.Load(key); ok {
   104  		return v, true, nil
   105  	}
   106  	// 如果不存在,则加写锁,再次查找,如果获取到则直接返回
   107  	s.locker.Lock()
   108  	defer s.locker.Unlock()
   109  	// 再次重试,如果获取到则直接返回
   110  	if v, ok := s.Load(key); ok {
   111  		return v, true, nil
   112  	}
   113  	// 如果还是不存在,则执行cf函数计算出value,并存储到 SyncMap 中
   114  	value, err = cf(key)
   115  	if err != nil {
   116  		return value, false, err
   117  	}
   118  	s.Store(key, value)
   119  	return value, false, nil
   120  }
   121  
   122  // GetOrSetFuncLock 根据key获取对应的value,若不存在则通过cf回调创建value并存储
   123  func (s *SyncMap) GetOrSetFuncLock(key KType, cf func(key KType) VType) (value VType, loaded bool) {
   124  	return s.LoadOrStoreFuncLock(key, cf)
   125  }
   126  
   127  // LoadOrStoreFuncLock 根据key获取对应的value,若不存在则通过cf回调创建value并存储
   128  func (s *SyncMap) LoadOrStoreFuncLock(key KType, cf func(key KType) VType) (value VType, loaded bool) {
   129  	value, loaded, _ = s.LoadOrStoreFuncErrorLock(key, func(key KType) (VType, error) {
   130  		return cf(key), nil
   131  	})
   132  	return value, loaded
   133  }
   134  
   135  // LoadOrStore 存储一个 key-value 对,若key已存在则返回已存在的value
   136  func (s *SyncMap) LoadOrStore(key KType, val VType) (VType, bool) {
   137  	actual, ok := s.sm.LoadOrStore(key, val)
   138  	return actual.(VType), ok
   139  }
   140  
   141  // Range 遍历映射中的 key-value 对,对每个 key-value 对执行给定的函数f
   142  func (s *SyncMap) Range(f func(key KType, value VType) bool) {
   143  	s.sm.Range(func(k, v interface{}) bool {
   144  		return f(k.(KType), v.(VType))
   145  	})
   146  }
   147  
   148  // RangeDeterministic 按照 key 的顺序遍历映射中的 key-value 对,对每个 key-value 对执行给定的函数 f, f返回false则中断退出
   149  // 参数 sortableGetter 接收一个 KType 切片并返回一个可排序接口,用于对key进行排序
   150  func (s *SyncMap) RangeDeterministic(f func(key KType, value VType) bool, sortableGetter func([]KType) sort.Interface) {
   151  	var keys []KType
   152  	s.sm.Range(func(key, value interface{}) bool {
   153  		keys = append(keys, key.(KType))
   154  		return true
   155  	})
   156  	sort.Sort(sortableGetter(keys))
   157  	for _, k := range keys {
   158  		if v, ok := s.Load(k); ok {
   159  			if !f(k, v) {
   160  				break
   161  			}
   162  		}
   163  	}
   164  }