github.com/polarismesh/polaris@v1.17.8/common/utils/collection.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  // Package utils contains common utility functions
    19  package utils
    20  
    21  import "sync"
    22  
    23  // NewSet returns a new Set
    24  func NewSet[K comparable]() *Set[K] {
    25  	return &Set[K]{
    26  		container: make(map[K]struct{}),
    27  	}
    28  }
    29  
    30  type Set[K comparable] struct {
    31  	container map[K]struct{}
    32  }
    33  
    34  // Add adds a string to the set
    35  func (set *Set[K]) Add(val K) {
    36  	set.container[val] = struct{}{}
    37  }
    38  
    39  // Remove removes a string from the set
    40  func (set *Set[K]) Remove(val K) {
    41  	delete(set.container, val)
    42  }
    43  
    44  func (set *Set[K]) ToSlice() []K {
    45  	ret := make([]K, 0, len(set.container))
    46  	for k := range set.container {
    47  		ret = append(ret, k)
    48  	}
    49  	return ret
    50  }
    51  
    52  func (set *Set[K]) Range(fn func(val K)) {
    53  	for k := range set.container {
    54  		fn(k)
    55  	}
    56  }
    57  
    58  // NewSyncSet returns a new Set
    59  func NewSyncSet[K comparable]() *SyncSet[K] {
    60  	return &SyncSet[K]{
    61  		container: make(map[K]struct{}),
    62  	}
    63  }
    64  
    65  type SyncSet[K comparable] struct {
    66  	container map[K]struct{}
    67  	lock      sync.RWMutex
    68  }
    69  
    70  // Add adds a string to the set
    71  func (set *SyncSet[K]) Add(val K) {
    72  	set.lock.Lock()
    73  	defer set.lock.Unlock()
    74  
    75  	set.container[val] = struct{}{}
    76  }
    77  
    78  // Remove removes a string from the set
    79  func (set *SyncSet[K]) Remove(val K) {
    80  	set.lock.Lock()
    81  	defer set.lock.Unlock()
    82  
    83  	delete(set.container, val)
    84  }
    85  
    86  func (set *SyncSet[K]) ToSlice() []K {
    87  	set.lock.RLock()
    88  	defer set.lock.RUnlock()
    89  
    90  	ret := make([]K, 0, len(set.container))
    91  	for k := range set.container {
    92  		ret = append(ret, k)
    93  	}
    94  	return ret
    95  }
    96  
    97  func (set *SyncSet[K]) Range(fn func(val K)) {
    98  	snapshot := map[K]struct{}{}
    99  	set.lock.RLock()
   100  	for k := range set.container {
   101  		snapshot[k] = struct{}{}
   102  	}
   103  	set.lock.RUnlock()
   104  
   105  	for k := range snapshot {
   106  		fn(k)
   107  	}
   108  }
   109  
   110  func (set *SyncSet[K]) Len() int {
   111  	set.lock.RLock()
   112  	defer set.lock.RUnlock()
   113  
   114  	return len(set.container)
   115  }
   116  
   117  func NewSegmentMap[K comparable, V any](soltNum int, hashFunc func(k K) int) *SegmentMap[K, V] {
   118  	locks := make([]*sync.RWMutex, 0, soltNum)
   119  	solts := make([]map[K]V, 0, soltNum)
   120  	for i := 0; i < int(soltNum); i++ {
   121  		locks = append(locks, &sync.RWMutex{})
   122  		solts = append(solts, map[K]V{})
   123  	}
   124  	return &SegmentMap[K, V]{
   125  		soltNum:  soltNum,
   126  		locks:    locks,
   127  		solts:    solts,
   128  		hashFunc: hashFunc,
   129  	}
   130  }
   131  
   132  type SegmentMap[K comparable, V any] struct {
   133  	soltNum  int
   134  	locks    []*sync.RWMutex
   135  	solts    []map[K]V
   136  	hashFunc func(k K) int
   137  }
   138  
   139  func (s *SegmentMap[K, V]) Put(k K, v V) {
   140  	lock, solt := s.caulIndex(k)
   141  	lock.Lock()
   142  	defer lock.Unlock()
   143  	solt[k] = v
   144  }
   145  
   146  func (s *SegmentMap[K, V]) ComputeIfAbsent(k K, supplier func(k K) V) (V, bool) {
   147  	lock, solt := s.caulIndex(k)
   148  	lock.Lock()
   149  	defer lock.Unlock()
   150  	oldVal, ok := solt[k]
   151  	if !ok {
   152  		v := supplier(k)
   153  		solt[k] = v
   154  		return v, true
   155  	}
   156  	return oldVal, false
   157  }
   158  
   159  func (s *SegmentMap[K, V]) PutIfAbsent(k K, v V) (V, bool) {
   160  	lock, solt := s.caulIndex(k)
   161  	lock.Lock()
   162  	defer lock.Unlock()
   163  	oldVal, ok := solt[k]
   164  	if !ok {
   165  		solt[k] = v
   166  		return oldVal, true
   167  	}
   168  	return oldVal, false
   169  }
   170  
   171  func (s *SegmentMap[K, V]) Get(k K) (V, bool) {
   172  	lock, solt := s.caulIndex(k)
   173  	lock.RLock()
   174  	defer lock.RUnlock()
   175  
   176  	v, ok := solt[k]
   177  	return v, ok
   178  }
   179  
   180  func (s *SegmentMap[K, V]) Del(k K) bool {
   181  	lock, solt := s.caulIndex(k)
   182  	lock.Lock()
   183  	defer lock.Unlock()
   184  
   185  	_, ok := solt[k]
   186  	delete(solt, k)
   187  	return ok
   188  }
   189  
   190  func (s *SegmentMap[K, V]) Range(f func(k K, v V)) {
   191  	for i := 0; i < s.soltNum; i++ {
   192  		lock := s.locks[i]
   193  		solt := s.solts[i]
   194  		func() {
   195  			snapshot := map[K]V{}
   196  			lock.RLock()
   197  			for k, v := range solt {
   198  				snapshot[k] = v
   199  			}
   200  			lock.RUnlock()
   201  
   202  			for k, v := range snapshot {
   203  				f(k, v)
   204  			}
   205  		}()
   206  	}
   207  }
   208  
   209  func (s *SegmentMap[K, V]) Count() uint64 {
   210  	count := uint64(0)
   211  	for i := 0; i < s.soltNum; i++ {
   212  		lock := s.locks[i]
   213  		solt := s.solts[i]
   214  		func() {
   215  			lock.RLock()
   216  			defer lock.RUnlock()
   217  			count += uint64(len(solt))
   218  		}()
   219  	}
   220  	return count
   221  }
   222  
   223  func (s *SegmentMap[K, V]) caulIndex(k K) (*sync.RWMutex, map[K]V) {
   224  	index := s.hashFunc(k) % s.soltNum
   225  	lock := s.locks[index]
   226  	solt := s.solts[index]
   227  	return lock, solt
   228  }
   229  
   230  // NewSyncMap
   231  func NewSyncMap[K comparable, V any]() *SyncMap[K, V] {
   232  	return &SyncMap[K, V]{
   233  		m: make(map[K]V, 16),
   234  	}
   235  }
   236  
   237  // SyncMap
   238  type SyncMap[K comparable, V any] struct {
   239  	lock sync.RWMutex
   240  	m    map[K]V
   241  }
   242  
   243  // ComputeIfAbsent
   244  func (s *SyncMap[K, V]) ComputeIfAbsent(k K, supplier func(k K) V) (V, bool) {
   245  	s.lock.Lock()
   246  	defer s.lock.Unlock()
   247  
   248  	actual, exist := s.m[k]
   249  	if exist {
   250  		return actual, false
   251  	}
   252  	val := supplier(k)
   253  	s.m[k] = val
   254  	return val, true
   255  }
   256  
   257  // Load
   258  func (s *SyncMap[K, V]) Load(key K) (V, bool) {
   259  	s.lock.RLock()
   260  	defer s.lock.RUnlock()
   261  
   262  	v, ok := s.m[key]
   263  	if ok {
   264  		return v, ok
   265  	}
   266  	var empty V
   267  	return empty, false
   268  }
   269  
   270  // Store
   271  func (s *SyncMap[K, V]) Store(key K, val V) {
   272  	s.lock.Lock()
   273  	defer s.lock.Unlock()
   274  
   275  	s.m[key] = val
   276  }
   277  
   278  // Range
   279  func (s *SyncMap[K, V]) Range(f func(key K, val V) bool) {
   280  	snapshot := map[K]V{}
   281  	s.lock.RLock()
   282  	for k, v := range s.m {
   283  		snapshot[k] = v
   284  	}
   285  	s.lock.RUnlock()
   286  
   287  	for k, v := range snapshot {
   288  		_ = f(k, v)
   289  	}
   290  }
   291  
   292  // Values
   293  func (s *SyncMap[K, V]) Values() []V {
   294  	s.lock.RLock()
   295  	defer s.lock.RUnlock()
   296  
   297  	ret := make([]V, 0, len(s.m))
   298  	for _, v := range s.m {
   299  		ret = append(ret, v)
   300  	}
   301  	return ret
   302  }
   303  
   304  // Delete
   305  func (s *SyncMap[K, V]) Delete(key K) {
   306  	s.lock.Lock()
   307  	defer s.lock.Unlock()
   308  
   309  	delete(s.m, key)
   310  }
   311  
   312  // LoadOrStore
   313  func (s *SyncMap[K, V]) LoadOrStore(key K, val V) (V, bool) {
   314  	return s.ComputeIfAbsent(key, func(_ K) V {
   315  		return val
   316  	})
   317  }
   318  
   319  // Len
   320  func (s *SyncMap[K, V]) Len() int {
   321  	s.lock.RLock()
   322  	defer s.lock.RUnlock()
   323  
   324  	return len(s.m)
   325  }
   326  
   327  // NewMap
   328  func NewMap[K comparable, V any]() *Map[K, V] {
   329  	return &Map[K, V]{
   330  		m: map[K]V{},
   331  	}
   332  }
   333  
   334  // Map
   335  type Map[K comparable, V any] struct {
   336  	m map[K]V
   337  }
   338  
   339  // Load
   340  func (s *Map[K, V]) Load(key K) (V, bool) {
   341  	v, ok := s.m[key]
   342  	return v, ok
   343  }
   344  
   345  // Store
   346  func (s *Map[K, V]) Store(key K, val V) {
   347  	s.m[key] = val
   348  }
   349  
   350  // Range
   351  func (s *Map[K, V]) Range(f func(key K, val V)) {
   352  	for k, v := range s.m {
   353  		f(k, v)
   354  	}
   355  }
   356  
   357  // Delete
   358  func (s *Map[K, V]) Delete(key K) {
   359  	delete(s.m, key)
   360  }
   361  
   362  // Len
   363  func (s *Map[K, V]) Len() int {
   364  	return len(s.m)
   365  }