72 lines
1.3 KiB
Go
72 lines
1.3 KiB
Go
package channels
|
|
|
|
import "github.com/eapache/queue"
|
|
|
|
// InfiniteChannel implements the Channel interface with an infinite buffer between the input and the output.
|
|
type InfiniteChannel struct {
|
|
input, output chan interface{}
|
|
length chan int
|
|
buffer *queue.Queue
|
|
}
|
|
|
|
func NewInfiniteChannel() *InfiniteChannel {
|
|
ch := &InfiniteChannel{
|
|
input: make(chan interface{}),
|
|
output: make(chan interface{}),
|
|
length: make(chan int),
|
|
buffer: queue.New(),
|
|
}
|
|
go ch.infiniteBuffer()
|
|
return ch
|
|
}
|
|
|
|
func (ch *InfiniteChannel) In() chan<- interface{} {
|
|
return ch.input
|
|
}
|
|
|
|
func (ch *InfiniteChannel) Out() <-chan interface{} {
|
|
return ch.output
|
|
}
|
|
|
|
func (ch *InfiniteChannel) Len() int {
|
|
return <-ch.length
|
|
}
|
|
|
|
func (ch *InfiniteChannel) Cap() BufferCap {
|
|
return Infinity
|
|
}
|
|
|
|
func (ch *InfiniteChannel) Close() {
|
|
close(ch.input)
|
|
}
|
|
|
|
func (ch *InfiniteChannel) infiniteBuffer() {
|
|
var input, output chan interface{}
|
|
var next interface{}
|
|
input = ch.input
|
|
|
|
for input != nil || output != nil {
|
|
select {
|
|
case elem, open := <-input:
|
|
if open {
|
|
ch.buffer.Add(elem)
|
|
} else {
|
|
input = nil
|
|
}
|
|
case output <- next:
|
|
ch.buffer.Remove()
|
|
case ch.length <- ch.buffer.Length():
|
|
}
|
|
|
|
if ch.buffer.Length() > 0 {
|
|
output = ch.output
|
|
next = ch.buffer.Peek()
|
|
} else {
|
|
output = nil
|
|
next = nil
|
|
}
|
|
}
|
|
|
|
close(ch.output)
|
|
close(ch.length)
|
|
}
|