void clear() { buffer.clear(); }
void maintenance() { buffer.maintenance(); }
@Override public void freeId( long id ) { buffer.offer( id ); }
@Test public void shouldClearCurrentChunk() { // GIVEN Consumer<long[]> consumer = mock( Consumer.class ); DelayedBuffer<Long> buffer = new DelayedBuffer<>( singleton( 0L ), Predicates.alwaysTrue(), 10, consumer ); buffer.offer( 0 ); buffer.offer( 1 ); buffer.offer( 2 ); // WHEN buffer.clear(); buffer.maintenance(); // THEN verifyNoMoreInteractions( consumer ); }
Supplier<Long> chunkThreshold = txOpened::get; Predicate<Long> safeThreshold = value -> txClosed.get() >= value; DelayedBuffer<Long> buffer = new DelayedBuffer<>( chunkThreshold, safeThreshold, 100, consumer ); buffer.offer( 1 ); buffer.offer( 4 ); buffer.maintenance(); assertEquals( 0, consumer.chunksAccepted() ); buffer.offer( 5 ); buffer.offer( 7 ); buffer.maintenance(); assertEquals( 0, consumer.chunksAccepted() ); buffer.offer( 2 ); buffer.offer( 8 ); buffer.maintenance(); assertEquals( 0, consumer.chunksAccepted() ); buffer.offer( 6 ); buffer.offer( 9 ); buffer.offer( 3 ); buffer.offer( 11 );
/** * Offers a value to this buffer. This value will at a later point be part of a buffered chunk, * released by a call to {@link #maintenance()} when the safe threshold for the chunk, which is determined * when the chunk is full or otherwise queued. */ public synchronized void offer( long value ) { chunk[chunkCursor++] = value; if ( chunkCursor == chunkSize ) { flush(); } }
@Override public void close() { if ( buffer != null ) { buffer.close(); } super.close(); } }
@Test public void shouldClearPreviousChunks() { // GIVEN Consumer<long[]> consumer = mock( Consumer.class ); final AtomicBoolean safeThreshold = new AtomicBoolean( false ); DelayedBuffer<Long> buffer = new DelayedBuffer<>( singleton( 0L ), t -> safeThreshold.get(), 10, consumer ); // three chunks buffer.offer( 0 ); buffer.maintenance(); buffer.offer( 1 ); buffer.maintenance(); buffer.offer( 2 ); buffer.maintenance(); // WHEN safeThreshold.set( true ); buffer.clear(); buffer.maintenance(); // THEN verifyNoMoreInteractions( consumer ); }
/** * Closes this buffer, releasing all {@link #offer(long)} values into the {@link Consumer}. * * This class is typically not used in a scenario suitable for try-with-resource * and so having it implement AutoCloseable would be more annoying */ public synchronized void close() { flush(); while ( !chunks.isEmpty() ) { chunkConsumer.accept( chunks.poll().values ); } }
@Override public void close() { if ( buffer != null ) { buffer.close(); } super.close(); } }
@Override public void run() { while ( !end ) { buffer.maintenance(); LockSupport.parkNanos( nanoInterval ); } }
@Override public void freeId( long id ) { buffer.offer( id ); }
void clear() { buffer.clear(); }
void maintenance() { buffer.maintenance(); }
/** * Offers a value to this buffer. This value will at a later point be part of a buffered chunk, * released by a call to {@link #maintenance()} when the safe threshold for the chunk, which is determined * when the chunk is full or otherwise queued. */ public synchronized void offer( long value ) { chunk[chunkCursor++] = value; if ( chunkCursor == chunkSize ) { flush(); } }
/** * Closes this buffer, releasing all {@link #offer(long)} values into the {@link Consumer}. * * This class is typically not used in a scenario suitable for try-with-resource * and so having it implement AutoCloseable would be more annoying */ public synchronized void close() { flush(); while ( !chunks.isEmpty() ) { chunkConsumer.accept( chunks.poll().values ); } }