9
9
10
10
import io .deephaven .base .MathUtil ;
11
11
import io .deephaven .base .verify .Assert ;
12
+ import org .jetbrains .annotations .TestOnly ;
12
13
13
14
import java .io .Serializable ;
14
15
import java .util .NoSuchElementException ;
19
20
* {@code long} values. Head and tail will not wrap around; instead we use storage arrays sized to 2^N to allow fast
20
21
* determination of storage indices through a mask operation.
21
22
*/
22
- public class ByteRingBuffer implements Serializable {
23
+ public class ByteRingBuffer implements RingBuffer , Serializable {
23
24
static final long FIXUP_THRESHOLD = 1L << 62 ;
24
25
final boolean growable ;
25
26
byte [] storage ;
@@ -32,7 +33,7 @@ public class ByteRingBuffer implements Serializable {
32
33
*
33
34
* @param capacity minimum capacity of the ring buffer
34
35
*/
35
- public ByteRingBuffer (int capacity ) {
36
+ public ByteRingBuffer (final int capacity ) {
36
37
this (capacity , true );
37
38
}
38
39
@@ -42,7 +43,7 @@ public ByteRingBuffer(int capacity) {
42
43
* @param capacity minimum capacity of ring buffer
43
44
* @param growable whether to allow growth when the buffer is full.
44
45
*/
45
- public ByteRingBuffer (int capacity , boolean growable ) {
46
+ public ByteRingBuffer (final int capacity , final boolean growable ) {
46
47
Assert .leq (capacity , "ByteRingBuffer capacity" , MathUtil .MAX_POWER_OF_2 );
47
48
48
49
this .growable = growable ;
@@ -59,7 +60,7 @@ public ByteRingBuffer(int capacity, boolean growable) {
59
60
*
60
61
* @param increase Increase amount. The ring buffer's capacity will be increased by at least this amount.
61
62
*/
62
- protected void grow (int increase ) {
63
+ protected void grow (final int increase ) {
63
64
final int size = size ();
64
65
final long newCapacity = (long ) storage .length + increase ;
65
66
// assert that we are not asking for the impossible
@@ -83,7 +84,7 @@ protected void grow(int increase) {
83
84
*
84
85
* @param dest The destination buffer.
85
86
*/
86
- protected void copyRingBufferToArray (byte [] dest ) {
87
+ protected void copyRingBufferToArray (final byte [] dest ) {
87
88
final int size = size ();
88
89
final int storageHead = (int ) (head & mask );
89
90
@@ -99,27 +100,35 @@ protected void copyRingBufferToArray(byte[] dest) {
99
100
System .arraycopy (storage , 0 , dest , firstCopyLen , secondCopyLen );
100
101
}
101
102
103
+ @ Override
102
104
public boolean isFull () {
103
105
return size () == storage .length ;
104
106
}
105
107
108
+ @ Override
106
109
public boolean isEmpty () {
107
110
return tail == head ;
108
111
}
109
112
113
+ @ Override
110
114
public int size () {
111
115
return Math .toIntExact (tail - head );
112
116
}
113
117
118
+ @ Override
114
119
public int capacity () {
115
120
return storage .length ;
116
121
}
117
122
123
+ @ Override
118
124
public int remaining () {
119
125
return storage .length - size ();
120
126
}
121
127
128
+ @ Override
122
129
public void clear () {
130
+ // region object-bulk-clear
131
+ // endregion object-bulk-clear
123
132
tail = head = 0 ;
124
133
}
125
134
@@ -131,7 +140,7 @@ public void clear() {
131
140
* @throws UnsupportedOperationException when {@code growable} is {@code false} and buffer is full
132
141
* @return {@code true} if the byte was added successfully
133
142
*/
134
- public boolean add (byte e ) {
143
+ public boolean add (final byte e ) {
135
144
if (isFull ()) {
136
145
if (!growable ) {
137
146
throw new UnsupportedOperationException ("Ring buffer is full and growth is disabled" );
@@ -151,7 +160,8 @@ public boolean add(byte e) {
151
160
* @param count the minimum number of empty entries in the buffer after this call
152
161
* @throws UnsupportedOperationException when {@code growable} is {@code false} and buffer is full
153
162
*/
154
- public void ensureRemaining (int count ) {
163
+ @ Override
164
+ public void ensureRemaining (final int count ) {
155
165
if (remaining () < count ) {
156
166
if (!growable ) {
157
167
throw new UnsupportedOperationException ("Ring buffer is full and growth is disabled" );
@@ -168,7 +178,7 @@ public void ensureRemaining(int count) {
168
178
*
169
179
* @param e the value to add to the buffer
170
180
*/
171
- public void addUnsafe (byte e ) {
181
+ public void addUnsafe (final byte e ) {
172
182
// This is an extremely paranoid wrap check that in all likelihood will never run. With FIXUP_THRESHOLD at
173
183
// 1 << 62, and the user pushing 2^32 values per second(!), it will take 68 years to wrap this counter .
174
184
if (tail >= FIXUP_THRESHOLD ) {
@@ -188,7 +198,7 @@ public void addUnsafe(byte e) {
188
198
* @param notFullResult value to return is the buffer is not full
189
199
* @return the overwritten entry if the buffer is full, the provided value otherwise
190
200
*/
191
- public byte addOverwrite (byte e , byte notFullResult ) {
201
+ public byte addOverwrite (final byte e , final byte notFullResult ) {
192
202
byte val = notFullResult ;
193
203
if (isFull ()) {
194
204
val = remove ();
@@ -204,7 +214,7 @@ public byte addOverwrite(byte e, byte notFullResult) {
204
214
* @param e the byte to be added to the buffer
205
215
* @return true if the value was added successfully, false otherwise
206
216
*/
207
- public boolean offer (byte e ) {
217
+ public boolean offer (final byte e ) {
208
218
if (isFull ()) {
209
219
return false ;
210
220
}
@@ -218,7 +228,7 @@ public boolean offer(byte e) {
218
228
* @param count The number of elements to remove.
219
229
* @throws NoSuchElementException if the buffer is empty
220
230
*/
221
- public byte [] remove (int count ) {
231
+ public byte [] remove (final int count ) {
222
232
final int size = size ();
223
233
if (size < count ) {
224
234
throw new NoSuchElementException ();
@@ -264,7 +274,7 @@ public byte removeUnsafe() {
264
274
* @param onEmpty the value to return if the ring buffer is empty
265
275
* @return The removed element if the ring buffer was non-empty, otherwise the value of 'onEmpty'
266
276
*/
267
- public byte poll (byte onEmpty ) {
277
+ public byte poll (final byte onEmpty ) {
268
278
if (isEmpty ()) {
269
279
return onEmpty ;
270
280
}
@@ -291,7 +301,7 @@ public byte element() {
291
301
* @param onEmpty the value to return if the ring buffer is empty
292
302
* @return The head element if the ring buffer is non-empty, otherwise the value of 'onEmpty'
293
303
*/
294
- public byte peek (byte onEmpty ) {
304
+ public byte peek (final byte onEmpty ) {
295
305
if (isEmpty ()) {
296
306
return onEmpty ;
297
307
}
@@ -314,7 +324,7 @@ public byte front() {
314
324
* @throws NoSuchElementException if the buffer is empty
315
325
* @return The element at the specified offset
316
326
*/
317
- public byte front (int offset ) {
327
+ public byte front (final int offset ) {
318
328
if (offset < 0 || offset >= size ()) {
319
329
throw new NoSuchElementException ();
320
330
}
@@ -341,7 +351,7 @@ public byte back() {
341
351
* @param onEmpty the value to return if the ring buffer is empty
342
352
* @return The tail element if the ring buffer is non-empty, otherwise the value of 'onEmpty'
343
353
*/
344
- public byte peekBack (byte onEmpty ) {
354
+ public byte peekBack (final byte onEmpty ) {
345
355
if (isEmpty ()) {
346
356
return onEmpty ;
347
357
}
@@ -385,4 +395,14 @@ public void remove() {
385
395
throw new UnsupportedOperationException ();
386
396
}
387
397
}
398
+
399
+ /**
400
+ * Get the storage array for this ring buffer. This is intended for testing and debugging purposes only.
401
+ *
402
+ * @return The storage array for this ring buffer.
403
+ */
404
+ @ TestOnly
405
+ public byte [] getStorage () {
406
+ return storage ;
407
+ }
388
408
}
0 commit comments