コード例 #1
0
CParentIntfc::~CParentIntfc()
{
    TInt count = iChildrenList.Count();
    CChildIntfc* childPtr(NULL);
    for (TInt index(0); index < count; index++)
    {
        if (GetChild(index, childPtr) == KErrNone)
        {
            childPtr->ParentDeleted(*((CParentIntfc*)this));
        }
    }
    iChildrenList.Close();
}
コード例 #2
0
MatchExpression::ExpressionOptimizerFunc ListOfMatchExpression::getOptimizer() const {
    return [](std::unique_ptr<MatchExpression> expression) -> std::unique_ptr<MatchExpression> {
        auto& children = static_cast<ListOfMatchExpression&>(*expression)._expressions;

        // Recursively apply optimizations to child expressions.
        for (auto& childExpression : children) {
            // Since 'childExpression' is a reference to a member of the ListOfMatchExpression's
            // child array, this assignment replaces the original child with the optimized child.
            // We must set this child's entry in '_expressions' to null after assigning ownership to
            // 'childExpressionPtr'. Otherwise, if the call to optimize() throws we will attempt to
            // free twice.
            std::unique_ptr<MatchExpression> childExpressionPtr(childExpression);
            childExpression = nullptr;

            auto optimizedExpression = MatchExpression::optimize(std::move(childExpressionPtr));
            childExpression = optimizedExpression.release();
        }

        // Associativity of AND and OR: an AND absorbs the children of any ANDs among its children
        // (and likewise for any OR with OR children).
        MatchType matchType = expression->matchType();
        if (matchType == AND || matchType == OR) {
            std::vector<MatchExpression*> absorbedExpressions;
            for (MatchExpression*& childExpression : children) {
                if (childExpression->matchType() == matchType) {
                    // Move this child out of the children array.
                    std::unique_ptr<ListOfMatchExpression> childExpressionPtr(
                        static_cast<ListOfMatchExpression*>(childExpression));
                    childExpression = nullptr;  // Null out this child's entry in _expressions, so
                                                // that it will be deleted by the erase call below.

                    // Move all of the grandchildren from the child expression to
                    // absorbedExpressions.
                    auto& grandChildren = childExpressionPtr->_expressions;
                    absorbedExpressions.insert(
                        absorbedExpressions.end(), grandChildren.begin(), grandChildren.end());
                    grandChildren.clear();

                    // Note that 'childExpressionPtr' will now be destroyed.
                }
            }

            // We replaced each destroyed child expression with nullptr. Now we remove those
            // nullptrs from the array.
            children.erase(std::remove(children.begin(), children.end(), nullptr), children.end());

            // Append the absorbed children to the end of the array.
            children.insert(children.end(), absorbedExpressions.begin(), absorbedExpressions.end());
        }

        // Remove all children of AND that are $alwaysTrue and all children of OR that are
        // $alwaysFalse.
        if (matchType == AND || matchType == OR) {
            for (MatchExpression*& childExpression : children) {
                if ((childExpression->isTriviallyTrue() && matchType == MatchExpression::AND) ||
                    (childExpression->isTriviallyFalse() && matchType == MatchExpression::OR)) {
                    std::unique_ptr<MatchExpression> childPtr(childExpression);
                    childExpression = nullptr;
                }
            }

            // We replaced each destroyed child expression with nullptr. Now we remove those
            // nullptrs from the vector.
            children.erase(std::remove(children.begin(), children.end(), nullptr), children.end());
        }

        // Check if the above optimizations eliminated all children. An OR with no children is
        // always false.
        // TODO SERVER-34759 It is correct to replace this empty AND with an $alwaysTrue, but we
        // need to make enhancements to the planner to make it understand an $alwaysTrue and an
        // empty AND as the same thing. The planner can create inferior plans for $alwaysTrue which
        // it would not produce for an AND with no children.
        if (children.empty() && matchType == MatchExpression::OR) {
            return stdx::make_unique<AlwaysFalseMatchExpression>();
        }

        if (children.size() == 1) {
            if ((matchType == AND || matchType == OR || matchType == INTERNAL_SCHEMA_XOR)) {
                // Simplify AND/OR/XOR with exactly one operand to an expression consisting of just
                // that operand.
                MatchExpression* simplifiedExpression = children.front();
                children.clear();
                return std::unique_ptr<MatchExpression>(simplifiedExpression);
            } else if (matchType == NOR) {
                // Simplify NOR of exactly one operand to NOT of that operand.
                auto simplifiedExpression = stdx::make_unique<NotMatchExpression>(children.front());
                children.clear();
                return std::move(simplifiedExpression);
            }
        }

        if (matchType == MatchExpression::AND || matchType == MatchExpression::OR) {
            for (auto& childExpression : children) {
                // An AND containing an expression that always evaluates to false can be
                // optimized to a single $alwaysFalse expression.
                if (childExpression->isTriviallyFalse() && matchType == MatchExpression::AND) {
                    return stdx::make_unique<AlwaysFalseMatchExpression>();
                }

                // Likewise, an OR containing an expression that always evaluates to true can be
                // optimized to a single $alwaysTrue expression.
                if (childExpression->isTriviallyTrue() && matchType == MatchExpression::OR) {
                    return stdx::make_unique<AlwaysTrueMatchExpression>();
                }
            }
        }

        return expression;
    };
}