diff --git a/gradle/changelog/iterable_queue.yaml b/gradle/changelog/iterable_queue.yaml new file mode 100644 index 0000000000..fa6112e358 --- /dev/null +++ b/gradle/changelog/iterable_queue.yaml @@ -0,0 +1,2 @@ +- type: removed + description: Unused class `IterableQueue` diff --git a/scm-core/src/main/java/sonia/scm/collect/CallableQueueCollector.java b/scm-core/src/main/java/sonia/scm/collect/CallableQueueCollector.java deleted file mode 100644 index 549752022a..0000000000 --- a/scm-core/src/main/java/sonia/scm/collect/CallableQueueCollector.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2020 - present Cloudogu GmbH - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more - * details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see https://www.gnu.org/licenses/. - */ - -package sonia.scm.collect; - - -import com.google.common.collect.Lists; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.concurrent.Callable; - -/** - * A {@link Callable} which consumes all items from a {@link QueueIterator} and - * returns a list with all items from the queue. - * - * - * @since 1.29 - * - * @param type of the queued items - */ -public class CallableQueueCollector implements Callable> -{ - - private static final Logger logger = - LoggerFactory.getLogger(CallableQueueCollector.class); - - - /** - * Constructs a new {@link CallableQueueCollector} from the given - * {@link IterableQueue}. - * - * @param queue queue to collect - */ - public CallableQueueCollector(IterableQueue queue) - { - this.queue = queue; - } - - - /** - * Creates a {@link List} from all items of the queue. - * - * - * @return {@link List} from all items of the queue - */ - @Override - public List call() - { - logger.trace("start collecting item from queue"); - - return Lists.newArrayList(queue); - } - - //~--- fields --------------------------------------------------------------- - - /** queue to collect items from */ - private IterableQueue queue; -} diff --git a/scm-core/src/main/java/sonia/scm/collect/IterableQueue.java b/scm-core/src/main/java/sonia/scm/collect/IterableQueue.java deleted file mode 100644 index 8d020c1342..0000000000 --- a/scm-core/src/main/java/sonia/scm/collect/IterableQueue.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2020 - present Cloudogu GmbH - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more - * details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see https://www.gnu.org/licenses/. - */ - -package sonia.scm.collect; - - -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Iterator; -import java.util.List; - -/** - * An iterable queue. The queue can have multiple parallel consumer - * {@link Iterator}s, which can iterate over all items of the queue until the - * end of the queue is reached. The end of the queue if reached, if a producer - * call the method {@link #endReached()} and the iterator has consumed all items - * of the backend list. Warning: The queue iterator blocks - * forever if the producer never call {@link #endReached()}. - * - * - * @since 1.29 - * @param type of the queued items - */ -public final class IterableQueue implements Iterable -{ - private boolean endReached = false; - - /** backend list of the queue */ - private List list; - - private static final Logger logger = - LoggerFactory.getLogger(IterableQueue.class); - - - /** - * Constructs a new {@link IterableQueue} with the default implementation - * of the backing list. - * - */ - public IterableQueue() - { - list = Lists.newArrayList(); - } - - /** - * Constructs a new {@link IterableQueue} with the given backing list. - * - * - * @param list backend list for the queue - */ - public IterableQueue(List list) - { - this.list = list; - } - - - /** - * Mark that the end of the queue is reached and notify all consuming - * iterators. - * - * @throws IllegalStateException if the end of the queue if already reached - */ - public synchronized void endReached() - { - if (endReached) - { - throw new IllegalStateException( - "the end of the queue is already reached"); - } - endReached = true; - notifyAll(); - } - - /** - * Returns a new consuming iterator for the queue. The methods - * {@link Iterator#hasNext()} and {@link Iterator#next()} of the - * {@link Iterator} will block until the next item is pushed to the queue, if - * the queue is empty and the end is not reached. The - * {@link Iterator#remove()} method of the {@link Iterator} is not implemented - * and will throw a {@link UnsupportedOperationException}. - * - * - * @return new consuming iterator - */ - @Override - public Iterator iterator() - { - Iterator iterator; - - if (endReached) - { - logger.trace("create list iterator"); - iterator = Iterators.unmodifiableIterator(list.iterator()); - } - else - { - logger.trace("create queue iterator"); - iterator = new QueueIterator<>(this); - } - - return iterator; - } - - /** - * Push a new item to the queue and notify all consuming iterators. - * - * @throws IllegalStateException if the end of the queue is already reached - * @param item item to push to the queue - */ - public synchronized void push(T item) - { - if (endReached) - { - throw new IllegalStateException( - "the end of the queue is already reached"); - } - - list.add(item); - notifyAll(); - } - - /** - * Returns the current size of the queue. - */ - int size() - { - return list.size(); - } - - - /** - * Returns the item at the specified index in this queue. - */ - T get(int index) - { - return list.get(index); - } - - /** - * Returns true if the end of the queue is reached. - */ - boolean isEndReached() - { - return endReached; - } - -} diff --git a/scm-core/src/main/java/sonia/scm/collect/QueueIterator.java b/scm-core/src/main/java/sonia/scm/collect/QueueIterator.java deleted file mode 100644 index 6316c3960b..0000000000 --- a/scm-core/src/main/java/sonia/scm/collect/QueueIterator.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2020 - present Cloudogu GmbH - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more - * details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see https://www.gnu.org/licenses/. - */ - -package sonia.scm.collect; - - -import com.google.common.collect.UnmodifiableIterator; - -import java.util.NoSuchElementException; -import java.util.concurrent.TimeUnit; - -/** - * Iterator for the {@link IterableQueue}. The {@link QueueIterator} should - * only be created from the {@link IterableQueue} by calling the - * {@link IterableQueue#iterator()}. - * - * - * @since 1.29 - * @param type of the queued items - */ -public final class QueueIterator extends UnmodifiableIterator -{ - private final IterableQueue queue; - - private int index = 0; - - /** - * Constructs a new {@link QueueIterator} for the given {@link IterableQueue}. - * - * - * @param queue backend queue - */ - QueueIterator(IterableQueue queue) - { - this.queue = queue; - } - - - /** - * Returns the next item in the queue. This method will block until the next - * item is pushed to the queue, if the queue is empty and the end is not - * reached. - * - * @throws NoSuchElementException if the iteration has no more elements - * - * @return the next item in the queue - */ - @Override - public T next() - { - if (!hasNext()) - { - throw new NoSuchElementException("no more items in the queue"); - } - - return queue.get(index++); - } - - - /** - * Returns {@code true} if the queue has more items. - * This method will block until the next item is pushed to the queue, if the - * queue is empty and the end is not reached. - */ - @Override - public boolean hasNext() - { - boolean result = false; - - if (index < queue.size()) - { - result = true; - } - else if (!queue.isEndReached()) - { - synchronized (queue) - { - try - { - queue.wait(TimeUnit.SECONDS.toMillis(10)); - result = index < queue.size(); - } - catch (InterruptedException ex) - { - throw new RuntimeException(ex); - } - } - } - - return result; - } - -} diff --git a/scm-core/src/test/java/sonia/scm/collect/IterableQueueTest.java b/scm-core/src/test/java/sonia/scm/collect/IterableQueueTest.java deleted file mode 100644 index 11bcfe61ff..0000000000 --- a/scm-core/src/test/java/sonia/scm/collect/IterableQueueTest.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2020 - present Cloudogu GmbH - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more - * details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see https://www.gnu.org/licenses/. - */ - -package sonia.scm.collect; - - -import com.google.common.collect.Lists; - -import org.junit.Test; - -import static org.junit.Assert.*; - -import java.util.List; -import java.util.Random; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - - -public class IterableQueueTest -{ - - @Test(expected = IllegalStateException.class) - public void testDuplicatedEndReached() - { - IterableQueue queue = new IterableQueue<>(); - - queue.endReached(); - queue.endReached(); - } - - @Test - public void testIterator() - { - IterableQueue queue = new IterableQueue<>(); - - assertEquals(QueueIterator.class, queue.iterator().getClass()); - queue.endReached(); - assertNotEquals(QueueIterator.class, queue.iterator().getClass()); - } - - @Test - public void testMultiThreaded() throws Exception - { - testMultiThreaded(5, 10, false, 1000); - } - - @Test - public void testMultiThreadedWithRandomSleep() throws Exception - { - testMultiThreaded(5, 10, true, 50); - } - - @Test(expected = IllegalStateException.class) - public void testPushEndReached() - { - IterableQueue queue = new IterableQueue<>(); - - queue.push("a"); - queue.endReached(); - queue.push("b"); - } - - @Test - public void testSingleConsumer() - { - final IterableQueue queue = new IterableQueue<>(); - - new Thread(new IntegerProducer(queue, false, 100)).start(); - assertResult(Lists.newArrayList(queue), 100); - } - - - private void assertResult(List result, int itemCount) - { - assertNotNull(result); - assertEquals(itemCount, result.size()); - - for (int c = 0; c < itemCount; c++) - { - assertEquals(Integer.valueOf(c), result.get(c)); - } - } - - private void testMultiThreaded(int threads, int consumer, - boolean randomSleep, int itemCount) - throws Exception - { - ExecutorService executor = Executors.newFixedThreadPool(threads); - List>> futures = Lists.newArrayList(); - - final IterableQueue queue = new IterableQueue<>(); - - for (int i = 0; i < consumer; i++) - { - Future> future = - executor.submit(new CallableQueueCollector<>(queue)); - - futures.add(future); - } - - new Thread(new IntegerProducer(queue, randomSleep, itemCount)).start(); - - for (Future> f : futures) - { - assertResult(f.get(), itemCount); - } - } - - private static class IntegerProducer implements Runnable - { - - public IntegerProducer(IterableQueue queue, boolean randomSleep, - int itemCount) - { - this.queue = queue; - this.randomSleep = randomSleep; - this.itemCount = itemCount; - } - - @Override - public void run() - { - Random r = new Random(); - - for (int c = 0; c < itemCount; c++) - { - if (randomSleep) - { - try - { - Thread.sleep(r.nextInt(5)); - } - catch (InterruptedException ex) - { - throw new RuntimeException("thread interrupted", ex); - } - } - - queue.push(c); - } - - queue.endReached(); - } - - IterableQueue queue; - - private int itemCount; - - private boolean randomSleep; - } -}