jaulib v1.3.0
Jau Support Library (C++, Java, ..)
RingBuffer01Base.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 * Copyright (c) 2013 Gothel Software e.K.
5 * Copyright (c) 2013 JogAmp Community.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27package jau.test.util;
28
29
30import org.jau.util.Ringbuffer;
31import org.junit.Assert;
32import org.junit.Test;
33
34public abstract class RingBuffer01Base {
35 private static boolean DEBUG = false;
36
37 public abstract Ringbuffer<Integer> createEmpty(int initialCapacity);
38 public abstract Ringbuffer<Integer> createFull(Integer[] source);
39
40 public Integer[] createIntArray(final int capacity, final int startValue) {
41 final Integer[] array = new Integer[capacity];
42 for(int i=0; i<capacity; i++) {
43 array[i] = Integer.valueOf(startValue+i);
44 }
45 return array;
46 }
47
48 private void readTestImpl(final Ringbuffer<Integer> rb, final boolean clearRef, final int capacity, final int len, final int startValue) {
49 final int preSize = rb.size();
50 Assert.assertEquals("Wrong capacity "+rb, capacity, rb.capacity());
51 Assert.assertTrue("Too low capacity to read "+len+" elems: "+rb, capacity-len >= 0);
52 Assert.assertTrue("Too low size to read "+len+" elems: "+rb, preSize >= len);
53 Assert.assertTrue("Is empty "+rb, !rb.isEmpty());
54
55 for(int i=0; i<len; i++) {
56 final Integer vI = rb.get();
57 Assert.assertNotNull("Empty at read #"+(i+1)+": "+rb, vI);
58 Assert.assertEquals("Wrong value at read #"+(i+1)+": "+rb, startValue+i, vI.intValue());
59 }
60
61 Assert.assertEquals("Invalid size "+rb, preSize-len, rb.size());
62 Assert.assertTrue("Invalid free slots after reading "+len+": "+rb, rb.getFreeSlots()>= len);
63 Assert.assertTrue("Is full "+rb, !rb.isFull());
64 }
65
66 private void writeTestImpl(final Ringbuffer<Integer> rb, final int capacity, final int len, final int startValue) {
67 final int preSize = rb.size();
68
69 Assert.assertEquals("Wrong capacity "+rb, capacity, rb.capacity());
70 Assert.assertTrue("Too low capacity to write "+len+" elems: "+rb, capacity-len >= 0);
71 Assert.assertTrue("Too low size to write "+len+" elems: "+rb, preSize+len <= capacity);
72 Assert.assertTrue("Is full "+rb, !rb.isFull());
73
74 for(int i=0; i<len; i++) {
75 Assert.assertTrue("Buffer is full at put #"+i+": "+rb, rb.put( Integer.valueOf(startValue+i) ));
76 }
77
78 Assert.assertEquals("Invalid size "+rb, preSize+len, rb.size());
79 Assert.assertTrue("Is empty "+rb, !rb.isEmpty());
80 }
81
82 private void moveGetPutImpl(final Ringbuffer<Integer> rb, final int pos) {
83 Assert.assertTrue("RB is empty "+rb, !rb.isEmpty());
84 for(int i=0; i<pos; i++) {
85 Assert.assertEquals("MoveFull.get failed "+rb, i, rb.get().intValue());
86 Assert.assertTrue("MoveFull.put failed "+rb, rb.put(i));
87 }
88 }
89
90 private void movePutGetImpl(final Ringbuffer<Integer> rb, final int pos) {
91 Assert.assertTrue("RB is full "+rb, !rb.isFull());
92 for(int i=0; i<pos; i++) {
93 Assert.assertTrue("MoveEmpty.put failed "+rb, rb.put(600+i));
94 Assert.assertEquals("MoveEmpty.get failed "+rb, 600+i, rb.get().intValue());
95 }
96 }
97
98 @Test
99 public void test01_FullRead() {
100 final int capacity = 11;
101 final Integer[] source = createIntArray(capacity, 0);
102 final Ringbuffer<Integer> rb = createFull(source);
103 Assert.assertEquals("Not full size "+rb, capacity, rb.size());
104 Assert.assertTrue("Not full "+rb, rb.isFull());
105
106 readTestImpl(rb, true, capacity, capacity, 0);
107 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
108 }
109
110 @Test
111 public void test02_EmptyWrite() {
112 final int capacity = 11;
113 final Ringbuffer<Integer> rb = createEmpty(capacity);
114 Assert.assertEquals("Not zero size "+rb, 0, rb.size());
115 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
116
117 writeTestImpl(rb, capacity, capacity, 0);
118 Assert.assertEquals("Not full size "+rb, capacity, rb.size());
119 Assert.assertTrue("Not full "+rb, rb.isFull());
120
121 readTestImpl(rb, true, capacity, capacity, 0);
122 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
123 }
124
125 @Test
126 public void test03_FullReadReset() {
127 final int capacity = 11;
128 final Integer[] source = createIntArray(capacity, 0);
129 final Ringbuffer<Integer> rb = createFull(source);
130 Assert.assertTrue("Not full "+rb, rb.isFull());
131
132 rb.resetFull(source);
133 Assert.assertTrue("Not full "+rb, rb.isFull());
134
135 readTestImpl(rb, false, capacity, capacity, 0);
136 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
137
138 rb.resetFull(source);
139 Assert.assertTrue("Not full "+rb, rb.isFull());
140
141 readTestImpl(rb, false, capacity, capacity, 0);
142 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
143 }
144
145 @Test
147 final int capacity = 11;
148 final Ringbuffer<Integer> rb = createEmpty(capacity);
149 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
150
151 rb.clear();
152 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
153
154 writeTestImpl(rb, capacity, capacity, 0);
155 Assert.assertTrue("Not full "+rb, rb.isFull());
156
157 readTestImpl(rb, false, capacity, capacity, 0);
158 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
159
160 rb.clear();
161 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
162
163 writeTestImpl(rb, capacity, capacity, 0);
164 Assert.assertTrue("Not full "+rb, rb.isFull());
165
166 readTestImpl(rb, false, capacity, capacity, 0);
167 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
168 }
169
170 @Test
171 public void test05_ReadResetMid01() {
172 final int capacity = 11;
173 final Integer[] source = createIntArray(capacity, 0);
174 final Ringbuffer<Integer> rb = createFull(source);
175 Assert.assertTrue("Not full "+rb, rb.isFull());
176
177 rb.resetFull(source);
178 Assert.assertTrue("Not full "+rb, rb.isFull());
179
180 readTestImpl(rb, false, capacity, 5, 0);
181 Assert.assertTrue("Is empty "+rb, !rb.isEmpty());
182 Assert.assertTrue("Is Full "+rb, !rb.isFull());
183
184 if( DEBUG ) {
185 rb.dump(System.err, "ReadReset01["+5+"].pre0");
186 }
187 rb.resetFull(source);
188 Assert.assertTrue("Not full "+rb, rb.isFull());
189 if( DEBUG ) {
190 rb.dump(System.err, "ReadReset01["+5+"].post");
191 }
192
193 readTestImpl(rb, false, capacity, capacity, 0);
194 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
195 }
196
197 @Test
198 public void test06_ReadResetMid02() {
199 final int capacity = 11;
200 final Integer[] source = createIntArray(capacity, 0);
201 final Ringbuffer<Integer> rb = createFull(source);
202 Assert.assertTrue("Not full "+rb, rb.isFull());
203
204 rb.resetFull(source);
205 Assert.assertTrue("Not full "+rb, rb.isFull());
206
207 moveGetPutImpl(rb, 5);
208 // readTestImpl(rb, false, capacity, 5, 0);
209 // Assert.assertTrue("Is empty "+rb, !rb.isEmpty());
210 // Assert.assertTrue("Is Full "+rb, !rb.isFull());
211
212 if( DEBUG ) {
213 rb.dump(System.err, "ReadReset02["+5+"].pre0");
214 }
215 rb.resetFull(source);
216 Assert.assertTrue("Not full "+rb, rb.isFull());
217 if( DEBUG ) {
218 rb.dump(System.err, "ReadReset02["+5+"].post");
219 }
220
221 readTestImpl(rb, false, capacity, capacity, 0);
222 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
223 }
224
225 private void test_GrowEmptyImpl(final int initCapacity, final int pos) {
226 final int growAmount = 5;
227 final int grownCapacity = initCapacity+growAmount;
228 final Integer[] growArray = new Integer[growAmount];
229 for(int i=0; i<growAmount; i++) {
230 growArray[i] = Integer.valueOf(100+i);
231 }
232 final Ringbuffer<Integer> rb = createEmpty(initCapacity);
233
234 if( DEBUG ) {
235 rb.dump(System.err, "GrowEmpty["+pos+"].pre0");
236 }
237 movePutGetImpl(rb, pos);
238 if( DEBUG ) {
239 rb.dump(System.err, "GrowEmpty["+pos+"].pre1");
240 }
241 rb.growEmptyBuffer(growArray);
242 if( DEBUG ) {
243 rb.dump(System.err, "GrowEmpty["+pos+"].post");
244 }
245
246 Assert.assertEquals("Wrong capacity "+rb, grownCapacity, rb.capacity());
247 Assert.assertEquals("Not growAmount size "+rb, growAmount, rb.size());
248 Assert.assertTrue("Is full "+rb, !rb.isFull());
249 Assert.assertTrue("Is empty "+rb, !rb.isEmpty());
250
251 for(int i=0; i<growAmount; i++) {
252 final Integer vI = rb.get();
253 Assert.assertNotNull("Empty at read #"+(i+1)+": "+rb, vI);
254 Assert.assertEquals("Wrong value at read #"+(i+1)+": "+rb, 100+i, vI.intValue());
255 }
256
257 Assert.assertEquals("Not zero size "+rb, 0, rb.size());
258 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
259 Assert.assertTrue("Is full "+rb, !rb.isFull());
260 }
261 @Test
263 test_GrowEmptyImpl(11, 0);
264 }
265 @Test
267 test_GrowEmptyImpl(11, 0+2);
268 }
269 @Test
271 test_GrowEmptyImpl(11, 11-1);
272 }
273 @Test
275 test_GrowEmptyImpl(11, 11-1-2);
276 }
277
278 private void test_GrowFullImpl(final int initCapacity, final int pos, final boolean debug) {
279 final int growAmount = 5;
280 final int grownCapacity = initCapacity+growAmount;
281 final Integer[] source = createIntArray(initCapacity, 0);
282 final Ringbuffer<Integer> rb = createFull(source);
283
284 if( DEBUG || debug ) {
285 rb.dump(System.err, "GrowFull["+pos+"].pre0");
286 }
287 moveGetPutImpl(rb, pos);
288 if( DEBUG || debug ) {
289 rb.dump(System.err, "GrowFull["+pos+"].pre1");
290 }
291 rb.growFullBuffer(growAmount);
292 if( DEBUG || debug ) {
293 rb.dump(System.err, "GrowFull["+pos+"].post");
294 }
295
296 Assert.assertEquals("Wrong capacity "+rb, grownCapacity, rb.capacity());
297 Assert.assertEquals("Not orig size "+rb, initCapacity, rb.size());
298 Assert.assertTrue("Is full "+rb, !rb.isFull());
299 Assert.assertTrue("Is empty "+rb, !rb.isEmpty());
300
301 for(int i=0; i<growAmount; i++) {
302 Assert.assertTrue("Buffer is full at put #"+i+": "+rb, rb.put( Integer.valueOf(100+i) ));
303 }
304 Assert.assertEquals("Not new size "+rb, grownCapacity, rb.size());
305 Assert.assertTrue("Not full "+rb, rb.isFull());
306
307 for(int i=0; i<initCapacity; i++) {
308 final Integer vI = rb.get();
309 Assert.assertNotNull("Empty at read #"+(i+1)+": "+rb, vI);
310 Assert.assertEquals("Wrong value at read #"+(i+1)+": "+rb, (pos+i)%initCapacity, vI.intValue());
311 }
312 for(int i=0; i<growAmount; i++) {
313 final Integer vI = rb.get();
314 Assert.assertNotNull("Empty at read #"+(i+1)+": "+rb, vI);
315 Assert.assertEquals("Wrong value at read #"+(i+1)+": "+rb, 100+i, vI.intValue());
316 }
317
318 Assert.assertEquals("Not zero size "+rb, 0, rb.size());
319 Assert.assertTrue("Not empty "+rb, rb.isEmpty());
320 Assert.assertTrue("Is full "+rb, !rb.isFull());
321 }
322 @Test
324 test_GrowFullImpl(11, 0, false);
325 }
326 @Test
328 test_GrowFullImpl(11, 0+1, false);
329 }
330 @Test
332 test_GrowFullImpl(11, 0+2, false);
333 }
334 @Test
336 test_GrowFullImpl(11, 0+3, false);
337 }
338 @Test
339 public void test24_GrowFull05_End() {
340 test_GrowFullImpl(11, 11-1, false);
341 }
342 @Test
344 test_GrowFullImpl(11, 11-1-1, false);
345 }
346 @Test
348 test_GrowFullImpl(11, 11-1-2, false);
349 }
350 @Test
352 test_GrowFullImpl(11, 11-1-3, false);
353 }
354}
abstract Ringbuffer< Integer > createFull(Integer[] source)
abstract Ringbuffer< Integer > createEmpty(int initialCapacity)
Integer[] createIntArray(final int capacity, final int startValue)
Ring buffer interface, a.k.a circular buffer.
Definition: Ringbuffer.java:43
int size()
Returns the number of elements in this ring buffer.
int getFreeSlots()
Returns the number of free slots available to put.
void dump(PrintStream stream, String prefix)
Debug functionality - Dumps the contents of the internal array.
void resetFull(T[] copyFrom)
Resets the read and write position according to a full ring buffer and fill all slots w/ elements of ...
int capacity()
Returns the net capacity of this ring buffer.
boolean isEmpty()
Returns true if this ring buffer is empty, otherwise false.
boolean put(T e)
Enqueues the given element.
T get()
Dequeues the oldest enqueued element if available, otherwise null.
void clear()
Resets the read and write position according to an empty ring buffer and set all ring buffer slots to...
boolean isFull()
Returns true if this ring buffer is full, otherwise false.
void growFullBuffer(int amount)
Grows a full ring buffer, increasing it's capacity about the amount.