Skip to content

Commit

Permalink
Merge pull request #3972 from mad/fix-ordered-iterator
Browse files Browse the repository at this point in the history
Fix ordered iterator
  • Loading branch information
mad authored Sep 18, 2023
2 parents 6681799 + e1ebeb7 commit c39a12a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,7 @@ public void testGraphCentricQueryProfiling() {
// satisfied by two graph-centric queries, one is mixed index query and the other one is full scan
newTx();
assertEquals(3, tx.traversal().V().or(__.has("name", "bob"), __.has("age", 20)).count().next());
assertEquals(3, tx.traversal().V().or(__.has("name", "bob"), __.has("age", 20)).order().by("age").count().next());
assertEquals(3, tx.traversal().V().or(__.has("name", "bob"), __.has("age", 20)).toList().size());
assertEquals(190, tx.traversal().V().or(__.has("name", "bob"), __.has("age", 20)).values("height").max().next());
assertEquals(170, tx.traversal().V().or(__.has("name", "bob"), __.has("age", 20)).values("height").min().next());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,39 @@

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.TreeMap;

public class MultiDistinctOrderedIterator<E extends Element> extends CloseableAbstractIterator<E> {

public class MultiDistinctOrderedIterator<E extends Element> implements CloseableIterator<E> {

private final Map<Integer, Iterator<E>> iterators = new LinkedHashMap<>();
private final Map<Integer, E> values = new LinkedHashMap<>();
private final TreeMap<E, Integer> currentElements;
private final Map<Integer, Iterator<E>> iterators;
private final PriorityQueue<E> queue;
private final Set<Object> allElements = new HashSet<>();
private final List<E> iteratorValues;
private final Map<E, Integer> iteratorIdx;
private final Integer limit;
private final boolean singleIterator;
private long count = 0;

public MultiDistinctOrderedIterator(final Integer lowLimit, final Integer highLimit, final List<Iterator<E>> iterators, final List<OrderEntry> orders) {
this.limit = highLimit;
this.singleIterator = iterators.size() == 1;
final List<Comparator<E>> comp = new ArrayList<>();
orders.forEach(o -> comp.add(new ElementValueComparator(o.key, o.order)));
Comparator<E> comparator = new MultiComparator<>(comp);
this.iterators = new LinkedHashMap<>(iterators.size());
this.iteratorValues = new ArrayList<>(iterators.size());
this.iteratorIdx = new HashMap<>(iterators.size());
for (int i = 0; i < iterators.size(); i++) {
this.iterators.put(i, iterators.get(i));
this.iteratorValues.add(null);
}
currentElements = new TreeMap<>(comparator);
final List<Comparator<E>> comp = new ArrayList<>();
orders.forEach(o -> comp.add(new ElementValueComparator(o.key, o.order)));
this.queue = new PriorityQueue<>(iterators.size(), new MultiComparator<>(comp));
long i = 0;
while (i < lowLimit && this.hasNext()) {
this.next();
Expand All @@ -60,12 +64,12 @@ public MultiDistinctOrderedIterator(final Integer lowLimit, final Integer highLi
}

@Override
public boolean hasNext() {
protected E computeNext() {
if (limit != null && limit != Query.NO_LIMIT && count >= limit) {
return false;
return endOfData();
}
for (int i = 0; i < iterators.size(); i++) {
if (!values.containsKey(i) && iterators.get(i).hasNext()){
if (iteratorValues.get(i) == null && iterators.get(i).hasNext()) {
E element = null;
do {
element = iterators.get(i).next();
Expand All @@ -74,26 +78,27 @@ public boolean hasNext() {
}
} while (element == null && iterators.get(i).hasNext());
if (element != null) {
values.put(i, element);
currentElements.put(element, i);
iteratorValues.set(i, element);
iteratorIdx.put(element, i);
queue.add(element);
if (!singleIterator) {
allElements.add(element.id());
}
}
}
}
return !values.isEmpty();
}

@Override
public E next() {
count++;
return values.remove(currentElements.remove(currentElements.firstKey()));
if (queue.isEmpty()) {
return endOfData();
} else {
count++;
E result = queue.remove();
iteratorValues.set(iteratorIdx.remove(result), null);
return result;
}
}

@Override
public void close() {
iterators.values().forEach(CloseableIterator::closeIterator);
}

}

1 comment on commit c39a12a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: c39a12a Previous: 6205752 Ratio
org.janusgraph.JanusGraphSpeedBenchmark.basicAddAndDelete 17622.56595168698 ms/op 22579.688640648168 ms/op 0.78
org.janusgraph.GraphCentricQueryBenchmark.getVertices 1594.1248595544378 ms/op 1693.3271383287579 ms/op 0.94
org.janusgraph.MgmtOlapJobBenchmark.runClearIndex 221.99647398260868 ms/op 222.8017045478261 ms/op 1.00
org.janusgraph.MgmtOlapJobBenchmark.runReindex 509.75968897727273 ms/op 565.8578123657144 ms/op 0.90
org.janusgraph.JanusGraphSpeedBenchmark.basicCount 506.0548470977634 ms/op 458.33261599744327 ms/op 1.10
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesAllPropertiesWithAllMultiQuerySlicesUnderMaxRequestsPerConnection 12103.272196556067 ms/op 13027.779634965924 ms/op 0.93
org.janusgraph.CQLMultiQueryBenchmark.getElementsWithUsingEmitRepeatSteps 38104.24966912191 ms/op 42947.178598 ms/op 0.89
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesMultiplePropertiesWithSmallBatch 40825.23804507762 ms/op 47549.632632216664 ms/op 0.86
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.vertexCentricPropertiesFetching 83427.9873206 ms/op 99834.0656897 ms/op 0.84
org.janusgraph.CQLMultiQueryBenchmark.getAllElementsTraversedFromOuterVertex 19052.173492902635 ms/op 21717.084192162452 ms/op 0.88
org.janusgraph.CQLMultiQueryBenchmark.getVerticesWithDoubleUnion 740.9090414550153 ms/op 763.9341528866134 ms/op 0.97
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesAllPropertiesWithUnlimitedBatch 10509.448100418682 ms/op 12156.922564930786 ms/op 0.86
org.janusgraph.CQLMultiQueryBenchmark.getNames 19074.686938554165 ms/op 21623.489783162986 ms/op 0.88
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesThreePropertiesWithAllMultiQuerySlicesUnderMaxRequestsPerConnection 13477.87408297365 ms/op 16175.502236128377 ms/op 0.83
org.janusgraph.CQLMultiQueryBenchmark.getLabels 16573.850222334895 ms/op
org.janusgraph.CQLMultiQueryBenchmark.getVerticesFilteredByAndStep 820.7574024888672 ms/op 828.1404002420064 ms/op 0.99
org.janusgraph.CQLMultiQueryBenchmark.getVerticesFromMultiNestedRepeatStepStartingFromSingleVertex 26287.37958739365 ms/op 28624.24182517619 ms/op 0.92
org.janusgraph.CQLMultiQueryBenchmark.getVerticesWithCoalesceUsage 681.4104449129808 ms/op 770.5690844916234 ms/op 0.88
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesMultiplePropertiesWithAllMultiQuerySlicesUnderMaxRequestsPerConnection 35304.05537217595 ms/op 42753.61769863095 ms/op 0.83
org.janusgraph.CQLMultiQueryBenchmark.getIdToOutVerticesProjection 465.6852994644584 ms/op 518.0698862502832 ms/op 0.90
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesMultiplePropertiesWithUnlimitedBatch 37087.967557060634 ms/op 45390.244630558336 ms/op 0.82
org.janusgraph.CQLMultiQueryBenchmark.getNeighborNames 19265.263204399576 ms/op 21751.645129234243 ms/op 0.89
org.janusgraph.CQLMultiQueryBenchmark.getElementsWithUsingRepeatUntilSteps 20639.069591600553 ms/op 22817.45437812944 ms/op 0.90
org.janusgraph.CQLMultiQueryBenchmark.getAdjacentVerticesLocalCounts 19184.32202865276 ms/op 21574.947662841663 ms/op 0.89

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.