mirror of
https://github.com/emo2007/block-accounting.git
synced 2024-09-20 09:06:27 +00:00
74 lines
1.1 KiB
Go
74 lines
1.1 KiB
Go
|
package system
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"sync"
|
||
|
"sync/atomic"
|
||
|
)
|
||
|
|
||
|
type SystemQueue struct {
|
||
|
m sync.Mutex
|
||
|
_init_size int
|
||
|
buf []*any
|
||
|
_buf_p atomic.Int64
|
||
|
_read_p atomic.Int64
|
||
|
}
|
||
|
|
||
|
func NewSystemQueue(size int) *SystemQueue {
|
||
|
if size < 50 {
|
||
|
size = 50
|
||
|
}
|
||
|
|
||
|
return &SystemQueue{
|
||
|
_init_size: size,
|
||
|
buf: make([]*any, size),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *SystemQueue) Put(_ context.Context, job any) error {
|
||
|
s.m.Lock()
|
||
|
defer s.m.Unlock()
|
||
|
|
||
|
p := s._buf_p.Load()
|
||
|
|
||
|
// Resize buf if needed
|
||
|
if int64(len(s.buf)) == p {
|
||
|
s.resize()
|
||
|
}
|
||
|
|
||
|
s.buf[p] = &job
|
||
|
|
||
|
s._buf_p.Add(1)
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (s *SystemQueue) Pop(_ context.Context) (any, error) {
|
||
|
s.m.Lock()
|
||
|
defer s.m.Unlock()
|
||
|
|
||
|
p := s._buf_p.Load()
|
||
|
if int64(len(s.buf)) < p {
|
||
|
s.resize()
|
||
|
|
||
|
return nil, fmt.Errorf("system-queue: error _p index out of buffer range")
|
||
|
}
|
||
|
|
||
|
jobp := s.buf[p]
|
||
|
|
||
|
if jobp == nil {
|
||
|
return nil, fmt.Errorf("system-queue: error nil job")
|
||
|
}
|
||
|
|
||
|
job := *jobp
|
||
|
s._buf_p.Add(-1)
|
||
|
s.buf[p-1] = nil
|
||
|
|
||
|
return job, nil
|
||
|
}
|
||
|
|
||
|
func (s *SystemQueue) resize() {
|
||
|
s.buf = append(s.buf, make([]*any, s._init_size/2)...)
|
||
|
}
|