1
0
Fork 0
burlesque/counter.go

71 lines
1.2 KiB
Go
Raw Normal View History

2014-07-10 12:19:39 +00:00
package main
2014-07-12 10:38:35 +00:00
import (
"sync"
)
2014-07-10 12:19:39 +00:00
const (
MaxIndex = ^uint(0)
)
type (
2014-07-15 19:41:38 +00:00
// Counter is responsible for operating queue read and write indexes
2014-07-10 12:19:39 +00:00
Counter struct {
2014-07-15 19:41:38 +00:00
WriteIndex uint // Number of the record last written to the queue
ReadIndex uint // Number of the record last read from the queue
// If WriteIndex is greater than ReadIndex then there are unread messages
// If WriteIndex is less tham ReadIndex then MaxIndex was reached
mutex sync.Mutex
stream chan uint
streaming bool
2014-07-10 12:19:39 +00:00
}
)
2014-07-12 10:38:35 +00:00
func NewCounter(wi, ri uint) Counter {
c := Counter{
WriteIndex: wi,
ReadIndex: ri,
stream: make(chan uint),
streaming: false,
}
if c.Distance() > 0 {
go c.Stream()
}
2014-07-10 12:19:39 +00:00
return c
}
2014-07-12 10:38:35 +00:00
func (c *Counter) Write(proc func(i uint) bool) {
c.mutex.Lock()
defer c.mutex.Unlock()
ok := proc(c.WriteIndex + 1)
if ok {
c.WriteIndex++
if !c.streaming {
go c.Stream()
}
2014-07-10 12:19:39 +00:00
}
}
2014-07-12 10:38:35 +00:00
func (c *Counter) Read() uint {
2014-07-10 12:19:39 +00:00
return <-c.stream
}
func (c *Counter) Distance() uint {
2014-07-12 10:38:35 +00:00
d := c.WriteIndex - c.ReadIndex
2014-07-10 12:19:39 +00:00
if d < 0 {
d += MaxIndex
}
return d
}
2014-07-12 10:38:35 +00:00
func (c *Counter) Stream() {
c.streaming = true
for c.WriteIndex > c.ReadIndex {
c.stream <- c.ReadIndex + 1
c.ReadIndex++
2014-07-10 12:19:39 +00:00
}
2014-07-12 10:38:35 +00:00
c.streaming = false
2014-07-10 12:19:39 +00:00
}