void DocumentSourceGroup::populate() { for(bool hasNext = !pSource->eof(); hasNext; hasNext = pSource->advance()) { intrusive_ptr<Document> pDocument(pSource->getCurrent()); /* get the _id document */ intrusive_ptr<const Value> pId(pIdExpression->evaluate(pDocument)); /* treat Undefined the same as NULL SERVER-4674 */ if (pId->getType() == Undefined) pId = Value::getNull(); /* Look for the _id value in the map; if it's not there, add a new entry with a blank accumulator. */ vector<intrusive_ptr<Accumulator> > *pGroup; GroupsType::iterator it(groups.find(pId)); if (it != groups.end()) { /* point at the existing accumulators */ pGroup = &it->second; } else { /* insert a new group into the map */ groups.insert(it, pair<intrusive_ptr<const Value>, vector<intrusive_ptr<Accumulator> > >( pId, vector<intrusive_ptr<Accumulator> >())); /* find the accumulator vector (the map value) */ it = groups.find(pId); pGroup = &it->second; /* add the accumulators */ const size_t n = vpAccumulatorFactory.size(); pGroup->reserve(n); for(size_t i = 0; i < n; ++i) { intrusive_ptr<Accumulator> pAccumulator( (*vpAccumulatorFactory[i])(pExpCtx)); pAccumulator->addOperand(vpExpression[i]); pGroup->push_back(pAccumulator); } } /* point at the existing key */ // unneeded atm // pId = it.first; /* tickle all the accumulators for the group we found */ const size_t n = pGroup->size(); for(size_t i = 0; i < n; ++i) (*pGroup)[i]->evaluate(pDocument); } /* start the group iterator */ groupsIterator = groups.begin(); if (groupsIterator != groups.end()) pCurrent = makeDocument(groupsIterator); populated = true; }
intrusive_ptr<Accumulator> AccumulatorFirst::create( const intrusive_ptr<ExpressionContext> &pCtx) { intrusive_ptr<AccumulatorFirst> pAccumulator( new AccumulatorFirst()); return pAccumulator; }
intrusive_ptr<Accumulator> AccumulatorPush::create( const intrusive_ptr<ExpressionContext> &pCtx) { intrusive_ptr<AccumulatorPush> pAccumulator( new AccumulatorPush(pCtx)); return pAccumulator; }
intrusive_ptr<Accumulator> AccumulatorMinMax::createMax( const intrusive_ptr<ExpressionContext> &pCtx) { intrusive_ptr<AccumulatorMinMax> pAccumulator( new AccumulatorMinMax(-1)); return pAccumulator; }
intrusive_ptr<Accumulator> AccumulatorAddToSet::create( const intrusive_ptr<ExpressionContext> &pCtx) { intrusive_ptr<AccumulatorAddToSet> pAccumulator( new AccumulatorAddToSet(pCtx)); return pAccumulator; }