@Test(dataProvider = "empty") public void poll_whenEmpty(MpscGrowableArrayQueue<Integer> buffer) { assertThat(buffer.poll(), is(nullValue())); }
/** Drains the write buffer. */ @GuardedBy("evictionLock") void drainWriteBuffer() { if (!buffersWrites()) { return; } for (int i = 0; i < WRITE_BUFFER_MAX; i++) { Runnable task = writeBuffer().poll(); if (task == null) { break; } task.run(); } }
@Test(dataProvider = "full") public void poll_toEmpty(MpscGrowableArrayQueue<Integer> buffer) { while (buffer.poll() != null) {} assertThat(buffer.size(), is(0)); }
@Test(dataProvider = "populated") public void poll_whenPopulated(MpscGrowableArrayQueue<Integer> buffer) { assertThat(buffer.poll(), is(not(nullValue()))); assertThat(buffer.size(), is(POPULATED_SIZE - 1)); }
@Override @SuppressWarnings("FutureReturnValueIgnored") public void clear() { evictionLock.lock(); try { long now = expirationTicker().read(); // Apply all pending writes Runnable task; while (buffersWrites() && (task = writeBuffer().poll()) != null) { task.run(); } // Discard all entries for (Node<K, V> node : data.values()) { removeNode(node, now); } // Discard all pending reads readBuffer.drainTo(e -> {}); } finally { evictionLock.unlock(); } }
@Test(dataProvider = "empty") public void oneProducer_oneConsumer(MpscGrowableArrayQueue<Integer> buffer) { AtomicInteger started = new AtomicInteger(); AtomicInteger finished = new AtomicInteger(); ConcurrentTestHarness.execute(() -> { started.incrementAndGet(); Awaits.await().untilAtomic(started, is(2)); for (int i = 0; i < PRODUCE; i++) { while (!buffer.offer(i)) {} } finished.incrementAndGet(); }); ConcurrentTestHarness.execute(() -> { started.incrementAndGet(); Awaits.await().untilAtomic(started, is(2)); for (int i = 0; i < PRODUCE; i++) { while (buffer.poll() == null) {} } finished.incrementAndGet(); }); Awaits.await().untilAtomic(finished, is(2)); assertThat(buffer.size(), is(0)); }
@Test(dataProvider = "empty") public void manyProducers_oneConsumer(MpscGrowableArrayQueue<Integer> buffer) { AtomicInteger started = new AtomicInteger(); AtomicInteger finished = new AtomicInteger(); ConcurrentTestHarness.execute(() -> { started.incrementAndGet(); Awaits.await().untilAtomic(started, is(NUM_PRODUCERS + 1)); for (int i = 0; i < (NUM_PRODUCERS * PRODUCE); i++) { while (buffer.poll() == null) {} } finished.incrementAndGet(); }); ConcurrentTestHarness.timeTasks(NUM_PRODUCERS, () -> { started.incrementAndGet(); Awaits.await().untilAtomic(started, is(NUM_PRODUCERS + 1)); for (int i = 0; i < PRODUCE; i++) { while (!buffer.offer(i)) {} } finished.incrementAndGet(); }); Awaits.await().untilAtomic(finished, is(NUM_PRODUCERS + 1)); assertThat(buffer.size(), is(0)); }
/** Drains the write buffer. */ @GuardedBy("evictionLock") void drainWriteBuffer() { if (!buffersWrites()) { return; } for (int i = 0; i < WRITE_BUFFER_MAX; i++) { Runnable task = writeBuffer().poll(); if (task == null) { break; } task.run(); } }
@Override @SuppressWarnings("FutureReturnValueIgnored") public void clear() { evictionLock.lock(); try { long now = expirationTicker().read(); // Apply all pending writes Runnable task; while (buffersWrites() && (task = writeBuffer().poll()) != null) { task.run(); } // Discard all entries for (Node<K, V> node : data.values()) { removeNode(node, now); } // Discard all pending reads readBuffer.drainTo(e -> {}); } finally { evictionLock.unlock(); } }