mirror of
https://github.com/charlienet/go-mixed.git
synced 2025-07-18 00:22:41 +08:00
73 lines
1.4 KiB
Go
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
|
|
}
|
|
}
|