use of org.umlg.sqlg.structure.SqlgElement in project sqlg by pietermartin.
the class Emit method evaluateElementValueTraversal.
/**
* @param pathSize Indicates the head object path size.
* For SqlgVertexStepCompile they are objects that are already on the path before the step is executed.
*/
public void evaluateElementValueTraversal(int pathSize, Traverser.Admin<E> traverser) {
if (this.comparatorValues == null) {
this.comparatorValues = new ArrayList<>();
}
// loop in reverse, from end to start.
for (int i = this.sqlgComparatorHolders.size() - 1; i >= 0; i--) {
SqlgElement sqlgElement;
SqlgComparatorHolder comparatorHolder = this.sqlgComparatorHolders.get(i);
if (comparatorHolder.hasComparators()) {
if (comparatorHolder.hasPrecedingSelectOneLabel()) {
// Go get the element to compare against.
String precedingLabel = comparatorHolder.getPrecedingSelectOneLabel();
sqlgElement = traverser.path().get(precedingLabel);
} else {
sqlgElement = (SqlgElement) traverser.path().objects().get(i + pathSize);
}
for (Pair<Traversal.Admin<?, ?>, Comparator<?>> traversalComparator : comparatorHolder.getComparators()) {
Traversal.Admin<?, ?> traversal = traversalComparator.getValue0();
Comparator comparator = traversalComparator.getValue1();
if (traversal.getSteps().size() == 1 && traversal.getSteps().get(0) instanceof SelectOneStep) {
// xxxxx.select("a").order().by(select("a").by("name"), Order.decr)
SelectOneStep selectOneStep = (SelectOneStep) traversal.getSteps().get(0);
Preconditions.checkState(selectOneStep.getScopeKeys().size() == 1, "toOrderByClause expects the selectOneStep to have one scopeKey!");
Preconditions.checkState(selectOneStep.getLocalChildren().size() == 1, "toOrderByClause expects the selectOneStep to have one traversal!");
Preconditions.checkState(selectOneStep.getLocalChildren().get(0) instanceof ElementValueTraversal || selectOneStep.getLocalChildren().get(0) instanceof TokenTraversal, "toOrderByClause expects the selectOneStep's traversal to be a ElementValueTraversal or a TokenTraversal!");
String selectKey = (String) selectOneStep.getScopeKeys().iterator().next();
SqlgElement sqlgElementSelect = traverser.path().get(selectKey);
Traversal.Admin<?, ?> t = (Traversal.Admin<?, ?>) selectOneStep.getLocalChildren().get(0);
if (t instanceof ElementValueTraversal) {
ElementValueTraversal elementValueTraversal = (ElementValueTraversal) t;
this.comparatorValues.add(Pair.with(sqlgElementSelect.value(elementValueTraversal.getPropertyKey()), comparator));
} else {
TokenTraversal tokenTraversal = (TokenTraversal) t;
this.comparatorValues.add(Pair.with(tokenTraversal.getToken().apply(sqlgElementSelect), comparator));
}
} else if (traversal instanceof IdentityTraversal) {
// This is for Order.shuffle, Order.shuffle can not be used in Collections.sort(), it violates the sort contract.
// Basically its a crap comparator.
this.comparatorValues.add(Pair.with(new Random().nextInt(), Order.incr));
} else if (traversal instanceof ElementValueTraversal) {
ElementValueTraversal elementValueTraversal = (ElementValueTraversal) traversal;
this.comparatorValues.add(Pair.with(sqlgElement.value(elementValueTraversal.getPropertyKey()), comparator));
} else if (traversal instanceof TokenTraversal) {
TokenTraversal tokenTraversal = (TokenTraversal) traversal;
this.comparatorValues.add(Pair.with(tokenTraversal.getToken().apply(sqlgElement), comparator));
} else {
throw new IllegalStateException("Unhandled traversal " + traversal.getClass().getName());
}
}
}
}
}
use of org.umlg.sqlg.structure.SqlgElement in project sqlg by pietermartin.
the class SqlgBranchStepBarrier method processNextStart.
@Override
protected Traverser.Admin<E> processNextStart() throws NoSuchElementException {
if (this.first) {
List<Traverser.Admin<S>> successfulStarts = new ArrayList<>();
Map<Long, Traverser.Admin<S>> cachedStarts = new HashMap<>();
Map<Traverser.Admin<S>, Object> startBranchTraversalResults = new HashMap<>();
this.first = false;
long startCount = 1;
while (this.starts.hasNext()) {
Traverser.Admin<S> start = this.starts.next();
this.branchTraversal.addStart(start);
((SqlgElement) start.get()).setInternalStartTraverserIndex(startCount);
cachedStarts.put(startCount++, start);
}
Set<Long> toRemove = new HashSet<>();
while (true) {
if (this.branchTraversal.hasNext()) {
Traverser.Admin<M> branchTraverser = this.branchTraversal.nextTraverser();
long startElementIndex = ((SqlgTraverser<M>) branchTraverser).getStartElementIndex();
M m = branchTraverser.get();
// i.e. traversals that do not go to the db.
if (startElementIndex == 0 && m instanceof SqlgElement) {
SqlgElement sqlgElement = (SqlgElement) m;
startElementIndex = sqlgElement.getInternalStartTraverserIndex();
}
if (!(m instanceof SqlgElement)) {
// This assumes that branchTraversals that do not go to the db only return one value per start.
List<Object> branchTraverserPathObjects = branchTraverser.path().objects();
long count = 0;
for (Traverser.Admin<S> cachedStart : cachedStarts.values()) {
count++;
List<Object> cachedStartPathObjects = cachedStart.path().objects();
boolean startsWith = false;
// for CountGlobalStep the path is lost but all elements return something so the branch to take is always the 'true' branch.
if (!(branchTraverserPathObjects.get(0) instanceof SqlgElement)) {
startsWith = true;
}
if (!startsWith) {
int countX = 0;
for (Object startObject : cachedStartPathObjects) {
startsWith = branchTraverserPathObjects.get(countX++).equals(startObject);
if (!startsWith) {
break;
}
}
}
if (startsWith) {
successfulStarts.add(cachedStart);
toRemove.add(count);
startBranchTraversalResults.put(cachedStart, branchTraverserPathObjects.get(branchTraverserPathObjects.size() - 1));
}
}
} else {
Traverser.Admin<S> start = cachedStarts.remove(startElementIndex);
if (start != null) {
successfulStarts.add(start);
}
}
} else {
break;
}
}
// i.e. only failed starts remain in the list.
for (Long remove : toRemove) {
cachedStarts.remove(remove);
}
// true false choose step does not have a HasNextStep. Its been removed to keep the path.
if (this.traversalOptions.containsKey(Boolean.TRUE) && this.traversalOptions.containsKey(Boolean.FALSE)) {
for (Traverser.Admin<S> successfulStart : successfulStarts) {
for (Traversal.Admin<S, E> optionTraversal : this.traversalOptions.get(Boolean.TRUE)) {
optionTraversal.addStart(successfulStart);
}
}
for (Traversal.Admin<S, E> optionTraversal : this.traversalOptions.get(Boolean.FALSE)) {
for (Traverser.Admin<S> start : cachedStarts.values()) {
optionTraversal.addStart(start);
}
}
} else {
for (Map.Entry<Traverser.Admin<S>, Object> entry : startBranchTraversalResults.entrySet()) {
Traverser.Admin<S> start = entry.getKey();
Object branchEndObject = entry.getValue();
if (this.traversalOptions.containsKey(branchEndObject)) {
for (Traversal.Admin<S, E> optionTraversal : this.traversalOptions.get(branchEndObject)) {
optionTraversal.addStart(start);
}
} else {
if (this.traversalOptions.containsKey(Pick.none)) {
for (Traversal.Admin<S, E> optionTraversal : this.traversalOptions.get(Pick.none)) {
optionTraversal.addStart(start);
}
}
}
}
// List<Traversal.Admin<S, E>> optionTraversals = this.traversalOptions.get(Pick.none);
// for (Traversal.Admin<S, E> optionTraversal : optionTraversals) {
// for (Traverser.Admin<S> start : cachedStarts.values()) {
// optionTraversal.addStart(start);
// }
// }
}
// Now travers the options. The starts have been set.
for (M choice : this.traversalOptions.keySet()) {
for (Traversal.Admin<S, E> option : this.traversalOptions.get(choice)) {
while (true) {
if (option.hasNext()) {
this.results.add(option.nextTraverser());
} else {
break;
}
}
}
}
// Sort the results, this is to ensure the the incoming start order is not lost.
this.results.sort((o1, o2) -> {
SqlgTraverser x = (SqlgTraverser) o1;
SqlgTraverser y = (SqlgTraverser) o2;
return Long.compare(x.getStartElementIndex(), y.getStartElementIndex());
});
this.resultIterator = this.results.iterator();
}
while (this.resultIterator.hasNext()) {
return this.resultIterator.next();
}
throw FastNoSuchElementException.instance();
}
use of org.umlg.sqlg.structure.SqlgElement in project sqlg by pietermartin.
the class SqlgOptionalStepBarrier method processNextStart.
@Override
protected Traverser.Admin<S> processNextStart() throws NoSuchElementException {
if (this.first) {
Multimap<String, Traverser.Admin<S>> startRecordIds = LinkedListMultimap.create();
this.first = false;
long startCount = 1;
while (this.starts.hasNext()) {
Traverser.Admin<S> start = this.starts.next();
this.optionalTraversal.addStart(start);
((SqlgElement) start.get()).setInternalStartTraverserIndex(startCount++);
List<Object> startObjects = start.path().objects();
StringBuilder recordIdConcatenated = new StringBuilder();
for (Object startObject : startObjects) {
Element e = (Element) startObject;
recordIdConcatenated.append(e.id().toString());
}
startRecordIds.put(recordIdConcatenated.toString(), start);
}
while (true) {
if (this.optionalTraversal.hasNext()) {
Traverser.Admin<S> optionalTraverser = this.optionalTraversal.nextTraverser();
this.results.add(optionalTraverser);
List<Object> optionObjects = optionalTraverser.path().objects();
String startId = "";
for (Object optionObject : optionObjects) {
Element e = (Element) optionObject;
startId += e.id().toString();
if (startRecordIds.removeAll(startId).isEmpty()) {
break;
}
}
} else {
break;
}
}
for (Traverser.Admin<S> start : startRecordIds.values()) {
this.results.add(start);
// Bulking logic interferes here, addStart calls DefaultTraversal.merge which has bulking logic
start.setBulk(1L);
}
// Now travers the options. The starts have been set.
while (true) {
if (this.optionalTraversal.hasNext()) {
this.results.add(optionalTraversal.nextTraverser());
} else {
break;
}
}
// Sort the results, this is to ensure the the incoming start order is not lost.
this.results.sort((o1, o2) -> {
SqlgTraverser x = (SqlgTraverser) o1;
SqlgTraverser y = (SqlgTraverser) o2;
return Long.compare(x.getStartElementIndex(), y.getStartElementIndex());
});
this.resultIterator = this.results.iterator();
}
while (this.resultIterator.hasNext()) {
return this.resultIterator.next();
}
throw FastNoSuchElementException.instance();
}
Aggregations