void LocationPath::evaluate(NodeSet& nodes) const { bool resultIsSorted = nodes.isSorted(); for (unsigned i = 0; i < m_steps.size(); i++) { Step* step = m_steps[i]; NodeSet newNodes; HashSet<Node*> newNodesSet; bool needToCheckForDuplicateNodes = !nodes.subtreesAreDisjoint() || (step->axis() != Step::ChildAxis && step->axis() != Step::SelfAxis && step->axis() != Step::DescendantAxis && step->axis() != Step::DescendantOrSelfAxis && step->axis() != Step::AttributeAxis); if (needToCheckForDuplicateNodes) resultIsSorted = false; // This is a simplified check that can be improved to handle more cases. if (nodes.subtreesAreDisjoint() && (step->axis() == Step::ChildAxis || step->axis() == Step::SelfAxis)) newNodes.markSubtreesDisjoint(true); for (unsigned j = 0; j < nodes.size(); j++) { NodeSet matches; step->evaluate(nodes[j], matches); if (!matches.isSorted()) resultIsSorted = false; for (size_t nodeIndex = 0; nodeIndex < matches.size(); ++nodeIndex) { Node* node = matches[nodeIndex]; if (!needToCheckForDuplicateNodes || newNodesSet.add(node).isNewEntry) newNodes.append(node); } } nodes.swap(newNodes); } nodes.markSorted(resultIsSorted); }
void LocationPath::evaluate(NodeSet& nodes) const { bool resultIsSorted = nodes.isSorted(); for (auto& step : m_steps) { NodeSet newNodes; HashSet<Node*> newNodesSet; bool needToCheckForDuplicateNodes = !nodes.subtreesAreDisjoint() || (step->axis() != Step::ChildAxis && step->axis() != Step::SelfAxis && step->axis() != Step::DescendantAxis && step->axis() != Step::DescendantOrSelfAxis && step->axis() != Step::AttributeAxis); if (needToCheckForDuplicateNodes) resultIsSorted = false; // This is a simplified check that can be improved to handle more cases. if (nodes.subtreesAreDisjoint() && (step->axis() == Step::ChildAxis || step->axis() == Step::SelfAxis)) newNodes.markSubtreesDisjoint(true); for (auto& node : nodes) { NodeSet matches; step->evaluate(*node, matches); if (!matches.isSorted()) resultIsSorted = false; for (auto& match : matches) { if (!needToCheckForDuplicateNodes || newNodesSet.add(match.get()).isNewEntry) newNodes.append(match.copyRef()); } } nodes = WTFMove(newNodes); } nodes.markSorted(resultIsSorted); }