github.com/bruceshao/lockfree@v1.1.3-0.20230816090528-e89824c0a6e9/buffer.go (about)

     1  //go:build !386
     2  
     3  /*
     4   * Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * SPDX-License-Identifier: Apache-2.0
     7   *
     8   */
     9  
    10  package lockfree
    11  
    12  import "sync/atomic"
    13  
    14  type e[T any] struct {
    15  	c   uint64
    16  	val T
    17  }
    18  
    19  // ringBuffer 具体对象的存放区域,通过数组(定长切片)实现环状数据结构
    20  // 其中e为具体对象,非指针,这样可以一次性进行内存申请
    21  type ringBuffer[T any] struct {
    22  	// 增加默认的对象以便于return,处理data race问题
    23  	tDefault T
    24  	buf      []e[T]
    25  	capMask  uint64
    26  }
    27  
    28  func newRingBuffer[T any](cap int) *ringBuffer[T] {
    29  	x := ringBuffer[T]{
    30  		capMask: uint64(cap) - 1,
    31  		buf:     make([]e[T], cap),
    32  	}
    33  	return &x
    34  }
    35  
    36  func (r *ringBuffer[T]) write(c uint64, v T) {
    37  	x := &r.buf[c&r.capMask]
    38  	x.val = v
    39  	atomic.StoreUint64(&x.c, c+1)
    40  }
    41  
    42  func (r *ringBuffer[T]) element(c uint64) e[T] {
    43  	return r.buf[c&r.capMask]
    44  }
    45  
    46  func (r *ringBuffer[T]) contains(c uint64) (T, *uint64, bool) {
    47  	x := &r.buf[c&r.capMask]
    48  	if atomic.LoadUint64(&x.c) == c+1 {
    49  		v := x.val
    50  		return v, &x.c, true
    51  	}
    52  	return r.tDefault, &x.c, false
    53  }
    54  
    55  func (r *ringBuffer[T]) cap() uint64 {
    56  	return r.capMask + 1
    57  }