// Copyright 2017 JanusGraph 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 org.janusgraph.graphdb.query; import com.google.common.base.Preconditions; import java.util.Comparator; import java.util.Iterator; import java.util.NoSuchElementException; /** * @author Matthias Broecheler (me@matthiasb.com) */ public class ResultMergeSortIterator<R> implements Iterator<R> { private final Iterator<R> first; private final Iterator<R> second; private final Comparator<R> comp; private final boolean filterDuplicates; private R nextFirst; private R nextSecond; private R next; public ResultMergeSortIterator(Iterator<R> first, Iterator<R> second, Comparator<R> comparator, boolean filterDuplicates) { Preconditions.checkNotNull(first); Preconditions.checkNotNull(second); Preconditions.checkNotNull(comparator); this.first = first; this.second = second; this.comp = comparator; this.filterDuplicates = filterDuplicates; nextFirst = null; nextSecond = null; next = nextInternal(); } @Override public boolean hasNext() { return next != null; } @Override public R next() { if (!hasNext()) throw new NoSuchElementException(); R current = next; next = null; do { next = nextInternal(); } while (next != null && filterDuplicates && comp.compare(current, next) == 0); return current; } public R nextInternal() { if (nextFirst == null && first.hasNext()) { nextFirst = first.next(); assert nextFirst != null; } if (nextSecond == null && second.hasNext()) { nextSecond = second.next(); assert nextSecond != null; } R result = null; if (nextFirst == null && nextSecond == null) { return null; } else if (nextFirst == null) { result = nextSecond; nextSecond = null; } else if (nextSecond == null) { result = nextFirst; nextFirst = null; } else { //Compare int c = comp.compare(nextFirst, nextSecond); if (c <= 0) { result = nextFirst; nextFirst = null; } else { result = nextSecond; nextSecond = null; } } return result; } @Override public void remove() { throw new UnsupportedOperationException(); } public static<R> Iterable<R> mergeSort(final Iterable<R> first, final Iterable<R> second, final Comparator<R> comparator, final boolean filterDuplicates) { return new Iterable<R>() { @Override public Iterator<R> iterator() { return new ResultMergeSortIterator<R>(first.iterator(),second.iterator(),comparator,filterDuplicates); } }; } }