Search in sources :

Example 1 with XPathEqExpr

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;
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression) HashMap(java.util.HashMap) XPathPathExpr(org.javarosa.xpath.expr.XPathPathExpr) ArrayList(java.util.ArrayList) Constraint(org.javarosa.core.model.condition.Constraint) XPathStringLiteral(org.javarosa.xpath.expr.XPathStringLiteral) XPathEqExpr(org.javarosa.xpath.expr.XPathEqExpr)

Aggregations

ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Constraint (org.javarosa.core.model.condition.Constraint)1 XPathEqExpr (org.javarosa.xpath.expr.XPathEqExpr)1 XPathExpression (org.javarosa.xpath.expr.XPathExpression)1 XPathPathExpr (org.javarosa.xpath.expr.XPathPathExpr)1 XPathStringLiteral (org.javarosa.xpath.expr.XPathStringLiteral)1