Skip to content

Commit 7fba6c8

Browse files
Merge pull request #94 from tylertreat-wf/rb_offer
Add Offer method to RingBuffer
2 parents 223470e + 7b36f79 commit 7fba6c8

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

queue/ring.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,25 @@ func (rb *RingBuffer) init(size uint64) {
7272
// call will block until an item is added to the queue or Dispose is called
7373
// on the queue. An error will be returned if the queue is disposed.
7474
func (rb *RingBuffer) Put(item interface{}) error {
75+
_, err := rb.put(item, false)
76+
return err
77+
}
78+
79+
// Offer adds the provided item to the queue if there is space. If the queue
80+
// is full, this call will return false. An error will be returned if the
81+
// queue is disposed.
82+
func (rb *RingBuffer) Offer(item interface{}) (bool, error) {
83+
return rb.put(item, true)
84+
}
85+
86+
func (rb *RingBuffer) put(item interface{}, offer bool) (bool, error) {
7587
var n *node
7688
pos := atomic.LoadUint64(&rb.queue)
7789
i := 0
7890
L:
7991
for {
8092
if atomic.LoadUint64(&rb.disposed) == 1 {
81-
return ErrDisposed
93+
return false, ErrDisposed
8294
}
8395

8496
n = rb.nodes[pos&rb.mask]
@@ -94,6 +106,10 @@ L:
94106
pos = atomic.LoadUint64(&rb.queue)
95107
}
96108

109+
if offer {
110+
return false, nil
111+
}
112+
97113
if i == 10000 {
98114
runtime.Gosched() // free up the cpu before the next iteration
99115
i = 0
@@ -104,7 +120,7 @@ L:
104120

105121
n.data = item
106122
atomic.StoreUint64(&n.position, pos+1)
107-
return nil
123+
return true, nil
108124
}
109125

110126
// Get will return the next item in the queue. This call will block

queue/ring_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,27 @@ func TestPutToFull(t *testing.T) {
128128
wg.Wait()
129129
}
130130

131+
func TestOffer(t *testing.T) {
132+
rb := NewRingBuffer(2)
133+
134+
ok, err := rb.Offer("foo")
135+
assert.True(t, ok)
136+
assert.Nil(t, err)
137+
ok, err = rb.Offer("bar")
138+
assert.True(t, ok)
139+
assert.Nil(t, err)
140+
ok, err = rb.Offer("baz")
141+
assert.False(t, ok)
142+
assert.Nil(t, err)
143+
144+
item, err := rb.Get()
145+
assert.Nil(t, err)
146+
assert.Equal(t, "foo", item)
147+
item, err = rb.Get()
148+
assert.Nil(t, err)
149+
assert.Equal(t, "bar", item)
150+
}
151+
131152
func TestRingGetEmpty(t *testing.T) {
132153
rb := NewRingBuffer(3)
133154

0 commit comments

Comments
 (0)