|
|
|
@ -197,3 +197,86 @@ func (star *StarStack) Write(bts []byte) (int, error) {
|
|
|
|
|
}
|
|
|
|
|
return sum, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type StarChanStack struct {
|
|
|
|
|
data chan interface{}
|
|
|
|
|
cap uint64
|
|
|
|
|
current uint64
|
|
|
|
|
isClose atomic.Value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewStarChanStack(cap uint64) *StarChanStack {
|
|
|
|
|
rtnBuffer := new(StarChanStack)
|
|
|
|
|
rtnBuffer.cap = cap
|
|
|
|
|
rtnBuffer.isClose.Store(false)
|
|
|
|
|
rtnBuffer.data = make(chan interface{}, cap)
|
|
|
|
|
return rtnBuffer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (star *StarChanStack) init() {
|
|
|
|
|
star.cap = 1024
|
|
|
|
|
star.data = make(chan interface{}, star.cap)
|
|
|
|
|
star.isClose.Store(false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (star *StarChanStack) Free() uint64 {
|
|
|
|
|
return star.cap - star.current
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (star *StarChanStack) Cap() uint64 {
|
|
|
|
|
return star.cap
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (star *StarChanStack) Len() uint64 {
|
|
|
|
|
return star.current
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (star *StarChanStack) Pop() (interface{}, error) {
|
|
|
|
|
if star.isClose.Load() == nil {
|
|
|
|
|
star.init()
|
|
|
|
|
}
|
|
|
|
|
if star.isClose.Load().(bool) {
|
|
|
|
|
return 0, io.EOF
|
|
|
|
|
}
|
|
|
|
|
data, ok := <-star.data
|
|
|
|
|
if !ok {
|
|
|
|
|
star.isClose.Store(true)
|
|
|
|
|
return 0, errors.New("channel read error")
|
|
|
|
|
}
|
|
|
|
|
for {
|
|
|
|
|
current := atomic.LoadUint64(&star.current)
|
|
|
|
|
if atomic.CompareAndSwapUint64(&star.current, current, current-1) {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return data, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (star *StarChanStack) Push(data interface{}) error {
|
|
|
|
|
defer func() {
|
|
|
|
|
recover()
|
|
|
|
|
}()
|
|
|
|
|
if star.isClose.Load() == nil {
|
|
|
|
|
star.init()
|
|
|
|
|
}
|
|
|
|
|
if star.isClose.Load().(bool) {
|
|
|
|
|
return io.EOF
|
|
|
|
|
}
|
|
|
|
|
star.data <- data
|
|
|
|
|
for {
|
|
|
|
|
current := atomic.LoadUint64(&star.current)
|
|
|
|
|
if atomic.CompareAndSwapUint64(&star.current, current, current+1) {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (star *StarChanStack) Close() error {
|
|
|
|
|
if star.isClose.Load() == nil {
|
|
|
|
|
star.init()
|
|
|
|
|
}
|
|
|
|
|
star.isClose.Store(true)
|
|
|
|
|
close(star.data)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|