Class CircularConcurrentLinkedDeque<E>
- All Implemented Interfaces:
Serializable,Iterable<E>,Collection<E>,Deque<E>,Queue<E>
ConcurrentLinkedDeque that evicts the oldest element(s) once it reaches
maxSize, invoking an optional callback on each evicted element.
Why the explicit size counter: ConcurrentLinkedDeque.size() is
documented as an O(n) operation (it walks the whole list). The eviction check runs
on every add(E)/offer(E), so relying on super.size() made each insertion
O(n) once the deque was full — the hot path for MockServer's request/event log. Under a
sustained request load this manifested as CPU usage that climbed as the log filled and stayed
high (GitHub issue #2329). An AtomicInteger maintained by every mutating method makes
size() and the eviction check O(1).
The counter is kept consistent by every size-changing method on this class
(add(E), offer(E), addAll(java.util.Collection<? extends E>) (via add), remove(java.lang.Object),
removeItem(E), clear(), and the internal eviction). Callers must mutate the deque
only through these methods (MockServer's MockServerEventLog does); direct use of other
inherited bulk mutators is not supported by this subclass.
Optional byte budget: in addition to the element-count bound, an optional
maxBytes budget can be supplied together with a weigher (via the 4-arg
constructor). Each element's weight is measured by the weigher on insertion and accumulated into
totalBytes; whenever an insertion would push the running total over maxBytes the
oldest elements are evicted first until it fits (or the deque is empty). This caps the heap held
by the event log when individual entries are large (e.g. big LLM-capture bodies) rather than only
by entry count. A single element whose weight alone exceeds maxBytes is still retained —
the byte-eviction loop stops once the deque is empty so we never reject the incoming element. The
budget is disabled when maxBytes <= 0 or the weigher is null, in which case the
deque behaves exactly as the count-bounded version.
- Author:
- jamesdbloom
- See Also:
-
Constructor Summary
ConstructorsConstructorDescriptionCircularConcurrentLinkedDeque(int maxSize, long maxBytes, ToLongFunction<E> weigher, Consumer<E> onEvictCallback) CircularConcurrentLinkedDeque(int maxSize, Consumer<E> onEvictCallback) -
Method Summary
Modifier and TypeMethodDescriptionbooleanbooleanaddAll(Collection<? extends E> collection) voidclear()booleanisEmpty()booleanbooleanDeprecated.use removeItem insteadbooleanremoveItem(E e) voidsetMaxBytes(long maxBytes) voidsetMaxSize(int maxSize) intsize()O(1) size, backed by an internal counter (unlikeConcurrentLinkedDeque.size()which is O(n)).Methods inherited from class java.util.concurrent.ConcurrentLinkedDeque
addFirst, addLast, contains, descendingIterator, element, forEach, getFirst, getLast, iterator, offerFirst, offerLast, peek, peekFirst, peekLast, poll, pollFirst, pollLast, pop, push, remove, removeAll, removeFirst, removeFirstOccurrence, removeIf, removeLast, removeLastOccurrence, retainAll, spliterator, toArray, toArray, toStringMethods inherited from class java.util.AbstractCollection
containsAllMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface java.util.Collection
containsAll, equals, hashCode, parallelStream, stream, toArray
-
Constructor Details
-
CircularConcurrentLinkedDeque
-
CircularConcurrentLinkedDeque
public CircularConcurrentLinkedDeque(int maxSize, long maxBytes, ToLongFunction<E> weigher, Consumer<E> onEvictCallback)
-
-
Method Details
-
setMaxSize
public void setMaxSize(int maxSize) -
setMaxBytes
public void setMaxBytes(long maxBytes) -
size
public int size()O(1) size, backed by an internal counter (unlikeConcurrentLinkedDeque.size()which is O(n)).- Specified by:
sizein interfaceCollection<E>- Specified by:
sizein interfaceDeque<E>- Overrides:
sizein classConcurrentLinkedDeque<E>
-
isEmpty
public boolean isEmpty()- Specified by:
isEmptyin interfaceCollection<E>- Overrides:
isEmptyin classConcurrentLinkedDeque<E>
-
add
-
addAll
- Specified by:
addAllin interfaceCollection<E>- Specified by:
addAllin interfaceDeque<E>- Overrides:
addAllin classConcurrentLinkedDeque<E>
-
offer
-
clear
public void clear()- Specified by:
clearin interfaceCollection<E>- Overrides:
clearin classConcurrentLinkedDeque<E>
-
remove
Deprecated.use removeItem instead- Specified by:
removein interfaceCollection<E>- Specified by:
removein interfaceDeque<E>- Overrides:
removein classConcurrentLinkedDeque<E>
-
removeItem
-