2121import rx .Subscription ;
2222import rx .exceptions .MissingBackpressureException ;
2323import rx .internal .operators .NotificationLite ;
24- import rx .internal .util .unsafe .SpmcArrayQueue ;
25- import rx .internal .util .unsafe .SpscArrayQueue ;
2624import rx .internal .util .unsafe .UnsafeAccess ;
2725
2826/**
@@ -33,15 +31,28 @@ public class RxRingBuffer implements Subscription {
3331
3432 public static RxRingBuffer getSpscInstance () {
3533 if (UnsafeAccess .isUnsafeAvailable ()) {
36- return new RxRingBuffer (SPSC_POOL , SIZE );
34+ // using SynchronizedQueue until issues are solved with SpscArrayQueue offer rejection
35+ // RxRingBufferSpmcTest.testConcurrency occasionally fails with a
36+ // BackpressureException when using SpscArrayQueue
37+ // return new RxRingBuffer(SPSC_POOL, SIZE); // this is the one we were trying to use
38+ // return new RxRingBuffer(new SpscArrayQueue<Object>(SIZE), SIZE);
39+ // the performance of this is sufficient (actually faster in some cases)
40+ return new RxRingBuffer (new SynchronizedQueue <Object >(SIZE ), SIZE );
3741 } else {
3842 return new RxRingBuffer ();
3943 }
4044 }
4145
4246 public static RxRingBuffer getSpmcInstance () {
4347 if (UnsafeAccess .isUnsafeAvailable ()) {
44- return new RxRingBuffer (SPMC_POOL , SIZE );
48+ // using SynchronizedQueue until issues are solved with SpmcArrayQueue offer rejection
49+ // RxRingBufferSpmcTest.testConcurrency occasionally fails with a
50+ // BackpressureException when using SpmcArrayQueue/MpmcArrayQueue
51+ // return new RxRingBuffer(SPMC_POOL, SIZE); // this is the one we were trying to use
52+ // return new RxRingBuffer(new SpmcArrayQueue<Object>(SIZE), SIZE);
53+ // return new RxRingBuffer(new MpmcArrayQueue<Object>(SIZE), SIZE);
54+ // the performance of this is sufficient (actually faster in some cases)
55+ return new RxRingBuffer (new SynchronizedQueue <Object >(SIZE ), SIZE );
4556 } else {
4657 return new RxRingBuffer ();
4758 }
@@ -75,7 +86,7 @@ public static RxRingBuffer getSpmcInstance() {
7586 * r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 23951121.098 1982380.330 ops/s
7687 * r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 1142.351 33.592 ops/s
7788 *
78- * With SynchronizedQueue (synchronized LinkedList)
89+ * With SynchronizedQueue (synchronized LinkedList ... no object pooling )
7990 *
8091 * r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 33231667.136 685757.510 ops/s
8192 * r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 74623.614 5493.766 ops/s
@@ -119,11 +130,11 @@ public static RxRingBuffer getSpmcInstance() {
119130 * With SpmcArrayQueue
120131 * - requires access to Unsafe
121132 *
122- * Benchmark Mode Samples Score Score error Units
123- * r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 1835494.523 63874.461 ops/s
124- * r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 45545.599 1882.146 ops/s
125- * r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 38126258.816 474874.236 ops/s
126- * r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 42507.743 240.530 ops/s
133+ * Benchmark Mode Samples Score Score error Units
134+ * r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1 thrpt 5 27630345.474 769219.142 ops/s
135+ * r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1000 thrpt 5 80052.046 4059.541 ops/s
136+ * r.i.RxRingBufferPerf.spmcRingBufferAddRemove1 thrpt 5 44449524.222 563068.793 ops/s
137+ * r.i.RxRingBufferPerf.spmcRingBufferAddRemove1000 thrpt 5 65231.253 1805.732 ops/s
127138 *
128139 * With SpmcArrayQueue and ObjectPool (object pool improves createUseAndDestroy1 by 10x)
129140 *
@@ -135,17 +146,7 @@ public static RxRingBuffer getSpmcInstance() {
135146 *
136147 * --------------
137148 *
138- * When UnsafeAccess.isUnsafeAvailable() == true we can use the Spmc/SpscArrayQueue implementations and get these numbers:
139- *
140- * Benchmark Mode Samples Score Score error Units
141- * r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1 thrpt 5 17813072.116 672207.872 ops/s
142- * r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1000 thrpt 5 46794.691 1146.195 ops/s
143- * r.i.RxRingBufferPerf.spmcRingBufferAddRemove1 thrpt 5 32117630.315 749011.552 ops/s
144- * r.i.RxRingBufferPerf.spmcRingBufferAddRemove1000 thrpt 5 47257.476 1081.623 ops/s
145- * r.i.RxRingBufferPerf.spscCreateUseAndDestroy1 thrpt 5 24729994.601 353101.940 ops/s
146- * r.i.RxRingBufferPerf.spscCreateUseAndDestroy1000 thrpt 5 73101.460 2406.377 ops/s
147- * r.i.RxRingBufferPerf.spscRingBufferAddRemove1 thrpt 5 83548821.062 752738.756 ops/s
148- * r.i.RxRingBufferPerf.spscRingBufferAddRemove1000 thrpt 5 70549.816 1377.227 ops/s
149+ * When UnsafeAccess.isUnsafeAvailable() == true we can use the Spmc/SpscArrayQueue implementations.
149150 *
150151 * } </pre>
151152 */
@@ -169,30 +170,13 @@ public static RxRingBuffer getSpmcInstance() {
169170
170171 public static final int SIZE = 1024 ;
171172
172- private static ObjectPool <Queue <Object >> SPSC_POOL = new ObjectPool <Queue <Object >>() {
173-
174- @ Override
175- protected SpscArrayQueue <Object > createObject () {
176- return new SpscArrayQueue <Object >(SIZE );
177- }
178-
179- };
180-
181- private static ObjectPool <Queue <Object >> SPMC_POOL = new ObjectPool <Queue <Object >>() {
182-
183- @ Override
184- protected SpmcArrayQueue <Object > createObject () {
185- return new SpmcArrayQueue <Object >(SIZE );
186- }
187-
188- };
189-
190173 private RxRingBuffer (Queue <Object > queue , int size ) {
191174 this .queue = queue ;
192175 this .pool = null ;
193176 this .size = size ;
194177 }
195178
179+ @ SuppressWarnings ("unused" )
196180 private RxRingBuffer (ObjectPool <Queue <Object >> pool , int size ) {
197181 this .pool = pool ;
198182 this .queue = pool .borrowObject ();
@@ -213,7 +197,7 @@ public void unsubscribe() {
213197 release ();
214198 }
215199
216- /* for unit tests */ RxRingBuffer () {
200+ /* package accessible for unit tests */ RxRingBuffer () {
217201 this (new SynchronizedQueue <Object >(SIZE ), SIZE );
218202 }
219203
@@ -260,7 +244,7 @@ public int count() {
260244 }
261245 return queue .size ();
262246 }
263-
247+
264248 public boolean isEmpty () {
265249 if (queue == null ) {
266250 return true ;
@@ -294,7 +278,7 @@ public Object poll() {
294278 }
295279 return o ;
296280 }
297-
281+
298282 public Object peek () {
299283 if (queue == null ) {
300284 // we are unsubscribed and have released the undelrying queue
0 commit comments