github.com/sandwich-go/boost@v1.3.29/xcontainer/smap/gen_int_any.go (about)

     1  // Code generated by gotemplate. DO NOT EDIT.
     2  
     3  // smap 包提供了一个分片的协程安全的映射
     4  // NewWithSharedCount 返回一个线程安全的映射实例
     5  // New 返回一个线程安全的映射实例
     6  package smap
     7  
     8  import (
     9  	"strconv"
    10  	"sync"
    11  )
    12  
    13  //template type Concurrent(KType,VType,KeyHash)
    14  
    15  // A thread safe map.
    16  // To avoid lock bottlenecks this map is dived to several (DefaultShardCount) map shards.
    17  
    18  var DefaultShardCountIntAny = uint64(32)
    19  
    20  type IntAny struct {
    21  	shardedList  []*shardedIntAny
    22  	shardedCount uint64
    23  }
    24  
    25  type shardedIntAny struct {
    26  	items map[int]interface{}
    27  	sync.RWMutex
    28  }
    29  
    30  type TupleIntAny struct {
    31  	Key int
    32  	Val interface{}
    33  }
    34  
    35  // NewWithSharedCount 返回协程安全版本
    36  func NewWithSharedCountIntAny(sharedCount uint64) *IntAny {
    37  	p := &IntAny{
    38  		shardedCount: sharedCount,
    39  		shardedList:  make([]*shardedIntAny, sharedCount),
    40  	}
    41  	for i := uint64(0); i < sharedCount; i++ {
    42  		p.shardedList[i] = &shardedIntAny{items: make(map[int]interface{})}
    43  	}
    44  	return p
    45  }
    46  
    47  // New 返回协程安全版本
    48  func NewIntAny() *IntAny {
    49  	return NewWithSharedCountIntAny(DefaultShardCountIntAny)
    50  }
    51  
    52  // GetShard 返回key对应的分片
    53  func (m *IntAny) GetShard(key int) *shardedIntAny {
    54  	return m.shardedList[KeyToHashInt(key)%m.shardedCount]
    55  }
    56  
    57  // IsEmpty 返回容器是否为空
    58  func (m *IntAny) IsEmpty() bool {
    59  	return m.Count() == 0
    60  }
    61  
    62  // Set 设定元素
    63  func (m *IntAny) Set(key int, value interface{}) {
    64  	shard := m.GetShard(key)
    65  	shard.Lock()
    66  	shard.items[key] = value
    67  	shard.Unlock()
    68  }
    69  
    70  // Keys 返回所有的key列表
    71  func (m *IntAny) Keys() []int {
    72  	var ret []int
    73  	for _, shard := range m.shardedList {
    74  		shard.RLock()
    75  		for key := range shard.items {
    76  			ret = append(ret, key)
    77  		}
    78  		shard.RUnlock()
    79  	}
    80  	return ret
    81  }
    82  
    83  // GetAll 返回所有元素副本,其中value浅拷贝
    84  func (m *IntAny) GetAll() map[int]interface{} {
    85  	data := make(map[int]interface{})
    86  	for _, shard := range m.shardedList {
    87  		shard.RLock()
    88  		for key, val := range shard.items {
    89  			data[key] = val
    90  		}
    91  		shard.RUnlock()
    92  	}
    93  	return data
    94  }
    95  
    96  // Clear 清空元素
    97  func (m *IntAny) Clear() {
    98  	for _, shard := range m.shardedList {
    99  		shard.Lock()
   100  		shard.items = make(map[int]interface{})
   101  		shard.Unlock()
   102  	}
   103  }
   104  
   105  // ClearWithFunc 清空元素,onClear在对应分片的Lock内执行,执行完毕后对容器做整体clear操作
   106  //
   107  // Note: 不要在onClear对当前容器做读写操作,容易死锁
   108  //
   109  // data.ClearWithFuncLock(func(key string,val string) {
   110  //		data.Get(...) // 死锁
   111  // })
   112  //
   113  func (m *IntAny) ClearWithFuncLock(onClear func(key int, val interface{})) {
   114  	for _, shard := range m.shardedList {
   115  		shard.Lock()
   116  		for key, val := range shard.items {
   117  			onClear(key, val)
   118  		}
   119  		shard.items = make(map[int]interface{})
   120  		shard.Unlock()
   121  	}
   122  }
   123  
   124  // MGet 返回多个元素
   125  func (m *IntAny) MGet(keys ...int) map[int]interface{} {
   126  	data := make(map[int]interface{})
   127  	for _, key := range keys {
   128  		if val, ok := m.Get(key); ok {
   129  			data[key] = val
   130  		}
   131  	}
   132  	return data
   133  }
   134  
   135  // MSet 同时设定多个元素
   136  func (m *IntAny) MSet(data map[int]interface{}) {
   137  	for key, value := range data {
   138  		m.Set(key, value)
   139  	}
   140  }
   141  
   142  // SetNX 如果key不存在,则设定为value, 设定成功则返回true,否则返回false
   143  func (m *IntAny) SetNX(key int, value interface{}) (isSet bool) {
   144  	shard := m.GetShard(key)
   145  	shard.Lock()
   146  	if _, ok := shard.items[key]; !ok {
   147  		shard.items[key] = value
   148  		isSet = true
   149  	}
   150  	shard.Unlock()
   151  	return isSet
   152  }
   153  
   154  // LockFuncWithKey 对key对应的分片加写锁,并用f操作该分片内数据
   155  //
   156  // Note: 不要对f中对容器的该分片做读写操作,可以直接操作shardData数据源
   157  //
   158  //  data.LockFuncWithKey("test",func(shardData map[string]string) {
   159  //     data.Remove("test")      // 当前分片已被加读锁, 死锁
   160  //  })
   161  //
   162  func (m *IntAny) LockFuncWithKey(key int, f func(shardData map[int]interface{})) {
   163  	shard := m.GetShard(key)
   164  	shard.Lock()
   165  	defer shard.Unlock()
   166  	f(shard.items)
   167  }
   168  
   169  // RLockFuncWithKey 对key对应的分片加读锁,并用f操作该分片内数据
   170  //
   171  // Note: 不要在f内对容器做写操作,否则会引起死锁,可以直接操作shardData数据源
   172  //
   173  //  data.RLockFuncWithKey("test",func(shardData map[string]string) {
   174  //     data.Remove("test")      // 当前分片已被加读锁, 死锁
   175  //  })
   176  //
   177  func (m *IntAny) RLockFuncWithKey(key int, f func(shardData map[int]interface{})) {
   178  	shard := m.GetShard(key)
   179  	shard.RLock()
   180  	defer shard.RUnlock()
   181  	f(shard.items)
   182  }
   183  
   184  // LockFunc 遍历容器分片,f在Lock写锁内执行
   185  //
   186  // Note: 不要在f内对容器做读写操作,否则会引起死锁,可以直接操作shardData数据源
   187  //
   188  //  data.LockFunc(func(shardData map[string]string) {
   189  //     data.Count()             // 当前分片已被加写锁, 死锁
   190  //  })
   191  //
   192  func (m *IntAny) LockFunc(f func(shardData map[int]interface{})) {
   193  	for _, shard := range m.shardedList {
   194  		shard.Lock()
   195  		f(shard.items)
   196  		shard.Unlock()
   197  	}
   198  }
   199  
   200  // RLockFunc 遍历容器分片,f在RLock读锁内执行
   201  //
   202  // Note: 不要在f内对容器做修改操作,否则会引起死锁,可以直接操作shardData数据源
   203  //
   204  //  data.RLockFunc(func(shardData map[string]string) {
   205  //     data.Remove("test")      // 当前分片已被加读锁, 死锁
   206  //  })
   207  //
   208  func (m *IntAny) RLockFunc(f func(shardData map[int]interface{})) {
   209  	for _, shard := range m.shardedList {
   210  		shard.RLock()
   211  		f(shard.items)
   212  		shard.RUnlock()
   213  	}
   214  }
   215  
   216  func (m *IntAny) doSetWithLockCheck(key int, val interface{}) (result interface{}, isSet bool) {
   217  	shard := m.GetShard(key)
   218  	shard.Lock()
   219  
   220  	if got, ok := shard.items[key]; ok {
   221  		shard.Unlock()
   222  		return got, false
   223  	}
   224  
   225  	shard.items[key] = val
   226  	isSet = true
   227  	result = val
   228  	shard.Unlock()
   229  	return
   230  }
   231  
   232  func (m *IntAny) doSetWithLockCheckWithFunc(key int, f func(key int) interface{}) (result interface{}, isSet bool) {
   233  	shard := m.GetShard(key)
   234  	shard.Lock()
   235  
   236  	if got, ok := shard.items[key]; ok {
   237  		shard.Unlock()
   238  		return got, false
   239  	}
   240  
   241  	val := f(key)
   242  	shard.items[key] = val
   243  	isSet = true
   244  	result = val
   245  	shard.Unlock()
   246  	return
   247  }
   248  
   249  // GetOrSetFunc 获取或者设定数值,方法f在Lock写锁外执行, 如元素早已存在则返回false,设定成功返回true
   250  func (m *IntAny) GetOrSetFunc(key int, f func(key int) interface{}) (result interface{}, isSet bool) {
   251  	if v, ok := m.Get(key); ok {
   252  		return v, false
   253  	}
   254  	return m.doSetWithLockCheck(key, f(key))
   255  }
   256  
   257  // GetOrSetFuncLock 获取或者设定数值,方法f在Lock写锁内执行, 如元素早已存在则返回false,设定成功返回true
   258  //
   259  // Note: 不要在f内对容器做操作,否则会死锁
   260  //
   261  //  data.GetOrSetFuncLock(“test”,func(key string)string {
   262  //     data.Count() // 死锁
   263  //  })
   264  //
   265  func (m *IntAny) GetOrSetFuncLock(key int, f func(key int) interface{}) (result interface{}, isSet bool) {
   266  	if v, ok := m.Get(key); ok {
   267  		return v, false
   268  	}
   269  	return m.doSetWithLockCheckWithFunc(key, f)
   270  }
   271  
   272  // GetOrSet 获取或设定元素, 如元素早已存在则返回false,设定成功返回true
   273  func (m *IntAny) GetOrSet(key int, val interface{}) (interface{}, bool) {
   274  	if v, ok := m.Get(key); ok {
   275  		return v, false
   276  	}
   277  	return m.doSetWithLockCheck(key, val)
   278  }
   279  
   280  // Get 返回key对应的元素,不存在返回false
   281  func (m *IntAny) Get(key int) (interface{}, bool) {
   282  	shard := m.GetShard(key)
   283  	shard.RLock()
   284  	val, ok := shard.items[key]
   285  	shard.RUnlock()
   286  	return val, ok
   287  }
   288  
   289  // Len Count方法别名
   290  func (m *IntAny) Len() int { return m.Count() }
   291  
   292  // Size Count方法别名
   293  func (m *IntAny) Size() int { return m.Count() }
   294  
   295  // Count 返回容器内元素数量
   296  func (m *IntAny) Count() int {
   297  	count := 0
   298  	for i := uint64(0); i < m.shardedCount; i++ {
   299  		shard := m.shardedList[i]
   300  		shard.RLock()
   301  		count += len(shard.items)
   302  		shard.RUnlock()
   303  	}
   304  	return count
   305  }
   306  
   307  // Has 是否存在key对应的元素
   308  func (m *IntAny) Has(key int) bool {
   309  	shard := m.GetShard(key)
   310  	shard.RLock()
   311  	_, ok := shard.items[key]
   312  	shard.RUnlock()
   313  	return ok
   314  }
   315  
   316  // Remove 删除key对应的元素
   317  func (m *IntAny) Remove(key int) {
   318  	shard := m.GetShard(key)
   319  	shard.Lock()
   320  	delete(shard.items, key)
   321  	shard.Unlock()
   322  }
   323  
   324  // GetAndRemove 返回key对应的元素并将其由容器中删除,如果元素不存在则返回false
   325  func (m *IntAny) GetAndRemove(key int) (interface{}, bool) {
   326  	shard := m.GetShard(key)
   327  	shard.Lock()
   328  	val, ok := shard.items[key]
   329  	delete(shard.items, key)
   330  	shard.Unlock()
   331  	return val, ok
   332  }
   333  
   334  // Iter 迭代当前容器内所有元素,使用无缓冲chan
   335  //
   336  // Note: 不要在迭代过程中对当前容器作修改操作(申请写锁),容易会产生死锁
   337  //
   338  //  for v:= data.Iter() {
   339  //		data.Remove(v.Key) // 尝试删除元素申请分片Lock,但是Iter内部的迭代协程对分片做了RLock,导致死锁
   340  //  }
   341  //
   342  func (m *IntAny) Iter() <-chan TupleIntAny {
   343  	ch := make(chan TupleIntAny)
   344  	go func() {
   345  		// Foreach shard.
   346  		for _, shard := range m.shardedList {
   347  			shard.RLock()
   348  			// Foreach key, value pair.
   349  			for key, val := range shard.items {
   350  				ch <- TupleIntAny{key, val}
   351  			}
   352  			shard.RUnlock()
   353  		}
   354  		close(ch)
   355  	}()
   356  	return ch
   357  }
   358  
   359  // IterBuffered 迭代当前容器内所有元素,使用有缓冲chan,缓冲区大小等于容器大小,迭代过程中操作容器是安全的
   360  func (m *IntAny) IterBuffered() <-chan TupleIntAny {
   361  	ch := make(chan TupleIntAny, m.Count())
   362  	go func() {
   363  		// Foreach shard.
   364  		for _, shard := range m.shardedList {
   365  			// Foreach key, value pair.
   366  			shard.RLock()
   367  			for key, val := range shard.items {
   368  				ch <- TupleIntAny{key, val}
   369  			}
   370  			shard.RUnlock()
   371  		}
   372  		close(ch)
   373  	}()
   374  	return ch
   375  }
   376  
   377  //template format
   378  var __formatKTypeToIntAny = func(i interface{}) int {
   379  	switch ii := i.(type) {
   380  	case int:
   381  		return int(ii)
   382  	case int8:
   383  		return int(ii)
   384  	case int16:
   385  		return int(ii)
   386  	case int32:
   387  		return int(ii)
   388  	case int64:
   389  		return int(ii)
   390  	case uint:
   391  		return int(ii)
   392  	case uint8:
   393  		return int(ii)
   394  	case uint16:
   395  		return int(ii)
   396  	case uint32:
   397  		return int(ii)
   398  	case uint64:
   399  		return int(ii)
   400  	case float32:
   401  		return int(ii)
   402  	case float64:
   403  		return int(ii)
   404  	case string:
   405  		iv, err := strconv.ParseInt(ii, 10, 64)
   406  		if err != nil {
   407  			panic(err)
   408  		}
   409  		return int(iv)
   410  	default:
   411  		panic("unknown type")
   412  	}
   413  }
   414  
   415  //template format
   416  var __formatVTypeToIntAny = func(i interface{}) interface{} {
   417  	return i
   418  }