static int s_GetTreeHeight(const CQueryParseTree::TNode& node)
{
    if (node.IsLeaf()) return 0;

    CQueryParseTree::TNode::TNodeList_CI iter = node.SubNodeBegin();
    vector<int> heights;
    for ( ; iter != node.SubNodeEnd(); ++iter) {
        CQueryParseTree::TNode& sub_node = **iter;
        heights.push_back(s_GetTreeHeight(sub_node));
    }

    auto it = max_element(begin(heights), end(heights));
    return *it + 1;
}
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;
}
Example #3
0
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);
                 }
             }
         }}