1
0
mirror of https://github.com/charlienet/go-mixed.git synced 2025-07-18 00:22:41 +08:00
Files
go-mixed/idGenerator/buffer.go
2023-10-26 14:42:23 +08:00

73 lines
1.4 KiB
Go

package idgenerator
import (
"sync"
"time"
"github.com/charlienet/go-mixed/idGenerator/store"
)
type obtainFunc func() (*store.Segment, error)
type doubleBuffer struct {
current *store.Segment // 当前
backup *store.Segment // 备用
obtain obtainFunc // 数据段获取函数
inFill bool // 备用缓冲填充中
isReadly bool // 备用缓冲区填充完成
mu sync.Mutex
}
func newDoubleBuffer(obtainFunc obtainFunc) *doubleBuffer {
b := &doubleBuffer{obtain: obtainFunc}
b.current, _ = b.obtain()
return b
}
func (b *doubleBuffer) allot() (int64, bool) {
if !b.inFill && b.current.IsEnding() {
go b.full() // 填充备用缓冲
}
// 缓冲区耗尽时切换
if b.current.IsEmpty() {
// 检查备用缓冲是否已经填充完成,已完成时切换,否则等待
for !b.isReadly {
time.Sleep(time.Microsecond * 100)
}
b.switchBuf()
}
return b.current.Allot(), b.current.Reback()
}
func (b *doubleBuffer) full() {
b.mu.Lock()
defer b.mu.Unlock()
if !b.inFill {
var err error
b.inFill = true
b.backup, err = b.obtain()
if err != nil {
println("填充失败:", err.Error())
panic(err)
}
b.isReadly = true
}
}
func (b *doubleBuffer) switchBuf() {
b.mu.Lock()
defer b.mu.Unlock()
if b.isReadly {
b.current, b.backup = b.backup, b.current
b.inFill = false
b.isReadly = false
}
}