github.com/duomi520/utils@v0.0.0-20240430123446-e03a4cddd6ec/queue.go (about)

     1  package utils
     2  
     3  import (
     4  	"runtime"
     5  	"sync/atomic"
     6  )
     7  
     8  // CopyOnWriteList (COW)需要修改的时候拷贝一个副本出来,适用不频繁写的场景
     9  // 修改时新数据原子替换旧数据地址,旧数据由GC回收。
    10  type CopyOnWriteList struct {
    11  	//0-unlock 1-lock
    12  	mutex int64
    13  	slice atomic.Value
    14  }
    15  
    16  // NewCopyOnWriteList 新增
    17  func NewCopyOnWriteList() *CopyOnWriteList {
    18  	l := CopyOnWriteList{}
    19  	l.slice.Store([]any{})
    20  	return &l
    21  }
    22  
    23  // Add 增加
    24  func (l *CopyOnWriteList) Add(element any) {
    25  	for {
    26  		if atomic.CompareAndSwapInt64(&l.mutex, 0, 1) {
    27  			base := l.slice.Load().([]any)
    28  			data := append([]any{}, base...)
    29  			data = append(data, element)
    30  			l.slice.Store(data)
    31  			atomic.StoreInt64(&l.mutex, 0)
    32  			return
    33  		}
    34  		runtime.Gosched()
    35  	}
    36  }
    37  
    38  // Remove 移除
    39  func (l *CopyOnWriteList) Remove(judge func(any) bool) {
    40  	for {
    41  		if atomic.CompareAndSwapInt64(&l.mutex, 0, 1) {
    42  			base := l.slice.Load().([]any)
    43  			data := make([]any, 0, len(base))
    44  			for _, item := range base {
    45  				if !judge(item) {
    46  					data = append(data, item)
    47  				}
    48  			}
    49  			l.slice.Store(data)
    50  			atomic.StoreInt64(&l.mutex, 0)
    51  			return
    52  		}
    53  		runtime.Gosched()
    54  	}
    55  }
    56  
    57  // List 列
    58  func (l *CopyOnWriteList) List() []any {
    59  	return l.slice.Load().([]any)
    60  }
    61  
    62  // https://github.com/yireyun/go-queue
    63  // https://github.com/Workiva/go-datastructures
    64  // https://www.jianshu.com/p/231caf90f30b
    65  // https://zhuanlan.zhihu.com/p/512916201
    66  // https://blog.csdn.net/tjcwt2011/article/details/108293520