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

be.bagofwords.iterator.IterableUtils Maven / Gradle / Ivy

package be.bagofwords.iterator;

import be.bagofwords.util.KeyValue;

import java.lang.reflect.Array;
import java.util.*;

public class IterableUtils {

    public static  DataIterable createIterable(final DataIterable... iterables) {
        return createIterable(CombineMethod.SEQUENTIAL, iterables);
    }

    public static  DataIterable createIterable(CombineMethod combineMethod, final DataIterable... iterables) {
        return createIterable(combineMethod, Arrays.asList(iterables));
    }

    public static  DataIterable createIterable(final List> iterables) {
        return createIterable(CombineMethod.SEQUENTIAL, iterables);
    }

    public static  DataIterable createIterable(final Collection collection) {
        return new DataIterable() {
            @Override
            public CloseableIterator iterator() {
                return IterableUtils.iterator(collection.iterator());
            }

            @Override
            public long apprSize() {
                return collection.size();
            }
        };
    }

    public static  DataIterable createIterable(final CombineMethod combineMethod, final List> iterables) {
        return new DataIterable() {
            @Override
            public CloseableIterator iterator() {
                List> iterators = new ArrayList<>();
                for (DataIterable iterable : iterables) {
                    iterators.add(iterable.iterator());
                }
                if (combineMethod == CombineMethod.SEQUENTIAL) {
                    return new SequentialIteratorOfIterators<>(iterators);
                } else {
                    return new InterleavedIteratorOfIterators<>(iterators);
                }
            }

            @Override
            public long apprSize() {
                long result = 0;
                for (DataIterable iterable : iterables) {
                    result += iterable.apprSize();
                }
                return result;
            }
        };
    }

    public static  CloseableIterator iterator(final SimpleIterator simpleIt) {
        return iterator(simpleIt, null);
    }

    public static  CloseableIterator iterator(final SimpleIterator simpleIt, final T lastValue) {
        return new CloseableIterator() {

            private T nextValue;

            {
                findNext();
            }

            private void findNext() {
                try {
                    nextValue = simpleIt.next();
                    if (nextValue == null) {
                        if (lastValue == null) {
                            close();
                        }
                    } else {
                        if (lastValue != null && nextValue.equals(lastValue)) {
                            close();
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException("Could not read next value ", e);
                }
            }

            @Override
            public boolean hasNext() {
                if (lastValue == null) {
                    return nextValue != null;
                } else {
                    return !lastValue.equals(nextValue);
                }
            }

            @Override
            public synchronized T next() {
                T result = nextValue;
                findNext();
                return result;
            }

            @Override
            public void remove() {
                throw new RuntimeException("Not implemented");
            }

            @Override
            public void closeInt() {
                synchronized (this) {
                    try {
                        simpleIt.close();
                    } catch (Exception e) {
                        throw new RuntimeException("Failed to close iterator", e);
                    }
                }
            }
        };
    }

    public static  CloseableIterator iterator(final Iterator iterator) {
        return new CloseableIterator() {
            @Override
            public void closeInt() {
                //do nothing
            }

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

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

    public static  CloseableIterator maxSizeIterator(final long maxIterations, final CloseableIterator iterator) {
        return new CloseableIterator() {

            private long numDone = 0;

            @Override
            protected void closeInt() {
                iterator.close();
            }

            @Override
            public boolean hasNext() {
                return iterator.hasNext() && numDone < maxIterations;
            }

            @Override
            public T next() {
                numDone++;
                return iterator.next();
            }
        };
    }

    public static  DataIterable maxSizeIterable(final long maxIterations, final DataIterable iterable) {
        if (maxIterations <= 0) {
            throw new RuntimeException("Incorrect number of iterations " + maxIterations);
        }
        return new DataIterable() {
            @Override
            public CloseableIterator iterator() {
                return maxSizeIterator(maxIterations, iterable.iterator());
            }

            @Override
            public long apprSize() {
                return Math.min(maxIterations, iterable.apprSize());
            }
        };
    }

    public static enum CombineMethod {
        SEQUENTIAL, INTERLEAVED
    }

    public static  DataIterable> createGroupingIterable(final Class objectClass, final List>> iterables) {
        final List>> iterators = new ArrayList<>();
        for (DataIterable> iterable : iterables) {
            iterators.add(iterable.iterator());
        }

        return new DataIterable>() {
            @Override
            public CloseableIterator> iterator() {
                return new CloseableIterator>() {

                    private KeyValue[] storedValues = new KeyValue[iterators.size()];

                    @Override
                    protected void closeInt() {
                        for (CloseableIterator> iterator : iterators) {
                            iterator.close();
                        }
                    }

                    @Override
                    public boolean hasNext() {
                        for (int i = 0; i < iterators.size(); i++) {
                            if (iterators.get(i).hasNext() || storedValues[i] != null) {
                                return true;
                            }
                        }
                        return false;
                    }

                    @Override
                    public KeyValue next() {
                        long smallestKey = Long.MAX_VALUE;
                        for (int i = 0; i < iterators.size(); i++) {
                            CloseableIterator> currIt = iterators.get(i);
                            if (storedValues[i] == null && currIt.hasNext()) {
                                storedValues[i] = currIt.next();
                            }
                            if (storedValues[i] != null) {
                                smallestKey = Math.min(smallestKey, storedValues[i].getKey());
                            }
                        }
                        T[] result = (T[]) Array.newInstance(objectClass, storedValues.length);
                        for (int i = 0; i < iterators.size(); i++) {
                            if (storedValues[i] != null && storedValues[i].getKey() == smallestKey) {
                                result[i] = storedValues[i].getValue();
                                storedValues[i] = null;
                            }
                        }
                        return new KeyValue<>(smallestKey, result);
                    }
                };
            }

            @Override
            public long apprSize() {
                long maxSize = 0;
                for (DataIterable> iterable : iterables) {
                    maxSize = Math.max(maxSize, iterable.apprSize());
                }
                return maxSize;
            }
        };
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy