@Before public void setup() { service = Execs.multiThreaded(2, "blocking-pool-test"); pool = new CloseableDefaultBlockingPool<>(Suppliers.ofInstance(1), 10); emptyPool = new CloseableDefaultBlockingPool<>(Suppliers.ofInstance(1), 0); }
@Test(timeout = 60_000L) public void testTakeTimeout() { final List<ReferenceCountingResourceHolder<Integer>> batchHolder = pool.takeBatch(10, 100L); final ReferenceCountingResourceHolder<Integer> holder = pool.take(100); assertNull(holder); batchHolder.forEach(ReferenceCountingResourceHolder::close); }
@Test(timeout = 60_000L) public void testConcurrentTakeBatch() throws ExecutionException, InterruptedException { final int batch1 = pool.maxSize() / 2; final Callable<List<ReferenceCountingResourceHolder<Integer>>> c1 = () -> pool.takeBatch(batch1, 10); final int batch2 = pool.maxSize() - batch1 + 1; final Callable<List<ReferenceCountingResourceHolder<Integer>>> c2 = () -> pool.takeBatch(batch2, 10); final Future<List<ReferenceCountingResourceHolder<Integer>>> f1 = service.submit(c1); final Future<List<ReferenceCountingResourceHolder<Integer>>> f2 = service.submit(c2); final List<ReferenceCountingResourceHolder<Integer>> r1 = f1.get(); final List<ReferenceCountingResourceHolder<Integer>> r2 = f2.get(); if (r1 != null) { assertTrue(r2.isEmpty()); assertEquals(pool.maxSize() - batch1, pool.getPoolSize()); assertEquals(batch1, r1.size()); r1.forEach(ReferenceCountingResourceHolder::close); } else { assertNotNull(r2); assertEquals(pool.maxSize() - batch2, pool.getPoolSize()); assertEquals(batch2, r2.size()); r2.forEach(ReferenceCountingResourceHolder::close); } assertEquals(pool.maxSize(), pool.getPoolSize()); }
@Test(timeout = 60_000L) public void testTakeBatch() { final List<ReferenceCountingResourceHolder<Integer>> holder = pool.takeBatch(6, 100L); assertNotNull(holder); assertEquals(6, holder.size()); assertEquals(4, pool.getPoolSize()); holder.forEach(ReferenceCountingResourceHolder::close); assertEquals(10, pool.getPoolSize()); }
@Override public List<ReferenceCountingResourceHolder<ByteBuffer>> takeBatch(final int maxElements, final long timeout) { final List<ReferenceCountingResourceHolder<ByteBuffer>> holder = super.takeBatch(maxElements, timeout); final int poolSize = getPoolSize(); if (minRemainBufferNum > poolSize) { minRemainBufferNum = poolSize; } return holder; }
@Override public List<ReferenceCountingResourceHolder<Integer>> call() { List<ReferenceCountingResourceHolder<Integer>> result = new ArrayList<>(); for (int i = 0; i < limit1; i++) { result.add(pool.take(10)); } return result; } }
@Test(timeout = 60_000L) public void testTake() { final ReferenceCountingResourceHolder<Integer> holder = pool.take(100); assertNotNull(holder); assertEquals(9, pool.getPoolSize()); holder.close(); assertEquals(10, pool.getPoolSize()); }
@Test(timeout = 60_000L) public void testConcurrentTake() throws ExecutionException, InterruptedException final int limit1 = pool.maxSize() / 2; final int limit2 = pool.maxSize() - limit1 + 1; final List<ReferenceCountingResourceHolder<Integer>> r2 = f2.get(); assertEquals(0, pool.getPoolSize()); assertTrue(r1.contains(null) || r2.contains(null)); assertEquals(pool.maxSize(), nonNullCount); future2.get(); assertEquals(pool.maxSize(), pool.getPoolSize());
@Test(timeout = 60_000L) public void testConcurrentTakeBatchClose() throws ExecutionException, InterruptedException final List<ReferenceCountingResourceHolder<Integer>> r1 = pool.takeBatch(1, 10); final Callable<List<ReferenceCountingResourceHolder<Integer>>> c2 = () -> pool.takeBatch(10, 100); assertNotNull(r2); assertEquals(10, r2.size()); assertEquals(0, pool.getPoolSize()); assertEquals(pool.maxSize(), pool.getPoolSize());
@Test(timeout = 60_000L) public void testWaitAndTakeBatch() throws InterruptedException, ExecutionException { List<ReferenceCountingResourceHolder<Integer>> batchHolder = pool.takeBatch(10, 10); assertNotNull(batchHolder); assertEquals(10, batchHolder.size()); assertEquals(0, pool.getPoolSize()); final Future<List<ReferenceCountingResourceHolder<Integer>>> future = service.submit( () -> pool.takeBatch(8, 100) ); Thread.sleep(20); batchHolder.forEach(ReferenceCountingResourceHolder::close); batchHolder = future.get(); assertNotNull(batchHolder); assertEquals(8, batchHolder.size()); assertEquals(2, pool.getPoolSize()); batchHolder.forEach(ReferenceCountingResourceHolder::close); assertEquals(10, pool.getPoolSize()); }
@Test(timeout = 60_000L) public void testTakeBatchTooManyObjects() { final List<ReferenceCountingResourceHolder<Integer>> holder = pool.takeBatch(100, 100L); assertTrue(holder.isEmpty()); }
@Override public List<ReferenceCountingResourceHolder<Integer>> call() { List<ReferenceCountingResourceHolder<Integer>> result = new ArrayList<>(); for (int i = 0; i < limit2; i++) { result.add(pool.take(10)); } return result; } }
@Test(timeout = 60_000L) public void testConcurrentBatchClose() throws ExecutionException, InterruptedException final int batch1 = pool.maxSize() / 2; final Callable<List<ReferenceCountingResourceHolder<Integer>>> c1 = () -> pool.takeBatch(batch1, 10); final int batch2 = pool.maxSize() - batch1; final Callable<List<ReferenceCountingResourceHolder<Integer>>> c2 = () -> pool.takeBatch(batch2, 10); assertEquals(batch1, r1.size()); assertEquals(batch2, r2.size()); assertEquals(0, pool.getPoolSize()); future2.get(); assertEquals(pool.maxSize(), pool.getPoolSize());
@Test public void testDrainFromEmptyPool() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Pool was initialized with limit = 0, there are no objects to take."); emptyPool.takeBatch(1, 0); }
@Override public ReferenceCountingResourceHolder<ByteBuffer> take(final long timeout) { final ReferenceCountingResourceHolder<ByteBuffer> holder = super.take(timeout); final int poolSize = getPoolSize(); if (minRemainBufferNum > poolSize) { minRemainBufferNum = poolSize; } return holder; }
final CloseableDefaultBlockingPool<ByteBuffer> mergeBufferPool = new CloseableDefaultBlockingPool<>( new Supplier<ByteBuffer>()
@AfterClass public static void teardownClass() { bufferPool.close(); mergeBufferPool.close(); }
holder = mergeBufferPool.takeBatch(1, 10); GroupByQueryRunnerTestHelper.runQuery(factory, runner, query);
@Test public void testTakeFromEmptyPool() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Pool was initialized with limit = 0, there are no objects to take."); emptyPool.take(0); }