use of annis.model.QueryNode.Range in project ANNIS by korpling.
the class TransitivePrecedenceOptimizer method propagateNodePrecedence.
private void propagateNodePrecedence(QueryNode initialNode, QueryNode currentNode, Set<Long> visitedNodes, Map<Long, Set<Precedence>> outJoins, Range range, String segmentation) {
visitedNodes.add(currentNode.getId());
Map<QueryNode, Range> nextNodes = new HashMap<>();
// iterator over all outgoing precedence joins
List<Join> originalJoins = new LinkedList<>(currentNode.getOutgoingJoins());
for (Join join : originalJoins) {
if (join instanceof Precedence) {
Precedence p = (Precedence) join;
if ((segmentation == null && p.getSegmentationName() == null) || (segmentation != null && segmentation.equals(p.getSegmentationName()))) {
Range newRange;
if (range == null) {
// create a new range at initial node
newRange = new Range(p.getMinDistance(), p.getMaxDistance());
} else {
// calculate the new range depending on old one
if (currentNode.isToken() == false || (range.getMin() == 0 && range.getMax() == 0) || (p.getMinDistance() == 0 && p.getMaxDistance() == 0)) {
// use unlimited range since
// a) the node could also be a
// span covering more than one token,
// b) the original constraint is an unlimited range
newRange = new Range(0, 0);
} else {
// add the new precendence values to the old one
newRange = new Range(range.getMin() + p.getMinDistance(), range.getMax() + p.getMaxDistance());
}
}
// put the target node in the list of nodes to check if not visited yet
if (!visitedNodes.contains(p.getTarget().getId())) {
nextNodes.put(p.getTarget(), newRange);
Precedence newJoin = new Precedence(p.getTarget(), newRange.getMin(), newRange.getMax());
Set<Precedence> existingJoins = outJoins.get(initialNode.getId());
// only add if this join is not already included
// (which is always true for the initial node)
// and the join is more restrictive than any previous one
boolean moreRestrictive = true;
for (Precedence oldJoin : existingJoins) {
if (oldJoin.getTarget() == newJoin.getTarget()) {
if (!joinMoreRestrictive(oldJoin, newJoin)) {
moreRestrictive = false;
break;
}
}
}
if (moreRestrictive) {
// add newly created discovered transitive precedence
initialNode.addOutgoingJoin(newJoin);
existingJoins.add(newJoin);
}
}
// end if not visited yet
}
// end if segmentation matches
}
// end if is precedence join
}
for (Map.Entry<QueryNode, Range> e : nextNodes.entrySet()) {
// call us recursivly but remember the range
propagateNodePrecedence(initialNode, e.getKey(), visitedNodes, outJoins, e.getValue(), segmentation);
}
}
Aggregations