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

org.deeplearning4j.berkeley.Iterators Maven / Gradle / Ivy

There is a newer version: 1.0.0-M2.1
Show newest version
/*-
 *
 *  * Copyright 2015 Skymind,Inc.
 *  *
 *  *    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 org.deeplearning4j.berkeley;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;


public class Iterators {

    public static  void fillList(Iterator it, List lst) {
        while (it.hasNext()) {
            lst.add(it.next());
        }
    }

    public static  List fillList(Iterator it) {
        List lst = new ArrayList<>();
        fillList(it, lst);
        return lst;
    }

    /**
     * WraTps a base iterator with a transformation function.
     */
    public static abstract class Transform implements Iterator {

        private Iterator base;

        public Transform(Iterator base) {
            this.base = base;
        }

        public boolean hasNext() {
            return base.hasNext();
        }

        public T next() {
            return transform(base.next());
        }

        protected abstract T transform(S next);

        public void remove() {
            base.remove();
        }

    }

    private Iterators() {}

    /**
     * Wraps an iterator as an iterable
     * 
     * @param 
     * @param it
     * @return
     */
    public static  Iterable newIterable(final Iterator it) {
        return new Iterable() {
            public Iterator iterator() {
                return it;
            }
        };
    }

    /**
     * Wraps an iterator as an iterable
     * 
     * @param 
     * @param it
     * @return
     */
    public static  Iterable able(final Iterator it) {
        return new Iterable() {
            boolean used = false;

            public Iterator iterator() {
                if (used)
                    throw new RuntimeException("One use iterable");
                used = true;
                return it;
            }
        };
    }

    /**
     * Executes calls to next() in a different thread
     * 
     * @param 
     * @param base
     * @param numThreads
     * @return
     */
    public static  Iterator thread(final Iterator base) {
        return new Iterator() {
            ArrayBlockingQueue els = new ArrayBlockingQueue<>(2);
            private boolean finishedLoading = false;
            private boolean running = false;

            Thread thread = new Thread(new Runnable() {
                public void run() {
                    while (base.hasNext()) {
                        try {
                            els.put(base.next());
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    finishedLoading = true;
                }
            });

            public boolean hasNext() {
                return !(finishedLoading && els.isEmpty());
            }

            public T next() {
                if (!running)
                    thread.start();
                running = true;
                try {
                    return els.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    public static  Iterator> zip(final Iterator s, final Iterator t) {
        return new Iterator>() {
            public boolean hasNext() {
                return s.hasNext() && t.hasNext();
            }

            public Pair next() {
                return Pair.newPair(s.next(), t.next());
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    /**
     * Provides a max number of elements for an underlying base iterator.
     */
    public static  Iterator maxLengthIterator(final Iterator base, final int max) {
        return new Iterator() {
            int count = 0;

            public boolean hasNext() {
                return base.hasNext() && count < max;
            }

            public T next() {
                if (!hasNext())
                    throw new NoSuchElementException("No more elements");
                count++;
                return base.next();
            }

            public void remove() {
                throw new UnsupportedOperationException();
                // TODO Maybe this should behave in a more friendly manner
            }

        };
    }

    /**
     * Wraps a two-level iteration scenario in an iterator. Each key of the keys
     * iterator returns an iterator (via the factory) over T's.
     * 
     * The IteratorIterator loops through the iterator associated with each key
     * until all the keys are used up.
     */
    public static class IteratorIterator implements Iterator {
        Iterator current = null;
        Iterator keys;
        Factory> iterFactory;

        public IteratorIterator(Iterator keys, Factory> iterFactory) {
            this.keys = keys;
            this.iterFactory = iterFactory;
            current = getNextIterator();
        }

        private Iterator getNextIterator() {
            Iterator next = null;
            while (next == null) {
                if (!keys.hasNext())
                    break;
                next = iterFactory.newInstance(keys.next());
                if (!next.hasNext())
                    next = null;
            }
            return next;
        }

        public boolean hasNext() {
            return current != null;
        }

        public T next() {
            T next = current.next();
            if (!current.hasNext())
                current = getNextIterator();
            return next;
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }

    }

    /**
     * Creates an iterator that only returns items of a base iterator that pass
     * a filter.
     * 
     * Null items cannot be returned from the base iterator.
     */
    public static class FilteredIterator implements Iterator {
        Filter filter;
        T next;
        private Iterator base;

        public FilteredIterator(Filter filter, Iterator base) {
            super();
            this.filter = filter;
            this.base = base;
            loadNext();
        }

        public FilteredIterator(Filter filter, Iterable items) {
            this(filter, items.iterator());
        }

        private void loadNext() {
            next = null;
            while (next == null && base.hasNext()) {
                next = base.next();
                if (!filter.accept(next))
                    next = null;
            }
        }

        public boolean hasNext() {
            return next != null;
        }

        public T next() {
            T old = next;
            loadNext();
            return old;
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }

    }

    public static class TransformingIterator implements Iterator {
        private MyMethod transformer;
        private Iterator inputIterator;

        public TransformingIterator(Iterator inputIterator, MyMethod transformer) {
            this.inputIterator = inputIterator;
            this.transformer = transformer;
        }

        public boolean hasNext() {
            return inputIterator.hasNext();
        }

        public O next() {
            return transformer.call(inputIterator.next());
        }

        public void remove() {
            inputIterator.remove();

        }
    }

    public static  Iterator filter(Iterator iterator, Filter filter) {
        return new FilteredIterator<>(filter, iterator);
    }

    public static  Iterator concat(Iterable> args) {
        Factory> factory = new Factory>() {

            public Iterator newInstance(Object... args) {
                return (Iterator) args[0];
            }

        };
        return new IteratorIterator<>(Arrays.asList(args).iterator(), factory);
    }

    public static  Iterator concat(Iterator... args) {
        Factory> factory = new Factory>() {

            public Iterator newInstance(Object... args) {
                return (Iterator) args[0];
            }

        };
        return new IteratorIterator<>(Arrays.asList(args).iterator(), factory);
    }

    public static  Iterator oneItemIterator(final U item) {
        return new Iterator() {
            boolean unused = true;

            public boolean hasNext() {
                return unused;
            }

            public U next() {
                unused = false;
                return item;
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    public static Iterator emptyIterator() {
        return new Iterator() {

            public boolean hasNext() {
                return false;
            }

            public Object next() {
                throw new NoSuchElementException();
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }

        };
    }

    public static  Iterable concat(Iterable a, Iterable b) {
        return able(concat(a.iterator(), b.iterator()));
    }

    public static  List nextList(List> iterators) {
        List items = new ArrayList<>(iterators.size());
        for (Iterator iter : iterators) {
            items.add(iter.next());
        }
        return items;
    }

    public static Iterator objectIterator(final ObjectInputStream instream) {
        return new Iterator() {
            Object next = softRead();

            public boolean hasNext() {
                return next != null;
            }

            private Object softRead() {
                try {
                    return instream.readObject();
                } catch (IOException e) {
                    return null;
                } catch (ClassNotFoundException e) {
                    return null;
                }
            }

            public Object next() {
                Object curr = next;
                next = softRead();
                return curr;
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }

        };
    }

}