
io.mindmaps.graql.internal.gremlin.ShortcutTraversal Maven / Gradle / Ivy
/*
* MindmapsDB - A Distributed Semantic Database
* Copyright (C) 2016 Mindmaps Research Ltd
*
* MindmapsDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MindmapsDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MindmapsDB. If not, see .
*/
package io.mindmaps.graql.internal.gremlin;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static io.mindmaps.util.Schema.EdgeLabel.SHORTCUT;
import static io.mindmaps.util.Schema.EdgeProperty.*;
/**
* some {@code VarTraversals} can be represented using shortcut edges.
* {@code ShortcutTraversal} represents this pattern in order to improve query performance
*
* A {@code VarTraversals} can be represented by a shortcut edge when:
*
* - it represents a relation
* - the relation has no internal properties or resources specified (id, value ...)
* - the relation has exactly two roleplayers
* - if the type and role-types are specified, they are specified only by id and no other properties
* - the relation has not been given a variable name
*
*/
public class ShortcutTraversal {
private final List> roletypes = new ArrayList<>();
private final List roleplayers = new ArrayList<>();
private boolean valid = true;
private Optional type = Optional.empty();
private MultiTraversal multiTraversal = null;
/**
* @return true if a shortcut edge can be used in the traversal
*/
boolean isValid() {
return valid && (roleplayers.size() == 2);
}
/**
* Make this ShortcutTraversal invalid, so it will not be used in the traversal
*/
public void setInvalid() {
valid = false;
}
/**
* @return a MultiTraversal that follows shortcut edges
*/
MultiTraversal getMultiTraversal() {
if (multiTraversal == null) makeMultiTraversal();
return multiTraversal;
}
/**
* Create a MultiTraversal that follows shortcut edges
*/
private void makeMultiTraversal() {
Optional roleA = roletypes.get(0);
String playerA = roleplayers.get(0);
Optional roleB = roletypes.get(1);
String playerB = roleplayers.get(1);
multiTraversal = MultiTraversal.create(
new FragmentImpl(t -> makeTraversal(t, roleA, roleB), FragmentPriority.EDGE_RELATION, playerA, playerB),
new FragmentImpl(t -> makeTraversal(t, roleB, roleA), FragmentPriority.EDGE_RELATION, playerB, playerA)
);
}
/**
* @param traversal the traversal to start from
* @param roleA the role type of A, if one is specified
* @param roleB the role type of B, if one is specified
* @return a traversal following a shortcut edge from A to B using the given roles
*/
private GraphTraversal makeTraversal(
GraphTraversal traversal, Optional roleA, Optional roleB
) {
GraphTraversal edgeTraversal = traversal.outE(SHORTCUT.getLabel());
roleA.ifPresent(ra -> edgeTraversal.has(FROM_ROLE.name(), ra));
roleB.ifPresent(rb -> edgeTraversal.has(TO_ROLE.name(), rb));
type.ifPresent(t -> edgeTraversal.has(RELATION_TYPE_ID.name(), t));
return edgeTraversal.inV();
}
/**
* @param type the type of the variable this ShortcutTraversal represents
*/
public void setType(String type) {
if (!this.type.isPresent()) {
this.type = Optional.of(type);
} else {
setInvalid();
}
}
/**
* @param roleplayer a roleplayer of the relation that this ShortcutTraversal represents
*/
public void addRel(String roleplayer) {
roletypes.add(Optional.empty());
roleplayers.add(roleplayer);
}
/**
* @param roletype the role type of the given roleplayer
* @param roleplayer a roleplayer of the relation that this ShortcutTraversal represents
*/
public void addRel(String roletype, String roleplayer) {
roletypes.add(Optional.of(roletype));
roleplayers.add(roleplayer);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy