From 12d1abab9aa4f09bf9c0f7b5628c50155f2aaf4e Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Mon, 18 Sep 2023 10:28:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20buffer=20=E5=8C=85?= =?UTF-8?q?=EF=BC=8C=E5=86=85=E7=BD=AE=E4=BA=86=E4=B8=80=E4=B8=AA=E7=8E=AF?= =?UTF-8?q?=E5=BD=A2=E7=BC=93=E5=86=B2=E5=8C=BA=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/buffer/errors.go | 7 +++ utils/buffer/ring.go | 113 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 utils/buffer/errors.go create mode 100644 utils/buffer/ring.go diff --git a/utils/buffer/errors.go b/utils/buffer/errors.go new file mode 100644 index 0000000..0ea881e --- /dev/null +++ b/utils/buffer/errors.go @@ -0,0 +1,7 @@ +package buffer + +import "errors" + +var ( + ErrBufferIsEmpty = errors.New("buffer is empty") +) diff --git a/utils/buffer/ring.go b/utils/buffer/ring.go new file mode 100644 index 0000000..8c4b3df --- /dev/null +++ b/utils/buffer/ring.go @@ -0,0 +1,113 @@ +package buffer + +// NewRing 创建一个环形缓冲区 +func NewRing[T any](initSize int) *Ring[T] { + if initSize <= 1 { + panic("initial size must be great than one") + } + + return &Ring[T]{ + buf: make([]T, initSize), + initSize: initSize, + size: initSize, + } +} + +// Ring 环形缓冲区 +type Ring[T any] struct { + buf []T + initSize int + size int + r int + w int +} + +// Read 读取数据 +func (slf *Ring[T]) Read() (T, error) { + var t T + if slf.r == slf.w { + return t, ErrBufferIsEmpty + } + + v := slf.buf[slf.r] + slf.r++ + if slf.r == slf.size { + slf.r = 0 + } + + return v, nil +} + +// Peek 查看数据 +func (slf *Ring[T]) Peek() (t T, err error) { + if slf.r == slf.w { + return t, ErrBufferIsEmpty + } + + return slf.buf[slf.r], nil +} + +// Write 写入数据 +func (slf *Ring[T]) Write(v T) { + slf.buf[slf.w] = v + slf.w++ + + if slf.w == slf.size { + slf.w = 0 + } + + if slf.w == slf.r { + slf.grow() + } +} + +// grow 扩容 +func (slf *Ring[T]) grow() { + var size int + if slf.size < 1024 { + size = slf.size * 2 + } else { + size = slf.size + slf.size/4 + } + + buf := make([]T, size) + + copy(buf[0:], slf.buf[slf.r:]) + copy(buf[slf.size-slf.r:], slf.buf[0:slf.r]) + + slf.r = 0 + slf.w = slf.size + slf.size = size + slf.buf = buf +} + +// IsEmpty 是否为空 +func (slf *Ring[T]) IsEmpty() bool { + return slf.r == slf.w +} + +// Cap 返回缓冲区容量 +func (slf *Ring[T]) Cap() int { + return slf.size +} + +// Len 返回缓冲区长度 +func (slf *Ring[T]) Len() int { + if slf.r == slf.w { + return 0 + } + + if slf.w > slf.r { + return slf.w - slf.r + } + + return slf.size - slf.r + slf.w +} + +// Reset 重置缓冲区 +func (slf *Ring[T]) Reset() { + slf.r = 0 + slf.w = 0 + slf.size = slf.initSize + slf.buf = make([]T, slf.initSize) +}