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 }