use of com.thinkaurelius.titan.diskstorage.keycolumnvalue.SliceQuery in project titan by thinkaurelius.
the class AbstractVertexCentricQueryBuilder method constructQuery.
protected BaseVertexCentricQuery constructQuery(RelationType returnType) {
assert returnType != null;
if (limit == 0)
return BaseVertexCentricQuery.emptyQuery();
// Prepare direction
if (returnType == RelationType.PROPERTY) {
if (dir == Direction.IN)
return BaseVertexCentricQuery.emptyQuery();
dir = Direction.OUT;
}
assert getVertexConstraint() == null || returnType == RelationType.EDGE;
// Prepare constraints
And<TitanRelation> conditions = QueryUtil.constraints2QNF(tx, constraints);
if (conditions == null)
return BaseVertexCentricQuery.emptyQuery();
assert limit > 0;
// Don't be smart with query limit adjustments - it just messes up the caching layer and penalizes when appropriate limits are set by the user!
int sliceLimit = limit;
// Construct (optimal) SliceQueries
EdgeSerializer serializer = tx.getEdgeSerializer();
List<BackendQueryHolder<SliceQuery>> queries;
if (!hasTypes()) {
BackendQueryHolder<SliceQuery> query = new BackendQueryHolder<SliceQuery>(serializer.getQuery(returnType), ((dir == Direction.BOTH || (returnType == RelationType.PROPERTY && dir == Direction.OUT)) && !conditions.hasChildren() && includeHidden), true, null);
if (sliceLimit != Query.NO_LIMIT && sliceLimit < Integer.MAX_VALUE / 3) {
// If only one direction is queried, ask for twice the limit from backend since approximately half will be filtered
if (dir != Direction.BOTH && (returnType == RelationType.EDGE || returnType == RelationType.RELATION))
sliceLimit *= 2;
// on properties, add some for the hidden properties on a vertex
if (!includeHidden && (returnType == RelationType.PROPERTY || returnType == RelationType.RELATION))
sliceLimit += 3;
}
query.getBackendQuery().setLimit(computeLimit(conditions, sliceLimit));
queries = ImmutableList.of(query);
// Add remaining conditions that only apply if no type is defined
if (!includeHidden)
conditions.add(new HiddenFilterCondition<TitanRelation>());
conditions.add(returnType);
} else {
Set<TitanType> ts = new HashSet<TitanType>(types.length);
queries = new ArrayList<BackendQueryHolder<SliceQuery>>(types.length + 4);
for (String typeName : types) {
InternalType type = getType(typeName);
if (type != null && (includeHidden || !type.isHidden())) {
ts.add(type);
if (type.isPropertyKey()) {
if (returnType == RelationType.EDGE)
throw new IllegalArgumentException("Querying for edges but including a property key: " + type.getName());
returnType = RelationType.PROPERTY;
}
if (type.isEdgeLabel()) {
if (returnType == RelationType.PROPERTY)
throw new IllegalArgumentException("Querying for properties but including an edge label: " + type.getName());
returnType = RelationType.EDGE;
}
// Construct sort key constraints (if any, and if not direction==Both)
EdgeSerializer.TypedInterval[] sortKeyConstraints = new EdgeSerializer.TypedInterval[type.getSortKey().length];
And<TitanRelation> remainingConditions = conditions;
boolean vertexConstraintApplies = type.getSortKey().length == 0 || conditions.hasChildren();
if (type.getSortKey().length > 0 && conditions.hasChildren()) {
remainingConditions = conditions.clone();
sortKeyConstraints = compileSortKeyConstraints(type, tx, remainingConditions);
// Constraints cannot be matched
if (sortKeyConstraints == null)
continue;
Interval interval;
if (sortKeyConstraints[sortKeyConstraints.length - 1] == null || (interval = sortKeyConstraints[sortKeyConstraints.length - 1].interval) == null || !interval.isPoint()) {
vertexConstraintApplies = false;
}
}
Direction[] dirs = { dir };
EdgeSerializer.VertexConstraint vertexConstraint = getVertexConstraint();
if (dir == Direction.BOTH && (hasSortKeyConstraints(sortKeyConstraints) || (vertexConstraintApplies && vertexConstraint != null))) {
// Split on direction in the presence of effective sort key constraints
dirs = new Direction[] { Direction.OUT, Direction.IN };
}
for (Direction dir : dirs) {
EdgeSerializer.VertexConstraint vertexCon = vertexConstraint;
if (vertexCon == null || !vertexConstraintApplies || type.isUnique(dir))
vertexCon = null;
EdgeSerializer.TypedInterval[] sortConstraints = sortKeyConstraints;
if (hasSortKeyConstraints(sortKeyConstraints) && type.isUnique(dir)) {
sortConstraints = new EdgeSerializer.TypedInterval[type.getSortKey().length];
}
boolean isFitted = !remainingConditions.hasChildren() && vertexConstraint == vertexCon && sortConstraints == sortKeyConstraints;
SliceQuery q = serializer.getQuery(type, dir, sortConstraints, vertexCon);
q.setLimit(computeLimit(remainingConditions, sliceLimit));
queries.add(new BackendQueryHolder<SliceQuery>(q, isFitted, true, null));
}
}
}
if (queries.isEmpty())
return BaseVertexCentricQuery.emptyQuery();
conditions.add(getTypeCondition(ts));
}
return new BaseVertexCentricQuery(QueryUtil.simplifyQNF(conditions), dir, queries, limit);
}
use of com.thinkaurelius.titan.diskstorage.keycolumnvalue.SliceQuery in project titan by thinkaurelius.
the class MultiVertexCentricQueryBuilder method relations.
protected Map<TitanVertex, Iterable<? extends TitanRelation>> relations(RelationType returnType) {
Preconditions.checkArgument(!vertices.isEmpty(), "Need to add at least one vertex to query");
BaseVertexCentricQuery vq = super.constructQuery(returnType);
Map<TitanVertex, Iterable<? extends TitanRelation>> result = new HashMap<TitanVertex, Iterable<? extends TitanRelation>>(vertices.size());
if (!vq.isEmpty()) {
for (BackendQueryHolder<SliceQuery> sq : vq.getQueries()) {
tx.executeMultiQuery(vertices, sq.getBackendQuery());
}
Condition<TitanRelation> condition = vq.getCondition();
for (InternalVertex v : vertices) {
// Add other-vertex and direction related conditions
And<TitanRelation> newcond = new And<TitanRelation>();
if (condition instanceof And)
newcond.addAll((And) condition);
else
newcond.add(condition);
newcond.add(new DirectionCondition<TitanRelation>(v, getDirection()));
VertexCentricQuery vqsingle = new VertexCentricQuery(v, newcond, vq.getDirection(), vq.getQueries(), vq.getLimit());
result.put(v, new QueryProcessor<VertexCentricQuery, TitanRelation, SliceQuery>(vqsingle, tx.edgeProcessor));
}
} else {
Iterable<? extends TitanRelation> emptyIter = IterablesUtil.emptyIterable();
for (TitanVertex v : vertices) result.put(v, emptyIter);
}
return result;
}
Aggregations