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

org.canova.api.berkeley.Iterators Maven / Gradle / Ivy

There is a newer version: 0.0.0.17
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.canova.api.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;
	}

	/**
	 * Wraps 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
	 * @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();
			}

		};
	}

}