@Test
  public void partitionedReferencePileCollectsAllObjects()
      throws InterruptedException, ExecutionException {
    int backlog = 32;

    PartitionedReferencePile<Slot> pile = new PartitionedReferencePile<Slot>(backlog, Slot::new);

    Future[] futures = new Future[threadCnt];
    for (int i = 0; i < threadCnt; i++) {
      int idx = i;
      futures[i] =
          pool.submit(
              () -> {
                for (int j = 0; j < backlog * 2; j++) {
                  Slot s = pile.get();
                  s.var0 = idx;
                  s.var1 = j;
                }
              });
    }
    for (Future f : futures) {
      f.get();
    }

    Collection<Slot> slots = pile.collect();

    assertThat(
        "All Slots allocated are available", slots, iterableWithSize(threadCnt * backlog * 2));
  }
  @Test
  public void testPartitionedReferencePileThroughput() throws InterruptedException {
    int backlog = 64 * 1024;
    long start = System.nanoTime();

    PartitionedReferencePile<Slot> pile = new PartitionedReferencePile<Slot>(backlog, Slot::new);
    CountDownLatch latch = new CountDownLatch(threadCnt);
    for (int i = 0; i < threadCnt; i++) {
      int idx = i;
      pool.submit(
          () -> {
            for (int j = 0; j < backlog; j++) {
              Slot s = pile.get();
              s.var0 = idx;
              s.var1 = j;
            }

            for (Slot s : pile) {
              int slotIdx = s.var0;
            }
            latch.countDown();
          });
    }
    latch.await(5, TimeUnit.SECONDS);

    long end = System.nanoTime();
    double elapsed = TimeUnit.MILLISECONDS.convert(end - start, TimeUnit.NANOSECONDS);
    System.out.println(
        String.format("throughput: %s ops/ms", (long) ((threadCnt * backlog) / elapsed)));
  }
  @Test
  public void partitionedReferencePileProvidesThreadLocal() throws InterruptedException {
    int backlog = 32;

    PartitionedReferencePile<Slot> pile = new PartitionedReferencePile<Slot>(backlog, Slot::new);
    CountDownLatch latch = new CountDownLatch(threadCnt);

    for (int i = 0; i < threadCnt; i++) {
      int idx = i;
      pool.submit(
          () -> {
            for (int j = 0; j < backlog * 2; j++) {
              Slot s = pile.get();
              s.var0 = idx;
              s.var1 = j;
            }

            int expected = 0;
            for (Slot s : pile) {
              assert s.var1 == expected++;
            }

            latch.countDown();
          });
    }

    assertThat("Latch was counted down", latch.await(5, TimeUnit.SECONDS));
  }