if (contextItem != null)
{contextSequence = contextItem.toSequence();}
boolean useCached = false;
boolean optimize = false;
NodeSet originalContext = null;
if (contextSequence == null || contextSequence.isPersistentSet()) { // don't try to optimize in-memory node sets!
// contextSequence will be overwritten
originalContext = contextSequence == null ? null : contextSequence.toNodeSet();
if (cachedContext != null && cachedContext == originalContext)
{useCached = !originalContext.hasChanged(cachedTimestamp);}
if (contextVar != null) {
contextSequence = contextVar.eval(contextSequence);
}
// check if all Optimizable expressions signal that they can indeed optimize
// in the current context
if (useCached)
{optimize = cachedOptimize;}
else {
if (optimizables != null && optimizables.length > 0) {
for (int i = 0; i < optimizables.length; i++) {
if (optimizables[i].canOptimize(contextSequence))
{optimize = true;}
else {
optimize = false;
break;
}
}
}
}
}
if (optimize) {
cachedContext = originalContext;
cachedTimestamp = originalContext == null ? 0 : originalContext.getState();
cachedOptimize = true;
NodeSet ancestors;
NodeSet result = null;
for (int current = 0; current < optimizables.length; current++) {
NodeSet selection = optimizables[current].preSelect(contextSequence, current > 0);
if (LOG.isTraceEnabled())
{LOG.trace("exist:optimize: pre-selection: " + selection.getLength());}
// determine the set of potential ancestors for which the predicate has to
// be re-evaluated to filter out wrong matches
if (selection.isEmpty())
{ancestors = selection;}
else if (contextStep == null || current > 0) {
ancestors = selection.selectAncestorDescendant(contextSequence.toNodeSet(), NodeSet.ANCESTOR,
true, contextId, true);
} else {
// NodeSelector selector;
final long start = System.currentTimeMillis();
// selector = new AncestorSelector(selection, contextId, true, false);
final StructuralIndex index = context.getBroker().getStructuralIndex();
final QName ancestorQN = contextStep.getTest().getName();
if (optimizables[current].optimizeOnSelf()) {
ancestors = index.findAncestorsByTagName(ancestorQN.getNameType(), ancestorQN, Constants.SELF_AXIS,
selection.getDocumentSet(), selection, contextId);
} else {
ancestors = index.findAncestorsByTagName(ancestorQN.getNameType(), ancestorQN,
optimizables[current].optimizeOnChild() ? Constants.PARENT_AXIS : Constants.ANCESTOR_SELF_AXIS,
selection.getDocumentSet(), selection, contextId);
}
if (LOG.isTraceEnabled()) {
LOG.trace("Ancestor selection took " + (System.currentTimeMillis() - start));
LOG.trace("Found: " + ancestors.getLength());
}