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; } } }
void DisplayObjectContainer::releaseChildAt( const int index ) { if ( index < 0 || index >= (int)entityVec_.size() ) { assert( false && "invalid index" ); return; } DisplayObjectBase* obj = entityVec_[index]; releaseChild( obj ); }
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); }