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

     1  // ringbuf 包实现了一个环形缓冲区,可以对ringbuf进行读写操作
     2  // New 返回一个指定缓冲区大小的环形缓冲区实例
     3  package ringbuf
     4  
     5  import (
     6  	"errors"
     7  	"fmt"
     8  	"github.com/sandwich-go/boost/internal/log"
     9  )
    10  
    11  // NotEnoughMem 内存不够
    12  var NotEnoughMem = errors.New("not enough memory")
    13  
    14  type Ringbuf struct {
    15  	buf         []byte
    16  	start, size int
    17  }
    18  
    19  // New 这个 ringBuf 不是线程安全的!!!
    20  func New(size int) *Ringbuf {
    21  	return &Ringbuf{make([]byte, size), 0, 0}
    22  }
    23  
    24  // Write 写入数据
    25  func (r *Ringbuf) Write(b []byte) error {
    26  	if cap(r.buf)-r.size < len(b) {
    27  		return NotEnoughMem
    28  	}
    29  	for len(b) > 0 {
    30  		start := (r.start + r.size) % len(r.buf)
    31  		n := copy(r.buf[start:], b)
    32  		b = b[n:]
    33  
    34  		r.size += n
    35  	}
    36  	return nil
    37  }
    38  
    39  // Read 读数据
    40  func (r *Ringbuf) Read(b []byte, length int) int {
    41  	read := 0
    42  	for length > 0 && r.size > 0 {
    43  		end := r.start + length
    44  		if end > len(r.buf) {
    45  			end = len(r.buf)
    46  		}
    47  		n := copy(b, r.buf[r.start:end])
    48  		read += n
    49  		length -= n
    50  		b = b[n:]
    51  
    52  		r.size -= n
    53  		r.start = (r.start + n) % len(r.buf)
    54  	}
    55  	return read
    56  }
    57  
    58  // PreUse 预申请缓存
    59  func (r *Ringbuf) PreUse(length int) []byte {
    60  	s := (r.start + r.size) % r.Capacity()
    61  	e := s + length
    62  	if e > r.Capacity() {
    63  		e = r.Capacity()
    64  	}
    65  	if s < r.start && e > r.start {
    66  		e = r.start
    67  	}
    68  	if s == e {
    69  		log.Warn(fmt.Sprintf("not enough, length: %d,s: %d,e: %d,start: %d,size: %d", length, s, e, r.start, r.size))
    70  	}
    71  	return r.buf[s:e]
    72  }
    73  
    74  // RealUse 标记实际使用
    75  func (r *Ringbuf) RealUse(length int) {
    76  	if length <= 0 {
    77  		return
    78  	}
    79  	r.size += length
    80  }
    81  
    82  // Size buf 大小
    83  func (r *Ringbuf) Size() int { return r.size }
    84  
    85  // Capacity buf 容量
    86  func (r *Ringbuf) Capacity() int { return cap(r.buf) }