IResourceManager::GroupWeakPtr IResourceManager::CreateGroup(xst_castring& strName) { // Check for existing GroupHandle Handle = XSE_HASH( strName ); if( m_LastUsedGroupHandle == Handle ) { XST_LOG_ERR( "Group with name: " << strName << " already exists" ); return GroupWeakPtr(); } ResGroupMapItr Itr; XST::MapUtils::FindPlace( m_mGroups, Handle, &Itr ); if( Itr != m_mGroups.end() ) // group exists { XST_LOG_ERR( "Group with name: " << strName << " already exists" ); return GroupWeakPtr(); } GroupPtr pGroup( _CreateGroup( strName, Handle ) ); if( !pGroup ) { XST_LOG_ERR( "Unable to allocate memory for resource group: " << strName ); return GroupWeakPtr(); } XST::MapUtils::InsertOnPlace( m_mGroups, Handle, pGroup, Itr ); m_LastUsedGroupHandle = Handle; m_pLastUsedGroup = pGroup; return m_pLastUsedGroup; }
IResourceManager::GroupWeakPtr IResourceManager::GetOrCreateGroup(xst_castring& strName) { GroupHandle Handle = XSE_HASH( strName ); if( m_LastUsedGroupHandle == Handle && m_pLastUsedGroup.IsValid() ) return m_pLastUsedGroup; m_LastUsedGroupHandle = Handle; ResGroupMapItr Itr; if( !XST::MapUtils::FindPlace( m_mGroups, Handle, &Itr ) ) // if resource exists { m_pLastUsedGroup = Itr->second; // Return already found group pointer return m_pLastUsedGroup; } GroupPtr pGroup( _CreateGroup( strName, Handle ) ); if( pGroup.IsNull() ) { XST_LOG_ERR( "Unable to allocate memory for resource group: " << strName ); return GroupWeakPtr(); } //XST::MapUtils::InsertOnPlace( m_mGroups, Handle, pGroup, Itr ); m_mGroups.insert( Itr, ResGroupMap::value_type( Handle, pGroup ) ); m_pLastUsedGroup = pGroup; m_LastUsedGroupHandle = Handle; return m_pLastUsedGroup; }
void EmitterState::StartedGroup(GroupType::value type) { StartedNode(); const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.back()->indent); m_curIndent += lastGroupIndent; // TODO: Create move constructors for settings types to simplify transfer std::unique_ptr<Group> pGroup(new Group(type)); // transfer settings (which last until this group is done) // // NB: if pGroup->modifiedSettings == m_modifiedSettings, // m_modifiedSettings is not changed! pGroup->modifiedSettings = std::move(m_modifiedSettings); // set up group if (GetFlowType(type) == Block) { pGroup->flowType = FlowType::Block; } else { pGroup->flowType = FlowType::Flow; } pGroup->indent = GetIndent(); m_groups.push_back(std::move(pGroup)); }
std::unique_ptr <EmitterState::Group> EmitterState::_PopGroup() { if(m_groups.empty()) return std::unique_ptr <Group> (nullptr); std::unique_ptr <Group> pGroup(m_groups.top()); m_groups.pop(); return pGroup; }
ScriptGroup* ScriptRegistry::getOrMakeGroup(const char* group) { ScriptGroup* pGroup( getGroup(group) ); if(!pGroup) { pGroup = new ScriptGroup(group); m_groups.push_back(pGroup); } return pGroup; }
IResourceManager::GroupPtr IResourceManager::RemoveGroup(const GroupHandle& Handle) { ResGroupMapItr Itr = m_mGroups.find( Handle ); if( Itr == m_mGroups.end() ) { return GroupPtr(); } GroupPtr pGroup( Itr->second ); m_mGroups.erase( Itr ); return pGroup; }
bool C4Extra::InitGroup() { // register extra root into game group set for(const auto & iter : Reloc) { std::unique_ptr<C4Group> pGroup(new C4Group); if(pGroup->Open( (iter.strBuf + DirSep + C4CFN_Extra).getData())) ExtraGroups.emplace_back(std::move(pGroup)); } // done, success return true; }
bool C4Extra::InitGroup() { // register extra root into game group set for(C4Reloc::iterator iter = Reloc.begin(); iter != Reloc.end(); ++iter) { std::unique_ptr<C4Group> pGroup(new C4Group); if(pGroup->Open( ((*iter).strBuf + DirSep + C4CFN_Extra).getData())) ExtraGroups.emplace_back(std::move(pGroup)); } // done, success return true; }
void EmitterState::BeginGroup(GROUP_TYPE type) { unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top()->indent); m_curIndent += lastIndent; std::unique_ptr <Group> pGroup(new Group(type)); // transfer settings (which last until this group is done) pGroup->modifiedSettings = m_modifiedSettings; // set up group pGroup->flow = GetFlowType(type); pGroup->indent = GetIndent(); pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false); m_groups.push(pGroup.release()); }
intrusive_ptr<DocumentSource> DocumentSourceGroup::createFromBson( BSONElement elem, const intrusive_ptr<ExpressionContext>& pExpCtx) { uassert(15947, "a group's fields must be specified in an object", elem.type() == Object); intrusive_ptr<DocumentSourceGroup> pGroup(DocumentSourceGroup::create(pExpCtx)); BSONObj groupObj(elem.Obj()); BSONObjIterator groupIterator(groupObj); VariablesIdGenerator idGenerator; VariablesParseState vps(&idGenerator); while (groupIterator.more()) { BSONElement groupField(groupIterator.next()); const char* pFieldName = groupField.fieldName(); if (str::equals(pFieldName, "_id")) { uassert( 15948, "a group's _id may only be specified once", pGroup->_idExpressions.empty()); pGroup->parseIdExpression(groupField, vps); invariant(!pGroup->_idExpressions.empty()); } else if (str::equals(pFieldName, "$doingMerge")) { massert(17030, "$doingMerge should be true if present", groupField.Bool()); pGroup->setDoingMerge(true); } else { /* Treat as a projection field with the additional ability to add aggregation operators. */ auto parsedAccumulator = Accumulator::parseAccumulator(groupField, vps); auto fieldName = parsedAccumulator.first.toString(); auto accExpression = parsedAccumulator.second; auto factory = Accumulator::getFactory(groupField.embeddedObject().firstElementFieldName()); pGroup->addAccumulator(fieldName, factory, accExpression); } } uassert(15955, "a group specification must include an _id", !pGroup->_idExpressions.empty()); pGroup->_variables.reset(new Variables(idGenerator.getIdCount())); return pGroup; }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ GroupModel::pFutureGroup_type GroupModel::createGroup(Common::I_Session& _session, const std::string& _name, const std::string& _description) { /// TODO Check session (i.e. session user) against permissions. /// TODO Make this async pFutureGroup_type returnValue(new FutureGroup_type); // Get the data map. Community::Account::I_GroupDataMap::pGroupDataMap_type pGroupDM = Community::Account::I_GroupDataMap::create( m_service.getApplicationServer().getDatabaseConnection( m_service.getDatabaseConnectionName() ) ); // Create a new domain object. Community::Account::I_GroupDataMap::pGroupDomainObject_type pGroupDO = pGroupDM->createNew(); // Populate the values. pGroupDO->getGroupName() = _name; pGroupDO->getGroupDescription() = _description; // Update the object (and in this case, insert it). boost::uint64_t newGroupId = pGroupDM->update(pGroupDO)->getValue(); pGroupDO->getGroupId() = newGroupId; Group* pRawGroup = new Group(m_service, pGroupDO); pGroup_type pGroup( pRawGroup, &destroyGroup ); m_groups[_name] = pGroup; onAddGroup(pGroup); returnValue->setValue(pGroup); return returnValue; }
intrusive_ptr<DocumentSource> DocumentSourceGroup::createFromBson( BSONElement *pBsonElement, const intrusive_ptr<ExpressionContext> &pCtx) { uassert(15947, "a group's fields must be specified in an object", pBsonElement->type() == Object); intrusive_ptr<DocumentSourceGroup> pGroup( DocumentSourceGroup::create(pCtx)); bool idSet = false; BSONObj groupObj(pBsonElement->Obj()); BSONObjIterator groupIterator(groupObj); while(groupIterator.more()) { BSONElement groupField(groupIterator.next()); const char *pFieldName = groupField.fieldName(); if (strcmp(pFieldName, Document::idName.c_str()) == 0) { uassert(15948, "a group's _id may only be specified once", !idSet); BSONType groupType = groupField.type(); if (groupType == Object) { /* Use the projection-like set of field paths to create the group-by key. */ Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); intrusive_ptr<Expression> pId( Expression::parseObject(&groupField, &oCtx)); pGroup->setIdExpression(pId); idSet = true; } else if (groupType == String) { string groupString(groupField.String()); const char *pGroupString = groupString.c_str(); if ((groupString.length() == 0) || (pGroupString[0] != '$')) goto StringConstantId; string pathString( Expression::removeFieldPrefix(groupString)); intrusive_ptr<ExpressionFieldPath> pFieldPath( ExpressionFieldPath::create(pathString)); pGroup->setIdExpression(pFieldPath); idSet = true; } else { /* pick out the constant types that are allowed */ switch(groupType) { case NumberDouble: case String: case Object: case Array: case jstOID: case Bool: case Date: case NumberInt: case Timestamp: case NumberLong: case jstNULL: StringConstantId: // from string case above { intrusive_ptr<const Value> pValue( Value::createFromBsonElement(&groupField)); intrusive_ptr<ExpressionConstant> pConstant( ExpressionConstant::create(pValue)); pGroup->setIdExpression(pConstant); idSet = true; break; } default: uassert(15949, str::stream() << "a group's _id may not include fields of BSON type " << groupType, false); } } } else { /* Treat as a projection field with the additional ability to add aggregation operators. */ uassert(15950, str::stream() << "the group aggregate field name " << *pFieldName << " cannot be an operator name", *pFieldName != '$'); uassert(15951, str::stream() << "the group aggregate field " << *pFieldName << "must be defined as an expression inside an object", groupField.type() == Object); BSONObj subField(groupField.Obj()); BSONObjIterator subIterator(subField); size_t subCount = 0; for(; subIterator.more(); ++subCount) { BSONElement subElement(subIterator.next()); /* look for the specified operator */ GroupOpDesc key; key.pName = subElement.fieldName(); const GroupOpDesc *pOp = (const GroupOpDesc *)bsearch( &key, GroupOpTable, NGroupOp, sizeof(GroupOpDesc), GroupOpDescCmp); uassert(15952, str::stream() << "unknown group operator \"" << key.pName << "\"", pOp); intrusive_ptr<Expression> pGroupExpr; BSONType elementType = subElement.type(); if (elementType == Object) { Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); pGroupExpr = Expression::parseObject( &subElement, &oCtx); } else if (elementType == Array) { uassert(15953, str::stream() << "aggregating group operators are unary (" << key.pName << ")", false); } else { /* assume its an atomic single operand */ pGroupExpr = Expression::parseOperand(&subElement); } pGroup->addAccumulator( pFieldName, pOp->pFactory, pGroupExpr); } uassert(15954, str::stream() << "the computed aggregate \"" << pFieldName << "\" must specify exactly one operator", subCount == 1); } } uassert(15955, "a group specification must include an _id", idSet); return pGroup; }
intrusive_ptr<DocumentSource> DocumentSourceGroup::createFromBson( BSONElement elem, const intrusive_ptr<ExpressionContext> &pExpCtx) { uassert(15947, "a group's fields must be specified in an object", elem.type() == Object); intrusive_ptr<DocumentSourceGroup> pGroup( DocumentSourceGroup::create(pExpCtx)); BSONObj groupObj(elem.Obj()); BSONObjIterator groupIterator(groupObj); VariablesIdGenerator idGenerator; VariablesParseState vps(&idGenerator); while(groupIterator.more()) { BSONElement groupField(groupIterator.next()); const char *pFieldName = groupField.fieldName(); if (str::equals(pFieldName, "_id")) { uassert(15948, "a group's _id may only be specified once", pGroup->_idExpressions.empty()); pGroup->parseIdExpression(groupField, vps); invariant(!pGroup->_idExpressions.empty()); } else if (str::equals(pFieldName, "$doingMerge")) { massert(17030, "$doingMerge should be true if present", groupField.Bool()); pGroup->setDoingMerge(true); } else { /* Treat as a projection field with the additional ability to add aggregation operators. */ uassert(16414, str::stream() << "the group aggregate field name '" << pFieldName << "' cannot be used because $group's field names cannot contain '.'", !str::contains(pFieldName, '.') ); uassert(15950, str::stream() << "the group aggregate field name '" << pFieldName << "' cannot be an operator name", pFieldName[0] != '$'); uassert(15951, str::stream() << "the group aggregate field '" << pFieldName << "' must be defined as an expression inside an object", groupField.type() == Object); BSONObj subField(groupField.Obj()); BSONObjIterator subIterator(subField); size_t subCount = 0; for(; subIterator.more(); ++subCount) { BSONElement subElement(subIterator.next()); /* look for the specified operator */ GroupOpDesc key; key.name = subElement.fieldName(); const GroupOpDesc *pOp = (const GroupOpDesc *)bsearch( &key, GroupOpTable, NGroupOp, sizeof(GroupOpDesc), GroupOpDescCmp); uassert(15952, str::stream() << "unknown group operator '" << key.name << "'", pOp); intrusive_ptr<Expression> pGroupExpr; BSONType elementType = subElement.type(); if (elementType == Object) { Expression::ObjectCtx oCtx(Expression::ObjectCtx::DOCUMENT_OK); pGroupExpr = Expression::parseObject(subElement.Obj(), &oCtx, vps); } else if (elementType == Array) { uasserted(15953, str::stream() << "aggregating group operators are unary (" << key.name << ")"); } else { /* assume its an atomic single operand */ pGroupExpr = Expression::parseOperand(subElement, vps); } pGroup->addAccumulator(pFieldName, pOp->factory, pGroupExpr); } uassert(15954, str::stream() << "the computed aggregate '" << pFieldName << "' must specify exactly one operator", subCount == 1); } } uassert(15955, "a group specification must include an _id", !pGroup->_idExpressions.empty()); pGroup->_variables.reset(new Variables(idGenerator.getIdCount())); return pGroup; }
intrusive_ptr<DocumentSource> DocumentSourceGroup::createFromBson( BSONElement *pBsonElement, const intrusive_ptr<ExpressionContext> &pCtx) { assert(pBsonElement->type() == Object); // CW TODO must be an object intrusive_ptr<DocumentSourceGroup> pGroup( DocumentSourceGroup::create(pCtx)); bool idSet = false; BSONObj groupObj(pBsonElement->Obj()); BSONObjIterator groupIterator(groupObj); while(groupIterator.more()) { BSONElement groupField(groupIterator.next()); const char *pFieldName = groupField.fieldName(); if (strcmp(pFieldName, Document::idName.c_str()) == 0) { assert(!idSet); // CW TODO _id specified multiple times BSONType groupType = groupField.type(); if (groupType == Object) { /* Use the projection-like set of field paths to create the group-by key. */ Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); intrusive_ptr<Expression> pId( Expression::parseObject(&groupField, &oCtx)); pGroup->setIdExpression(pId); idSet = true; } else if (groupType == String) { string groupString(groupField.String()); const char *pGroupString = groupString.c_str(); if ((groupString.length() == 0) || (pGroupString[0] != '$')) goto StringConstantId; string pathString( Expression::removeFieldPrefix(groupString)); intrusive_ptr<ExpressionFieldPath> pFieldPath( ExpressionFieldPath::create(pathString)); pGroup->setIdExpression(pFieldPath); idSet = true; } else { /* pick out the constant types that are allowed */ switch(groupType) { case NumberDouble: case String: case Object: case Array: case jstOID: case Bool: case Date: case NumberInt: case Timestamp: case NumberLong: case jstNULL: StringConstantId: // from string case above { intrusive_ptr<const Value> pValue( Value::createFromBsonElement(&groupField)); intrusive_ptr<ExpressionConstant> pConstant( ExpressionConstant::create(pValue)); pGroup->setIdExpression(pConstant); idSet = true; break; } default: assert(false); // CW TODO disallowed constant group key } } } else { /* Treat as a projection field with the additional ability to add aggregation operators. */ assert(*pFieldName != '$'); // CW TODO error: field name can't be an operator assert(groupField.type() == Object); // CW TODO error: must be an operator expression BSONObj subField(groupField.Obj()); BSONObjIterator subIterator(subField); size_t subCount = 0; for(; subIterator.more(); ++subCount) { BSONElement subElement(subIterator.next()); /* look for the specified operator */ GroupOpDesc key; key.pName = subElement.fieldName(); const GroupOpDesc *pOp = (const GroupOpDesc *)bsearch( &key, GroupOpTable, NGroupOp, sizeof(GroupOpDesc), GroupOpDescCmp); assert(pOp); // CW TODO error: operator not found intrusive_ptr<Expression> pGroupExpr; BSONType elementType = subElement.type(); if (elementType == Object) { Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); pGroupExpr = Expression::parseObject( &subElement, &oCtx); } else if (elementType == Array) { assert(false); // CW TODO group operators are unary } else { /* assume its an atomic single operand */ pGroupExpr = Expression::parseOperand(&subElement); } pGroup->addAccumulator( pFieldName, pOp->pFactory, pGroupExpr); } assert(subCount == 1); // CW TODO error: only one operator allowed } } assert(idSet); // CW TODO error: missing _id specification return pGroup; }
intrusive_ptr<DocumentSource> DocumentSourceGroup::createFromBson( BSONElement *pBsonElement, const intrusive_ptr<ExpressionContext> &pExpCtx) { uassert(15947, "a group's fields must be specified in an object", pBsonElement->type() == Object); intrusive_ptr<DocumentSourceGroup> pGroup( DocumentSourceGroup::create(pExpCtx)); bool idSet = false; BSONObj groupObj(pBsonElement->Obj()); BSONObjIterator groupIterator(groupObj); while(groupIterator.more()) { BSONElement groupField(groupIterator.next()); const char *pFieldName = groupField.fieldName(); if (str::equals(pFieldName, "_id")) { uassert(15948, "a group's _id may only be specified once", !idSet); BSONType groupType = groupField.type(); if (groupType == Object) { /* Use the projection-like set of field paths to create the group-by key. */ Expression::ObjectCtx oCtx(Expression::ObjectCtx::DOCUMENT_OK); intrusive_ptr<Expression> pId( Expression::parseObject(&groupField, &oCtx)); pGroup->setIdExpression(pId); idSet = true; } else if (groupType == String) { const string groupString = groupField.str(); if (!groupString.empty() && groupString[0] == '$') { pGroup->setIdExpression(ExpressionFieldPath::parse(groupString)); idSet = true; } } if (!idSet) { // constant id - single group pGroup->setIdExpression(ExpressionConstant::create(Value(groupField))); idSet = true; } } else { /* Treat as a projection field with the additional ability to add aggregation operators. */ uassert(16414, str::stream() << "the group aggregate field name '" << pFieldName << "' cannot be used because $group's field names cannot contain '.'", !str::contains(pFieldName, '.') ); uassert(15950, str::stream() << "the group aggregate field name '" << pFieldName << "' cannot be an operator name", pFieldName[0] != '$'); uassert(15951, str::stream() << "the group aggregate field '" << pFieldName << "' must be defined as an expression inside an object", groupField.type() == Object); BSONObj subField(groupField.Obj()); BSONObjIterator subIterator(subField); size_t subCount = 0; for(; subIterator.more(); ++subCount) { BSONElement subElement(subIterator.next()); /* look for the specified operator */ GroupOpDesc key; key.name = subElement.fieldName(); const GroupOpDesc *pOp = (const GroupOpDesc *)bsearch( &key, GroupOpTable, NGroupOp, sizeof(GroupOpDesc), GroupOpDescCmp); uassert(15952, str::stream() << "unknown group operator '" << key.name << "'", pOp); intrusive_ptr<Expression> pGroupExpr; BSONType elementType = subElement.type(); if (elementType == Object) { Expression::ObjectCtx oCtx( Expression::ObjectCtx::DOCUMENT_OK); pGroupExpr = Expression::parseObject( &subElement, &oCtx); } else if (elementType == Array) { uasserted(15953, str::stream() << "aggregating group operators are unary (" << key.name << ")"); } else { /* assume its an atomic single operand */ pGroupExpr = Expression::parseOperand(&subElement); } pGroup->addAccumulator(pFieldName, pOp->factory, pGroupExpr); } uassert(15954, str::stream() << "the computed aggregate '" << pFieldName << "' must specify exactly one operator", subCount == 1); } } uassert(15955, "a group specification must include an _id", idSet); return pGroup; }