コード例 #1
0
std::pair<unique_ptr<MatchExpression>, unique_ptr<MatchExpression>> splitMatchExpressionBy(
    unique_ptr<MatchExpression> expr, const std::set<std::string>& fields) {
    if (isIndependentOf(*expr, fields)) {
        // 'expr' does not depend upon 'fields', so it can be completely moved.
        return {std::move(expr), nullptr};
    }
    if (!expr->isLogical()) {
        // 'expr' is a leaf, and was not independent of 'fields'.
        return {nullptr, std::move(expr)};
    }

    std::vector<unique_ptr<MatchExpression>> reliant;
    std::vector<unique_ptr<MatchExpression>> separate;

    switch (expr->matchType()) {
        case MatchExpression::AND: {
            auto andExpr = checked_cast<AndMatchExpression*>(expr.get());
            for (size_t i = 0; i < andExpr->numChildren(); i++) {
                auto children = splitMatchExpressionBy(andExpr->releaseChild(i), fields);

                invariant(children.first || children.second);

                if (children.first) {
                    separate.push_back(std::move(children.first));
                }
                if (children.second) {
                    reliant.push_back(std::move(children.second));
                }
            }
            return {createAndOfNodes(&separate), createAndOfNodes(&reliant)};
        }
        case MatchExpression::NOR: {
            // We can split a $nor because !(x | y) is logically equivalent to !x & !y.

            // However, we cannot split each child individually; instead, we must look for a wholly
            // independent child to split off by itself. As an example of why, with 'b' in
            // 'fields': $nor: [{$and: [{a: 1}, {b: 1}]}]} will match if a is not 1, or if b is not
            // 1. However, if we split this into: {$nor: [{$and: [{a: 1}]}]}, and
            // {$nor: [{$and: [{b: 1}]}]}, a document will only pass both stages if neither a nor b
            // is equal to 1.
            auto norExpr = checked_cast<NorMatchExpression*>(expr.get());
            for (size_t i = 0; i < norExpr->numChildren(); i++) {
                auto child = norExpr->releaseChild(i);
                if (isIndependentOf(*child, fields)) {
                    separate.push_back(std::move(child));
                } else {
                    reliant.push_back(std::move(child));
                }
            }
            return {createNorOfNodes(&separate), createNorOfNodes(&reliant)};
        }
        case MatchExpression::OR:
        case MatchExpression::NOT: {
            // If we aren't independent, we can't safely split.
            return {nullptr, std::move(expr)};
        }
        default: { MONGO_UNREACHABLE; }
    }
}
コード例 #2
0
void DisplayObjectContainer::releaseChildAt( const int index )
{
	if ( index < 0 || index >= (int)entityVec_.size() ) {
		assert( false && "invalid index" );
		return;
	}

	DisplayObjectBase* obj = entityVec_[index];
	releaseChild( obj );
}
コード例 #3
0
void DisplayObjectContainer::update(const double dt)
{	
	DisplayObjectVec::iterator iter = entityVec_.begin();

//	std::cout << "size: " << entityVec_.size() << std::endl;
	while (iter != entityVec_.end())
	{
		// check if needed to release
		if( (*iter)->needReleased() )
		{
			releaseChild(*iter);
			--iter;
			continue;
		}
//		std::cout << "update" << std::endl;
		(*iter)->update(dt);
		++iter;
	}
	
	DisplayObjectBase::update(dt);
}