static int s_CountNodesOfGivenType(const CQueryParseTree::TNode& node, CQueryParseNode::EType type) { if (node.IsLeaf()) { return (node->GetType() == type) ? 1 : 0; } CQueryParseTree::TNode::TNodeList_CI iter = node.SubNodeBegin(); int count = 0; for (; iter != node.SubNodeEnd(); ++iter) { CQueryParseTree::TNode& sub_node = **iter; count += s_CountNodesOfGivenType(sub_node, type); } return (node->GetType() == type) ? count +1 : count; }
void CAlignFilter::x_ParseTree_Flatten(CQueryParseTree& tree, CQueryParseTree::TNode& node) { CQueryParseNode::EType type = node->GetType(); switch (type) { case CQueryParseNode::eAnd: case CQueryParseNode::eOr: {{ CQueryParseTree::TNode::TNodeList_I iter; size_t hoisted = 0; size_t count_by_complexity[] = {0, 0}; do { hoisted = 0; for (iter = node.SubNodeBegin(); iter != node.SubNodeEnd(); ) { CQueryParseTree::TNode& sub_node = **iter; ++count_by_complexity[x_Complexity(sub_node)]; if (sub_node->GetType() == type) { /// hoist this node's children CQueryParseTree::TNode::TNodeList_I sub_iter = sub_node.SubNodeBegin(); for ( ; sub_iter != sub_node.SubNodeEnd(); ) { node.AddNode(sub_node.DetachNode(*sub_iter++)); } node.RemoveNode(iter++); ++hoisted; } else { ++iter; } } } while (hoisted != 0); if (count_by_complexity[CScoreLookup::IScore::eEasy] && count_by_complexity[CScoreLookup::IScore::eHard]) { /// Have both easy and hard subnodes; move hard nodes to end CQueryParseTree::TNode::TNodeList hard_nodes; for (iter = node.SubNodeBegin(); iter != node.SubNodeEnd(); ) { if (x_Complexity(**iter) == CScoreLookup::IScore::eHard) { hard_nodes.push_back(node.DetachNode(*iter++)); } else { ++iter; } } ITERATE (CQueryParseTree::TNode::TNodeList, it, hard_nodes) { node.AddNode(*it); } } }}