File tree Expand file tree Collapse file tree 2 files changed +39
-2
lines changed
Expand file tree Collapse file tree 2 files changed +39
-2
lines changed Original file line number Diff line number Diff 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.
7474func (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
7890L:
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 ]
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
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
Original file line number Diff line number Diff 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+
131152func TestRingGetEmpty (t * testing.T ) {
132153 rb := NewRingBuffer (3 )
133154
You can’t perform that action at this time.
0 commit comments