use of org.javarosa.xpath.expr.XPathEqExpr in project javarosa by opendatakit.
the class TreeElement method tryBatchChildFetch.
@Override
public List<TreeReference> tryBatchChildFetch(String name, int mult, List<XPathExpression> predicates, EvaluationContext evalContext) {
// Only do for predicates
if (mult != TreeReference.INDEX_UNBOUND || predicates == null) {
return null;
}
List<Integer> toRemove = new ArrayList<Integer>();
List<TreeReference> selectedChildren = null;
// Lazy init these until we've determined that our predicate is hintable
HashMap<XPathPathExpr, String> indices = null;
List<TreeElement> kids = null;
predicate: for (int i = 0; i < predicates.size(); ++i) {
XPathExpression xpe = predicates.get(i);
// something we index with something static.
if (xpe instanceof XPathEqExpr) {
XPathExpression left = ((XPathEqExpr) xpe).a;
XPathExpression right = ((XPathEqExpr) xpe).b;
// handling attribute based referencing with very reasonable timing, but it's complex otherwise)
if (left instanceof XPathPathExpr && right instanceof XPathStringLiteral) {
// don't want the overhead if our predicate is too complex anyway
if (indices == null) {
indices = new HashMap<XPathPathExpr, String>();
kids = this.getChildrenWithName(name);
if (kids.size() == 0) {
return null;
}
// Anything that we're going to use across elements should be on all of them
TreeElement kid = kids.get(0);
for (int j = 0; j < kid.getAttributeCount(); ++j) {
String attribute = kid.getAttributeName(j);
indices.put(XPathReference.getPathExpr("@" + attribute), attribute);
}
}
for (XPathPathExpr expr : indices.keySet()) {
if (expr.equals(left)) {
String attributeName = indices.get(expr);
for (TreeElement kid : kids) {
if (kid.getAttributeValue(null, attributeName).equals(((XPathStringLiteral) right).s)) {
if (selectedChildren == null) {
selectedChildren = new ArrayList<TreeReference>();
}
selectedChildren.add(kid.getRef());
}
}
// Note that this predicate is evaluated and doesn't need to be evaluated in the future.
toRemove.add(DataUtil.integer(i));
continue predicate;
}
}
}
}
// so otherwise, just get outta here.
break;
}
// if we weren't able to evaluate any predicates, signal that.
if (selectedChildren == null) {
return null;
}
// otherwise, remove all of the predicates we've already evaluated
for (int i = toRemove.size() - 1; i >= 0; i--) {
predicates.remove(toRemove.get(i).intValue());
}
return selectedChildren;
}
Aggregations