Implementation of a RingBuffer in Java with optional FIFO like semantics
github.com
github.com
In particular, using some pseudocode to simplify:
rb = new RingBuffer(... capacity=3, orderedReads=false/*the default*/)
rb.put_all(A, B, C, D)
rb.get() // D
rb.put(E)
rb.get_all(3) // E, C, D again
I haven't looked for bugs with orderedReads=true (besides the obvious memory leak), but given the footguns and unnecessarily complications this should be avoided regardless. final RingBuffer<String> ringBuffer = new RingBuffer<>(String.class, capacity);
Why does the constructor need the Class<?> parameter?Other than its indirect use in `copy` (which in Java normally takes the parameter itself), it's probably not actually necessary here since you could just use `Object[]`? But I don't spend enough time in Java (thankfully) so I'm not sure if there are intricacies involving the runtime overhead of casting.
this.entries = (T[]) Array.newInstance(type, capacity);
However, I think this alternative would work equally well, and would not require a `Class<T>` parameter: this.entries = (T[]) new Object[capacity];
There are some other choices in the library that I don't understand, such as the choice to have a static constructor with this signature: public static RingBuffer<Object> create(final int capacity) {
return create(capacity, false);
}
This returns the type `RingBuffer<Object>`, which isn't as useful as it could be; with appropriate idiomatic use of generics it could return a `RingBuffer<T>`: public static <T> RingBuffer<T> create(final int capacity, final boolean orderedReads) {
return new RingBuffer<>(capacity, orderedReads);
}
It's possible that this code was written by someone who is still learning idiomatic Java style, or effective use of generics.I'm also curious about the choice to have `get()` return `null`. I think I'd rather have seen this modeled with `Optional`. My preferred style when writing Java code is to employ non-nullable references wherever possible (though the return from `get()` is marked `@Nullable` at least).
[1] https://github.com/evolvedbinary/j8cu/blob/94d64cfc0ec49a340...
You can't just say new T[capacity] in java.
A RingBuffer is a data structure, because it defined by how it is represented in memory, and how its state should be manipulated to fulfil the deque operations.
Aren't there concurrent versions of this that block writers until space frees up?