All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.servicetalk.concurrent.internal.BlockingIterables Maven / Gradle / Ivy

/*
 * Copyright © 2018 Apple Inc. and the ServiceTalk project authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.servicetalk.concurrent.internal;

import io.servicetalk.concurrent.BlockingIterable;
import io.servicetalk.concurrent.BlockingIterator;
import io.servicetalk.concurrent.CloseableIterable;
import io.servicetalk.concurrent.CloseableIterator;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.annotation.Nullable;

/**
 * Utility methods for {@link BlockingIterable}.
 */
public final class BlockingIterables {
    private BlockingIterables() {
        // no instances
    }

    /**
     * Get a {@link BlockingIterable} that generates {@link BlockingIterator}s where
     * {@link BlockingIterator#hasNext()} returns {@code true}.
     * @param  The type of items for the {@link BlockingIterable}.
     * @return a {@link BlockingIterable} that generates {@link BlockingIterator}s where
     * {@link BlockingIterator#hasNext()} returns {@code true}.
     */
    @SuppressWarnings("unchecked")
    public static  BlockingIterable emptyBlockingIterable() {
        return (BlockingIterable) EmptyBlockingIterable.INSTANCE;
    }

    /**
     * Create a new {@link BlockingIterable} generates {@link BlockingIterator}s that only return a single {@code item}.
     * @param item The item returned by {@link BlockingIterator}s.
     * @param  The type of items for the {@link BlockingIterable}.
     * @return a new {@link BlockingIterable} generates {@link BlockingIterator}s that only return a single
     * {@code item}.
     */
    public static  BlockingIterable singletonBlockingIterable(T item) {
        return new SingletonBlockingIterable<>(item);
    }

    /**
     * Convert from a {@link Iterable} to a {@link BlockingIterable}.
     * @param iterable The {@link Iterable} to convert.
     * @param  The type of data.
     * @return The {@link BlockingIterable}.
     */
    public static  BlockingIterable from(Iterable iterable) {
        if (iterable instanceof BlockingIterable) {
            return (BlockingIterable) iterable;
        }
        return () -> new BlockingIterator() {
            private final Iterator itr = iterable.iterator();
            @Override
            public boolean hasNext(final long timeout, final TimeUnit unit) throws TimeoutException {
                // TODO(scott): apply timeout in another thread?
                return hasNext();
            }

            @Nullable
            @Override
            public T next(final long timeout, final TimeUnit unit) throws TimeoutException {
                // TODO(scott): apply timeout in another thread?
                return itr.next();
            }

            @Nullable
            @Override
            public T next() {
                return itr.next();
            }

            @Override
            public void close() {
            }

            @Override
            public boolean hasNext() {
                return itr.hasNext();
            }
        };
    }

    /**
     * Convert from a {@link Iterable} to a {@link CloseableIterable}.
     * @param iterable The {@link Iterable} to convert.
     * @param  The type of data.
     * @return The {@link CloseableIterable}.
     */
    public static  BlockingIterable from(CloseableIterable iterable) {
        if (iterable instanceof BlockingIterable) {
            return (BlockingIterable) iterable;
        }
        return () -> new BlockingIterator() {
            private final CloseableIterator itr = iterable.iterator();
            @Override
            public boolean hasNext(final long timeout, final TimeUnit unit) throws TimeoutException {
                // TODO(scott): apply timeout in another thread?
                return hasNext();
            }

            @Nullable
            @Override
            public T next(final long timeout, final TimeUnit unit) throws TimeoutException {
                // TODO(scott): apply timeout in another thread?
                return itr.next();
            }

            @Nullable
            @Override
            public T next() {
                return itr.next();
            }

            @Override
            public void close() throws Exception {
                itr.close();
            }

            @Override
            public boolean hasNext() {
                return itr.hasNext();
            }
        };
    }

    /**
     * A {@link BlockingIterable} which returns {@link BlockingIterator}s that are empty.
     * @param  The type of data.
     */
    private static final class EmptyBlockingIterable implements BlockingIterable {
        static final BlockingIterable INSTANCE = new EmptyBlockingIterable<>();

        private EmptyBlockingIterable() {
            // singleton
        }

        @Override
        public BlockingIterator iterator() {
            return EmptyBlockingIterator.instance();
        }

        private static final class EmptyBlockingIterator implements BlockingIterator {
            private static final BlockingIterator INSTANCE = new EmptyBlockingIterator<>();

            private EmptyBlockingIterator() {
                // singleton
            }

            @SuppressWarnings("unchecked")
            public static  BlockingIterator instance() {
                return (BlockingIterator) INSTANCE;
            }

            @Override
            public boolean hasNext(final long timeout, final TimeUnit unit) {
                return false;
            }

            @Nullable
            @Override
            public T next(final long timeout, final TimeUnit unit) {
                throw new NoSuchElementException();
            }

            @Override
            public void close() {
            }

            @Override
            public boolean hasNext() {
                return false;
            }

            @Override
            public T next() {
                throw new NoSuchElementException();
            }
        }
    }

    private static final class SingletonBlockingIterable implements BlockingIterable {
        @Nullable
        private final T item;

        SingletonBlockingIterable(T item) {
            this.item = item;
        }

        @Override
        public BlockingIterator iterator() {
            return new SingletonBlockingIterator<>(item);
        }

        private static final class SingletonBlockingIterator implements BlockingIterator {
            @Nullable
            private final T item;
            private boolean hasNext = true;

            SingletonBlockingIterator(@Nullable T item) {
                this.item = item;
            }

            @Override
            public boolean hasNext() {
                return hasNext;
            }

            @Override
            public T next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                hasNext = false;
                return item;
            }

            @Override
            public boolean hasNext(final long timeout, final TimeUnit unit) {
                return hasNext;
            }

            @Nullable
            @Override
            public T next(final long timeout, final TimeUnit unit) {
                return next();
            }

            @Override
            public void close() {
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy