int BinaryTree<DataType>::insert(const DataType &data) { // insert new data if (insert(root, data) != OK) return(NOTOK); #ifdef MUTABLE_ITERATOR // check if any iterators are traversing this tree if ( ! iterList.isEmpty()) { // now update any iterators ListIterator<AbstractIterator<DataType> * > piter(iterList); for ( ; ! piter.done(); piter++) { // save current iterator AbstractIterator<DataType> *paiter = piter(); // get current value DataType current = (*paiter)(); // update iterator (*paiter).resetByValue(current); } } #endif return(OK); }
// Form a trace of the async stack starting with the currently running // generator, if any. For now we just toss in the function name and // id, as well as the pseudo-frames for context breaks at explicit // joins. Later we'll add more, like file and line, hopefully function // args, wait handle status, etc. Array createAsyncStacktrace() { Array trace; auto currentWaitHandle = f_asio_get_running(); if (currentWaitHandle.isNull()) return trace; Array depStack = objToWaitableWaitHandle(currentWaitHandle)->t_getdependencystack(); for (ArrayIter iter(depStack); iter; ++iter) { if (iter.secondRef().isNull()) { trace.append(ArrayInit(0).toVariant()); } else { auto wh = objToWaitableWaitHandle(iter.secondRef().toObject()); auto parents = wh->t_getparents(); Array ancestors; for (ArrayIter piter(parents); piter; ++piter) { // Note: the parent list contains no nulls. auto parent = objToWaitableWaitHandle(piter.secondRef().toObject()); ancestors.append(parent->t_getname()); } Array frameData; frameData.set(s_function, wh->t_getname(), true); frameData.set(s_id, wh->t_getid(), true); frameData.set(s_ancestors, ancestors, true); // Continuation wait handles may have a source location to add. auto contWh = dynamic_cast<c_AsyncFunctionWaitHandle*>(wh); if (contWh != nullptr) addContinuationLocation(frameData, *contWh); trace.append(frameData); } } return trace; }
// Form a trace of the async stack starting with the currently running // generator, if any. For now we just toss in the function name and // id, as well as the pseudo-frames for context breaks at explicit // joins. Later we'll add more, like file and line, hopefully function // args, wait handle status, etc. static Array createAsyncStacktrace() { Array trace; auto currentWaitHandle = HHVM_FN(asio_get_running)(); if (currentWaitHandle.isNull()) return trace; Array depStack = objToWaitableWaitHandle(currentWaitHandle)->t_getdependencystack(); for (ArrayIter iter(depStack); iter; ++iter) { if (iter.secondRef().isNull()) { trace.append(Array(staticEmptyArray())); } else { auto wh = objToWaitableWaitHandle(iter.secondRef().toObject()); auto parents = wh->t_getparents(); Array ancestors; for (ArrayIter piter(parents); piter; ++piter) { // Note: the parent list contains no nulls. auto parent = objToWaitableWaitHandle(piter.secondRef().toObject()); ancestors.append(parent->t_getname()); } Array frameData; frameData.set(s_function, wh->t_getname(), true); frameData.set(s_id, wh->t_getid(), true); frameData.set(s_ancestors, ancestors, true); // Async function wait handles may have a source location to add. if (wh->getKind() == c_WaitHandle::Kind::AsyncFunction) { auto afwh = static_cast<c_AsyncFunctionWaitHandle*>(wh); addAsyncFunctionLocation(frameData, *afwh); } trace.append(frameData); } } return trace; }
int BinaryTree<DataType>::remove(DataType &data) { #ifdef MUTABLE_ITERATOR // check if any iterators are traversing this tree int status; if (iterList.isEmpty()) return(remove(root, data)); else { ListIterator<AbstractIterator<DataType> * > piter(iterList); for ( ; ! piter.done(); piter++) { // save current iterator AbstractIterator<DataType> *paiter = piter(); // check of iterator is done if ((*paiter).done()) continue; // check if iterator is pointing to deleted node if (data == (*paiter)()) (*paiter)++; } // delete element int status = remove(root, data); if (status != OK) return(status); // reset all iterators for (piter.reset(); ! piter.done(); piter++) { // save current iterator AbstractIterator<DataType> *paiter = piter(); // get current value DataType current = (*paiter)(); // check if iterator is done if ( ! (*paiter).done()) (*paiter).resetByValue(current); } return(OK); } #else return(remove(root, data)); #endif }
void BinaryTree<DataType>::clear() { // clear binary tree clear(root); #ifdef MUTABLE_ITERATOR // reset all iterators ListIterator<AbstractIterator<DataType> * > piter(iterList); for ( ; ! piter.done(); piter++) { // current iterator AbstractIterator<DataType> *paiter = piter(); // reset iterator (*paiter).reset(); } #endif return; }
void PolygonView::slotApplyColor() { EM_CERR("Polygonview::slotApplyColor"); bool bVertex = false; // change selected vertex Q3ListViewItemIterator viter(p_VertexListView); for (; viter.current(); ++viter) { if (viter.current()->isSelected()) { bVertex = true; if (((ListItem*)viter.current())->getObjectType() == LISTITEM_VERTEX) { // Color * color = poly->getColor((*coloritem).second); // assert(color != NULL); // color->r = p_EditR->text().toFloat(); // color->g = p_EditG->text().toFloat(); // color->b = p_EditB->text().toFloat(); // color->a = p_EditA->text().toFloat(); EM_CERR("PolygonView::slotApplyColor vertex"); } } } // change selected polygon only if no vertex was selected Q3ListViewItemIterator piter(p_PolygonListView); for (; piter.current() && !bVertex; ++piter) { if (piter.current()->isSelected()) { if (((ListItem*)piter.current())->getObjectType() == LISTITEM_POLYGON) { Polygon3D * poly = (Polygon3D*)((ListItem*)piter.current())->getObject(); assert(poly != NULL); poly->setColor(p_EditR->text().toFloat(), p_EditG->text().toFloat(), p_EditB->text().toFloat(), p_EditA->text().toFloat()); EM_CERR("PolygonView::slotApplyColor polygon"); } } } p_Doc->updateAll("polygon"); }
bool Grid::addShard( string* name , const ConnectionString& servers , long long maxSize , string& errMsg ) { // name can be NULL, so provide a dummy one here to avoid testing it elsewhere string nameInternal; if ( ! name ) { name = &nameInternal; } ReplicaSetMonitorPtr rsMonitor; // Check whether the host (or set) exists and run several sanity checks on this request. // There are two set of sanity checks: making sure adding this particular shard is consistent // with the replica set state (if it exists) and making sure this shards databases can be // brought into the grid without conflict. vector<string> dbNames; try { ScopedDbConnection newShardConn(servers.toString()); newShardConn->getLastError(); if ( newShardConn->type() == ConnectionString::SYNC ) { newShardConn.done(); errMsg = "can't use sync cluster as a shard. for replica set, have to use <setname>/<server1>,<server2>,..."; return false; } BSONObj resIsMongos; bool ok = newShardConn->runCommand( "admin" , BSON( "isdbgrid" << 1 ) , resIsMongos ); // should return ok=0, cmd not found if it's a normal mongod if ( ok ) { errMsg = "can't add a mongos process as a shard"; newShardConn.done(); return false; } BSONObj resIsMaster; ok = newShardConn->runCommand( "admin" , BSON( "isMaster" << 1 ) , resIsMaster ); if ( !ok ) { ostringstream ss; ss << "failed running isMaster: " << resIsMaster; errMsg = ss.str(); newShardConn.done(); return false; } // if the shard has only one host, make sure it is not part of a replica set string setName = resIsMaster["setName"].str(); string commandSetName = servers.getSetName(); if ( commandSetName.empty() && ! setName.empty() ) { ostringstream ss; ss << "host is part of set " << setName << ", use replica set url format <setname>/<server1>,<server2>,...."; errMsg = ss.str(); newShardConn.done(); return false; } if ( !commandSetName.empty() && setName.empty() ) { ostringstream ss; ss << "host did not return a set name, is the replica set still initializing? " << resIsMaster; errMsg = ss.str(); newShardConn.done(); return false; } // if the shard is part of replica set, make sure it is the right one if ( ! commandSetName.empty() && ( commandSetName != setName ) ) { ostringstream ss; ss << "host is part of a different set: " << setName; errMsg = ss.str(); newShardConn.done(); return false; } if( setName.empty() ) { // check this isn't a --configsvr BSONObj res; bool ok = newShardConn->runCommand("admin",BSON("replSetGetStatus"<<1),res); ostringstream ss; if( !ok && res["info"].type() == String && res["info"].String() == "configsvr" ) { errMsg = "the specified mongod is a --configsvr and should thus not be a shard server"; newShardConn.done(); return false; } } // if the shard is part of a replica set, make sure all the hosts mentioned in 'servers' are part of // the set. It is fine if not all members of the set are present in 'servers'. bool foundAll = true; string offendingHost; if ( ! commandSetName.empty() ) { set<string> hostSet; BSONObjIterator iter( resIsMaster["hosts"].Obj() ); while ( iter.more() ) { hostSet.insert( iter.next().String() ); // host:port } if ( resIsMaster["passives"].isABSONObj() ) { BSONObjIterator piter( resIsMaster["passives"].Obj() ); while ( piter.more() ) { hostSet.insert( piter.next().String() ); // host:port } } if ( resIsMaster["arbiters"].isABSONObj() ) { BSONObjIterator piter( resIsMaster["arbiters"].Obj() ); while ( piter.more() ) { hostSet.insert( piter.next().String() ); // host:port } } vector<HostAndPort> hosts = servers.getServers(); for ( size_t i = 0 ; i < hosts.size() ; i++ ) { if (!hosts[i].hasPort()) { hosts[i].setPort(ServerGlobalParams::DefaultDBPort); } string host = hosts[i].toString(); // host:port if ( hostSet.find( host ) == hostSet.end() ) { offendingHost = host; foundAll = false; break; } } } if ( ! foundAll ) { ostringstream ss; ss << "in seed list " << servers.toString() << ", host " << offendingHost << " does not belong to replica set " << setName; errMsg = ss.str(); newShardConn.done(); return false; } // shard name defaults to the name of the replica set if ( name->empty() && ! setName.empty() ) *name = setName; // In order to be accepted as a new shard, that mongod must not have any database name that exists already // in any other shards. If that test passes, the new shard's databases are going to be entered as // non-sharded db's whose primary is the newly added shard. BSONObj resListDB; ok = newShardConn->runCommand( "admin" , BSON( "listDatabases" << 1 ) , resListDB ); if ( !ok ) { ostringstream ss; ss << "failed listing " << servers.toString() << "'s databases:" << resListDB; errMsg = ss.str(); newShardConn.done(); return false; } BSONObjIterator i( resListDB["databases"].Obj() ); while ( i.more() ) { BSONObj dbEntry = i.next().Obj(); const string& dbName = dbEntry["name"].String(); if ( _isSpecialLocalDB( dbName ) ) { // 'local', 'admin', and 'config' are system DBs and should be excluded here continue; } else { dbNames.push_back( dbName ); } } if ( newShardConn->type() == ConnectionString::SET ) rsMonitor = ReplicaSetMonitor::get( setName ); newShardConn.done(); } catch ( DBException& e ) { if ( servers.type() == ConnectionString::SET ) { ReplicaSetMonitor::remove( servers.getSetName() ); } ostringstream ss; ss << "couldn't connect to new shard "; ss << e.what(); errMsg = ss.str(); return false; } // check that none of the existing shard candidate's db's exist elsewhere for ( vector<string>::const_iterator it = dbNames.begin(); it != dbNames.end(); ++it ) { DBConfigPtr config = getDBConfig( *it , false ); if ( config.get() != NULL ) { ostringstream ss; ss << "can't add shard " << servers.toString() << " because a local database '" << *it; ss << "' exists in another " << config->getPrimary().toString(); errMsg = ss.str(); return false; } } // if a name for a shard wasn't provided, pick one. if ( name->empty() && ! _getNewShardName( name ) ) { errMsg = "error generating new shard name"; return false; } // build the ConfigDB shard document BSONObjBuilder b; b.append(ShardType::name(), *name); b.append(ShardType::host(), rsMonitor ? rsMonitor->getServerAddress() : servers.toString()); if (maxSize > 0) { b.append(ShardType::maxSize(), maxSize); } BSONObj shardDoc = b.obj(); { ScopedDbConnection conn(configServer.getPrimary().getConnString(), 30); // check whether the set of hosts (or single host) is not an already a known shard BSONObj old = conn->findOne(ShardType::ConfigNS, BSON(ShardType::host(servers.toString()))); if ( ! old.isEmpty() ) { errMsg = "host already used"; conn.done(); return false; } conn.done(); } log() << "going to add shard: " << shardDoc << endl; Status result = clusterInsert( ShardType::ConfigNS, shardDoc, WriteConcernOptions::AllConfigs, NULL ); if ( !result.isOK() ) { errMsg = result.reason(); log() << "error adding shard: " << shardDoc << " err: " << errMsg << endl; return false; } Shard::reloadShardInfo(); // add all databases of the new shard for ( vector<string>::const_iterator it = dbNames.begin(); it != dbNames.end(); ++it ) { DBConfigPtr config = getDBConfig( *it , true , *name ); if ( ! config ) { log() << "adding shard " << servers << " even though could not add database " << *it << endl; } } // Record in changelog BSONObjBuilder shardDetails; shardDetails.append("name", *name); shardDetails.append("host", servers.toString()); configServer.logChange("addShard", "", shardDetails.obj()); return true; }
StatusWith<ShardType> ShardingCatalogManager::_validateHostAsShard( OperationContext* opCtx, std::shared_ptr<RemoteCommandTargeter> targeter, const std::string* shardProposedName, const ConnectionString& connectionString) { auto swCommandResponse = _runCommandForAddShard( opCtx, targeter.get(), NamespaceString::kAdminDb, BSON("isMaster" << 1)); if (swCommandResponse.getStatus() == ErrorCodes::IncompatibleServerVersion) { return swCommandResponse.getStatus().withReason( str::stream() << "Cannot add " << connectionString.toString() << " as a shard because its binary version is not compatible with " "the cluster's featureCompatibilityVersion."); } else if (!swCommandResponse.isOK()) { return swCommandResponse.getStatus(); } // Check for a command response error auto resIsMasterStatus = std::move(swCommandResponse.getValue().commandStatus); if (!resIsMasterStatus.isOK()) { return resIsMasterStatus.withContext(str::stream() << "Error running isMaster against " << targeter->connectionString().toString()); } auto resIsMaster = std::move(swCommandResponse.getValue().response); // Fail if the node being added is a mongos. const std::string msg = resIsMaster.getStringField("msg"); if (msg == "isdbgrid") { return {ErrorCodes::IllegalOperation, "cannot add a mongos as a shard"}; } // Extract the maxWireVersion so we can verify that the node being added has a binary version // greater than or equal to the cluster's featureCompatibilityVersion. We expect an incompatible // binary node to be unable to communicate, returning an IncompatibleServerVersion error, // because of our internal wire version protocol. So we can safely invariant here that the node // is compatible. long long maxWireVersion; Status status = bsonExtractIntegerField(resIsMaster, "maxWireVersion", &maxWireVersion); if (!status.isOK()) { return status.withContext(str::stream() << "isMaster returned invalid 'maxWireVersion' " << "field when attempting to add " << connectionString.toString() << " as a shard"); } if (serverGlobalParams.featureCompatibility.getVersion() > ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo40) { // If the cluster's FCV is 4.2, or upgrading to / downgrading from, the node being added // must be a v4.2 binary. invariant(maxWireVersion == WireVersion::LATEST_WIRE_VERSION); } else { // If the cluster's FCV is 4.0, the node being added must be a v4.0 or v4.2 binary. invariant(serverGlobalParams.featureCompatibility.getVersion() == ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo40); invariant(maxWireVersion >= WireVersion::LATEST_WIRE_VERSION - 1); } // Check whether there is a master. If there isn't, the replica set may not have been // initiated. If the connection is a standalone, it will return true for isMaster. bool isMaster; status = bsonExtractBooleanField(resIsMaster, "ismaster", &isMaster); if (!status.isOK()) { return status.withContext(str::stream() << "isMaster returned invalid 'ismaster' " << "field when attempting to add " << connectionString.toString() << " as a shard"); } if (!isMaster) { return {ErrorCodes::NotMaster, str::stream() << connectionString.toString() << " does not have a master. If this is a replica set, ensure that it has a" << " healthy primary and that the set has been properly initiated."}; } const std::string providedSetName = connectionString.getSetName(); const std::string foundSetName = resIsMaster["setName"].str(); // Make sure the specified replica set name (if any) matches the actual shard's replica set if (providedSetName.empty() && !foundSetName.empty()) { return {ErrorCodes::OperationFailed, str::stream() << "host is part of set " << foundSetName << "; " << "use replica set url format " << "<setname>/<server1>,<server2>, ..."}; } if (!providedSetName.empty() && foundSetName.empty()) { return {ErrorCodes::OperationFailed, str::stream() << "host did not return a set name; " << "is the replica set still initializing? " << resIsMaster}; } // Make sure the set name specified in the connection string matches the one where its hosts // belong into if (!providedSetName.empty() && (providedSetName != foundSetName)) { return {ErrorCodes::OperationFailed, str::stream() << "the provided connection string (" << connectionString.toString() << ") does not match the actual set name " << foundSetName}; } // Is it a config server? if (resIsMaster.hasField("configsvr")) { return {ErrorCodes::OperationFailed, str::stream() << "Cannot add " << connectionString.toString() << " as a shard since it is a config server"}; } // If the shard is part of a replica set, make sure all the hosts mentioned in the connection // string are part of the set. It is fine if not all members of the set are mentioned in the // connection string, though. if (!providedSetName.empty()) { std::set<std::string> hostSet; BSONObjIterator iter(resIsMaster["hosts"].Obj()); while (iter.more()) { hostSet.insert(iter.next().String()); // host:port } if (resIsMaster["passives"].isABSONObj()) { BSONObjIterator piter(resIsMaster["passives"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } if (resIsMaster["arbiters"].isABSONObj()) { BSONObjIterator piter(resIsMaster["arbiters"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } for (const auto& hostEntry : connectionString.getServers()) { const auto& host = hostEntry.toString(); // host:port if (hostSet.find(host) == hostSet.end()) { return {ErrorCodes::OperationFailed, str::stream() << "in seed list " << connectionString.toString() << ", host " << host << " does not belong to replica set " << foundSetName << "; found " << resIsMaster.toString()}; } } } std::string actualShardName; if (shardProposedName) { actualShardName = *shardProposedName; } else if (!foundSetName.empty()) { // Default it to the name of the replica set actualShardName = foundSetName; } // Disallow adding shard replica set with name 'config' if (actualShardName == NamespaceString::kConfigDb) { return {ErrorCodes::BadValue, "use of shard replica set with name 'config' is not allowed"}; } // Retrieve the most up to date connection string that we know from the replica set monitor (if // this is a replica set shard, otherwise it will be the same value as connectionString). ConnectionString actualShardConnStr = targeter->connectionString(); ShardType shard; shard.setName(actualShardName); shard.setHost(actualShardConnStr.toString()); shard.setState(ShardType::ShardState::kShardAware); return shard; }
MStatus findTexturesPerPolygon::doIt( const MArgList& ) // // Description: // Find the texture files that apply to the color of each polygon of // a selected shape if the shape has its polygons organized into sets. // { // Get the selection and choose the first path on the selection list. // MStatus status; MDagPath path; MObject cmp; MSelectionList slist; MGlobal::getActiveSelectionList(slist); slist.getDagPath(0, path, cmp); // Have to make the path include the shape below it so that // we can determine if the underlying shape node is instanced. // By default, dag paths only include transform nodes. // path.extendToShape(); // If the shape is instanced then we need to determine which // instance this path refers to. // int instanceNum = 0; if (path.isInstanced()) instanceNum = path.instanceNumber(); // Get a list of all sets pertaining to the selected shape and the // members of those sets. // MFnMesh fnMesh(path); MObjectArray sets; MObjectArray comps; if (!fnMesh.getConnectedSetsAndMembers(instanceNum, sets, comps, true)) cerr << "ERROR: MFnMesh::getConnectedSetsAndMembers\n"; // Loop through all the sets. If the set is a polygonal set, find the // shader attached to the and print out the texture file name for the // set along with the polygons in the set. // for ( unsigned i=0; i<sets.length(); i++ ) { MObject set = sets[i]; MObject comp = comps[i]; MFnSet fnSet( set, &status ); if (status == MS::kFailure) { cerr << "ERROR: MFnSet::MFnSet\n"; continue; } // Make sure the set is a polygonal set. If not, continue. MItMeshPolygon piter(path, comp, &status); if ((status == MS::kFailure) || comp.isNull()) continue; // Find the texture that is applied to this set. First, get the // shading node connected to the set. Then, if there is an input // attribute called "color", search upstream from it for a texture // file node. // MObject shaderNode = findShader(set); if (shaderNode == MObject::kNullObj) continue; MPlug colorPlug = MFnDependencyNode(shaderNode).findPlug("color", &status); if (status == MS::kFailure) continue; MItDependencyGraph dgIt(colorPlug, MFn::kFileTexture, MItDependencyGraph::kUpstream, MItDependencyGraph::kBreadthFirst, MItDependencyGraph::kNodeLevel, &status); if (status == MS::kFailure) continue; dgIt.disablePruningOnFilter(); // If no texture file node was found, just continue. // if (dgIt.isDone()) continue; // Print out the texture node name and texture file that it references. // MObject textureNode = dgIt.thisNode(); MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName"); MString textureName; filenamePlug.getValue(textureName); cerr << "Set: " << fnSet.name() << endl; cerr << "Texture Node Name: " << MFnDependencyNode(textureNode).name() << endl; cerr << "Texture File Name: " << textureName.asChar() << endl; // Print out the set of polygons that are contained in the current set. // for ( ; !piter.isDone(); piter.next() ) cerr << " poly component: " << piter.index() << endl; } return MS::kSuccess; }
StatusWith<string> isValidShard(const string& name, const ConnectionString& shardConnectionString, ScopedDbConnection& conn) { if (conn->type() == ConnectionString::SYNC) { return Status(ErrorCodes::BadValue, "can't use sync cluster as a shard; for a replica set, " "you have to use <setname>/<server1>,<server2>,..."); } BSONObj resIsMongos; // (ok == 0) implies that it is a mongos if (conn->runCommand("admin", BSON("isdbgrid" << 1), resIsMongos)) { return Status(ErrorCodes::BadValue, "can't add a mongos process as a shard"); } BSONObj resIsMaster; if (!conn->runCommand("admin", BSON("isMaster" << 1), resIsMaster)) { return Status(ErrorCodes::OperationFailed, str::stream() << "failed running isMaster: " << resIsMaster); } // if the shard has only one host, make sure it is not part of a replica set string setName = resIsMaster["setName"].str(); string commandSetName = shardConnectionString.getSetName(); if (commandSetName.empty() && !setName.empty()) { return Status(ErrorCodes::BadValue, str::stream() << "host is part of set " << setName << "; " << "use replica set url format " << "<setname>/<server1>,<server2>, ..."); } if (!commandSetName.empty() && setName.empty()) { return Status(ErrorCodes::OperationFailed, str::stream() << "host did not return a set name; " << "is the replica set still initializing? " << resIsMaster); } // if the shard is part of replica set, make sure it is the right one if (!commandSetName.empty() && (commandSetName != setName)) { return Status(ErrorCodes::OperationFailed, str::stream() << "host is part of a different set: " << setName); } if (setName.empty()) { // check this isn't a --configsvr BSONObj res; bool ok = conn->runCommand("admin", BSON("replSetGetStatus" << 1), res); if(!ok && res["info"].type() == String && res["info"].String() == "configsvr") { return Status(ErrorCodes::BadValue, "the specified mongod is a --configsvr and " "should thus not be a shard server"); } } // if the shard is part of a replica set, // make sure all the hosts mentioned in 'shardConnectionString' are part of // the set. It is fine if not all members of the set are present in 'shardConnectionString'. bool foundAll = true; string offendingHost; if (!commandSetName.empty()) { set<string> hostSet; BSONObjIterator iter(resIsMaster["hosts"].Obj()); while (iter.more()) { hostSet.insert(iter.next().String()); // host:port } if (resIsMaster["passives"].isABSONObj()) { BSONObjIterator piter(resIsMaster["passives"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } if (resIsMaster["arbiters"].isABSONObj()) { BSONObjIterator piter(resIsMaster["arbiters"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } vector<HostAndPort> hosts = shardConnectionString.getServers(); for (size_t i = 0; i < hosts.size(); i++) { if (!hosts[i].hasPort()) { hosts[i] = HostAndPort(hosts[i].host(), hosts[i].port()); } string host = hosts[i].toString(); // host:port if (hostSet.find(host) == hostSet.end()) { offendingHost = host; foundAll = false; break; } } } if (!foundAll) { return Status(ErrorCodes::OperationFailed, str::stream() << "in seed list " << shardConnectionString.toString() << ", host " << offendingHost << " does not belong to replica set " << setName); } string shardName(name); // shard name defaults to the name of the replica set if (name.empty() && !setName.empty()) { shardName = setName; } // disallow adding shard replica set with name 'config' if (shardName == "config") { return Status(ErrorCodes::BadValue, "use of shard replica set with name 'config' is not allowed"); } return shardName; }
bool CXRayObjectExport::initializeSetsAndLookupTables( bool exportAll ) // // Description : // Creates a list of all sets in Maya, a list of mesh objects, // and polygon/vertex lookup tables that will be used to // determine which sets are referenced by the poly components. // { int i=0,j=0, length; MStatus stat; // Initialize class data. // Note: we cannot do this in the constructor as it // only gets called upon registry of the plug-in. // numSets = 0; sets = NULL; lastSets = NULL; lastMaterials = NULL; objectId = 0; objectCount = 0; polygonTable = NULL; vertexTable = NULL; polygonTablePtr = NULL; vertexTablePtr = NULL; objectGroupsTablePtr = NULL; objectNodeNamesArray.clear(); transformNodeNameArray.clear(); ////////////////////////////////////////////////////////////////// // // Find all sets in Maya and store the ones we care about in // the 'sets' array. Also make note of the number of sets. // ////////////////////////////////////////////////////////////////// // Get all of the sets in maya and put them into // a selection list // MStringArray result; MGlobal::executeCommand( "ls -sets", result ); MSelectionList * setList = new MSelectionList(); length = result.length(); for ( i=0; i<length; i++ ) { setList->add( result[i] ); } // Extract each set as an MObject and add them to the // sets array. // We may be excluding groups, matierials, or ptGroups // in which case we can ignore those sets. // MObject mset; sets = new MObjectArray(); length = setList->length(); for ( i=0; i<length; i++ ) { setList->getDependNode( i, mset ); MFnSet fnSet( mset, &stat ); if ( stat ) { if ( MFnSet::kRenderableOnly == fnSet.restriction(&stat) ) { sets->append( mset ); } } } xr_delete(setList); numSets = sets->length(); ////////////////////////////////////////////////////////////////// // // Do a dag-iteration and for every mesh found, create facet and // vertex look-up tables. These tables will keep track of which // sets each component belongs to. // // If exportAll is false then iterate over the activeSelection // list instead of the entire DAG. // // These arrays have a corrisponding entry in the name // stringArray. // ////////////////////////////////////////////////////////////////// MIntArray vertexCounts; MIntArray polygonCounts; if ( exportAll ) { MItDag dagIterator( MItDag::kBreadthFirst, MFn::kInvalid, &stat); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in DAG iterator setup.\n"); return false; } objectNames = new MStringArray(); for ( ; !dagIterator.isDone(); dagIterator.next() ) { MDagPath dagPath; stat = dagIterator.getPath( dagPath ); if ( stat ) { // skip over intermediate objects // MFnDagNode dagNode( dagPath, &stat ); if (dagNode.isIntermediateObject()) { continue; } if (( dagPath.hasFn(MFn::kMesh)) && ( dagPath.hasFn(MFn::kTransform))) { // We want only the shape, // not the transform-extended-to-shape. continue; } else if ( dagPath.hasFn(MFn::kMesh)) { // We have a mesh so create a vertex and polygon table // for this object. // MFnMesh fnMesh( dagPath ); int vtxCount = fnMesh.numVertices(); int polygonCount = fnMesh.numPolygons(); // we do not need this call anymore, we have the shape. // dagPath.extendToShape(); MString name = dagPath.fullPathName(); objectNames->append( name ); objectNodeNamesArray.append( fnMesh.name() ); vertexCounts.append( vtxCount ); polygonCounts.append( polygonCount ); objectCount++; } } } }else{ MSelectionList slist; MGlobal::getActiveSelectionList( slist ); MItSelectionList iter( slist ); MStatus status; objectNames = new MStringArray(); // We will need to interate over a selected node's heirarchy // in the case where shapes are grouped, and the group is selected. MItDag dagIterator( MItDag::kDepthFirst, MFn::kInvalid, &status); for ( ; !iter.isDone(); iter.next() ){ MDagPath objectPath; stat = iter.getDagPath( objectPath ); // reset iterator's root node to be the selected node. status = dagIterator.reset (objectPath.node(), MItDag::kDepthFirst, MFn::kInvalid ); // DAG iteration beginning at at selected node for ( ; !dagIterator.isDone(); dagIterator.next() ){ MDagPath dagPath; MObject component = MObject::kNullObj; status = dagIterator.getPath(dagPath); if (!status){ fprintf(stderr,"Failure getting DAG path.\n"); freeLookupTables(); return false; } // skip over intermediate objects // MFnDagNode dagNode( dagPath, &stat ); if (dagNode.isIntermediateObject()) continue; if (( dagPath.hasFn(MFn::kMesh)) && ( dagPath.hasFn(MFn::kTransform))){ // We want only the shape, // not the transform-extended-to-shape. continue; }else if ( dagPath.hasFn(MFn::kMesh)){ // We have a mesh so create a vertex and polygon table // for this object. // MFnMesh fnMesh( dagPath ); int vtxCount = fnMesh.numVertices(); int polygonCount = fnMesh.numPolygons(); // we do not need this call anymore, we have the shape. // dagPath.extendToShape(); MString name = dagPath.fullPathName(); objectNames->append( name ); objectNodeNamesArray.append( fnMesh.name() ); vertexCounts.append( vtxCount ); polygonCounts.append( polygonCount ); objectCount++; } } } } // Now we know how many objects we are dealing with // and we have counts of the vertices/polygons for each // object so create the maya group look-up table. // if( objectCount > 0 ) { // To export Maya groups we traverse the hierarchy starting at // each objectNodeNamesArray[i] going towards the root collecting transform // nodes as we go. length = objectNodeNamesArray.length(); for( i=0; i<length; i++ ) { MIntArray transformNodeNameIndicesArray; recFindTransformDAGNodes( objectNodeNamesArray[i], transformNodeNameIndicesArray ); } if( transformNodeNameArray.length() > 0 ) { objectGroupsTablePtr = xr_alloc<bool*>(objectCount);// (bool**) malloc( sizeof(bool*)*objectCount ); length = transformNodeNameArray.length(); for ( i=0; i<objectCount; i++ ) { // objectGroupsTablePtr[i] = (bool*)calloc( length, sizeof(bool) ); objectGroupsTablePtr[i] = xr_alloc<bool>(length); ZeroMemory(objectGroupsTablePtr[i],length*sizeof(bool)); // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there if ( objectGroupsTablePtr[i] == NULL ) { Log("! calloc returned NULL (objectGroupsTablePtr)"); return false; } } } // else{ // Log("! Can't find transform for node."); // return false; // } } // Create the vertex/polygon look-up tables. // if ( objectCount > 0 ) { vertexTablePtr = xr_alloc<bool*>(objectCount); //(bool**) malloc( sizeof(bool*)*objectCount ); polygonTablePtr = xr_alloc<bool*>(objectCount); //(bool**) malloc( sizeof(bool*)*objectCount ); for ( i=0; i<objectCount; i++ ) { // vertexTablePtr[i] = (bool*)calloc( vertexCounts[i]*numSets, sizeof(bool) ); vertexTablePtr[i] = xr_alloc<bool>(vertexCounts[i]*numSets); ZeroMemory(vertexTablePtr[i],vertexCounts[i]*numSets*sizeof(bool)); // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there if ( vertexTablePtr[i] == NULL ) { Log("! calloc returned NULL (vertexTable)"); return false; } // polygonTablePtr[i] = (bool*)calloc( polygonCounts[i]*numSets, sizeof(bool) ); polygonTablePtr[i] = xr_alloc<bool>(polygonCounts[i]*numSets); ZeroMemory(polygonTablePtr[i],polygonCounts[i]*numSets*sizeof(bool)); // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there if ( polygonTablePtr[i] == NULL ) { Log("! calloc returned NULL (polygonTable)"); return false; } } } // If we found no meshes then return // if ( objectCount == 0 ) { return false; } ////////////////////////////////////////////////////////////////// // // Go through all of the set members (flattened lists) and mark // in the lookup-tables, the sets that each mesh component belongs // to. // // ////////////////////////////////////////////////////////////////// bool flattenedList = true; MDagPath object; MObject component; MSelectionList memberList; for ( i=0; i<numSets; i++ ) { MFnSet fnSet( (*sets)[i] ); memberList.clear(); stat = fnSet.getMembers( memberList, flattenedList ); if (MS::kSuccess != stat) { fprintf(stderr,"Error in fnSet.getMembers()!\n"); } int m, numMembers; numMembers = memberList.length(); for ( m=0; m<numMembers; m++ ) { if ( memberList.getDagPath(m,object,component) ) { if ( (!component.isNull()) && (object.apiType() == MFn::kMesh) ) { if (component.apiType() == MFn::kMeshVertComponent) { MItMeshVertex viter( object, component ); for ( ; !viter.isDone(); viter.next() ) { int compIdx = viter.index(); MString name = object.fullPathName(); // Figure out which object vertexTable // to get. // int o, numObjectNames; numObjectNames = objectNames->length(); for ( o=0; o<numObjectNames; o++ ) { if ( (*objectNames)[o] == name ) { // Mark set i as true in the table // vertexTable = vertexTablePtr[o]; *(vertexTable + numSets*compIdx + i) = true; break; } } } } else if (component.apiType() == MFn::kMeshPolygonComponent) { MItMeshPolygon piter( object, component ); for ( ; !piter.isDone(); piter.next() ) { int compIdx = piter.index(); MString name = object.fullPathName(); // Figure out which object polygonTable // to get. // int o, numObjectNames; numObjectNames = objectNames->length(); for ( o=0; o<numObjectNames; o++ ) { if ( (*objectNames)[o] == name ) { // Mark set i as true in the table // // Check for bad components in the set // if ( compIdx >= polygonCounts[o] ) { Msg("! Bad polygon index '%d' found. Polygon skipped",compIdx); break; } polygonTable = polygonTablePtr[o]; *(polygonTable + numSets*compIdx + i) = true; break; } } } } } else { // There are no components, therefore we can mark // all polygons as members of the given set. // if (object.hasFn(MFn::kMesh)) { MFnMesh fnMesh( object, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MFnMesh initialization.\n"); return false; } // We are going to iterate over all the polygons. // MItMeshPolygon piter( object, MObject::kNullObj, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr, "Failure in MItMeshPolygon initialization.\n"); return false; } for ( ; !piter.isDone(); piter.next() ) { int compIdx = piter.index(); MString name = object.fullPathName(); // Figure out which object polygonTable to get. // int o, numObjectNames; numObjectNames = objectNames->length(); for ( o=0; o<numObjectNames; o++ ) { if ( (*objectNames)[o] == name ) { // Check for bad components in the set // if ( compIdx >= polygonCounts[o] ) { Msg("! Bad polygon index '%d' found. Polygon skipped",compIdx); break; } // Mark set i as true in the table // polygonTable = polygonTablePtr[o]; *(polygonTable + numSets*compIdx + i) = true; break; } } } // end of piter.next() loop } // end of condition if (object.hasFn(MFn::kMesh)) } // end of else condifion if (!component.isNull()) } // end of memberList.getDagPath(m,object,component) } // end of memberList loop } // end of for-loop for sets // Go through all of the group members and mark in the // lookup-table, the group that each shape belongs to. length = objectNodeNamesArray.length(); if (objectGroupsTablePtr){ for( i=0; i<length; i++ ) { MIntArray groupTableIndicesArray; bool *objectGroupTable = objectGroupsTablePtr[i]; int length2; recFindTransformDAGNodes( objectNodeNamesArray[i], groupTableIndicesArray ); length2 = groupTableIndicesArray.length(); for( j=0; j<length2; j++ ) { int groupIdx = groupTableIndicesArray[j]; objectGroupTable[groupIdx] = true; } } } return true; }
StatusWith<ShardType> ShardingCatalogManagerImpl::_validateHostAsShard( OperationContext* txn, std::shared_ptr<RemoteCommandTargeter> targeter, const std::string* shardProposedName, const ConnectionString& connectionString) { // Check whether any host in the connection is already part of the cluster. Grid::get(txn)->shardRegistry()->reload(txn); for (const auto& hostAndPort : connectionString.getServers()) { std::shared_ptr<Shard> shard; shard = Grid::get(txn)->shardRegistry()->getShardNoReload(hostAndPort.toString()); if (shard) { return {ErrorCodes::OperationFailed, str::stream() << "'" << hostAndPort.toString() << "' " << "is already a member of the existing shard '" << shard->getConnString().toString() << "' (" << shard->getId() << ")."}; } } // Check for mongos and older version mongod connections, and whether the hosts // can be found for the user specified replset. auto swCommandResponse = _runCommandForAddShard(txn, targeter.get(), "admin", BSON("isMaster" << 1)); if (!swCommandResponse.isOK()) { if (swCommandResponse.getStatus() == ErrorCodes::RPCProtocolNegotiationFailed) { // Mongos to mongos commands are no longer supported in the wire protocol // (because mongos does not support OP_COMMAND), similarly for a new mongos // and an old mongod. So the call will fail in such cases. // TODO: If/When mongos ever supports opCommands, this logic will break because // cmdStatus will be OK. return {ErrorCodes::RPCProtocolNegotiationFailed, str::stream() << targeter->connectionString().toString() << " does not recognize the RPC protocol being used. This is" << " likely because it contains a node that is a mongos or an old" << " version of mongod."}; } else { return swCommandResponse.getStatus(); } } // Check for a command response error auto resIsMasterStatus = std::move(swCommandResponse.getValue().commandStatus); if (!resIsMasterStatus.isOK()) { return {resIsMasterStatus.code(), str::stream() << "Error running isMaster against " << targeter->connectionString().toString() << ": " << causedBy(resIsMasterStatus)}; } auto resIsMaster = std::move(swCommandResponse.getValue().response); // Check whether there is a master. If there isn't, the replica set may not have been // initiated. If the connection is a standalone, it will return true for isMaster. bool isMaster; Status status = bsonExtractBooleanField(resIsMaster, "ismaster", &isMaster); if (!status.isOK()) { return Status(status.code(), str::stream() << "isMaster returned invalid 'ismaster' " << "field when attempting to add " << connectionString.toString() << " as a shard: " << status.reason()); } if (!isMaster) { return {ErrorCodes::NotMaster, str::stream() << connectionString.toString() << " does not have a master. If this is a replica set, ensure that it has a" << " healthy primary and that the set has been properly initiated."}; } const string providedSetName = connectionString.getSetName(); const string foundSetName = resIsMaster["setName"].str(); // Make sure the specified replica set name (if any) matches the actual shard's replica set if (providedSetName.empty() && !foundSetName.empty()) { return {ErrorCodes::OperationFailed, str::stream() << "host is part of set " << foundSetName << "; " << "use replica set url format " << "<setname>/<server1>,<server2>, ..."}; } if (!providedSetName.empty() && foundSetName.empty()) { return {ErrorCodes::OperationFailed, str::stream() << "host did not return a set name; " << "is the replica set still initializing? " << resIsMaster}; } // Make sure the set name specified in the connection string matches the one where its hosts // belong into if (!providedSetName.empty() && (providedSetName != foundSetName)) { return {ErrorCodes::OperationFailed, str::stream() << "the provided connection string (" << connectionString.toString() << ") does not match the actual set name " << foundSetName}; } // Is it a config server? if (resIsMaster.hasField("configsvr")) { return {ErrorCodes::OperationFailed, str::stream() << "Cannot add " << connectionString.toString() << " as a shard since it is a config server"}; } // If the shard is part of a replica set, make sure all the hosts mentioned in the connection // string are part of the set. It is fine if not all members of the set are mentioned in the // connection string, though. if (!providedSetName.empty()) { std::set<string> hostSet; BSONObjIterator iter(resIsMaster["hosts"].Obj()); while (iter.more()) { hostSet.insert(iter.next().String()); // host:port } if (resIsMaster["passives"].isABSONObj()) { BSONObjIterator piter(resIsMaster["passives"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } if (resIsMaster["arbiters"].isABSONObj()) { BSONObjIterator piter(resIsMaster["arbiters"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } vector<HostAndPort> hosts = connectionString.getServers(); for (size_t i = 0; i < hosts.size(); i++) { const string host = hosts[i].toString(); // host:port if (hostSet.find(host) == hostSet.end()) { return {ErrorCodes::OperationFailed, str::stream() << "in seed list " << connectionString.toString() << ", host " << host << " does not belong to replica set " << foundSetName << "; found " << resIsMaster.toString()}; } } } string actualShardName; if (shardProposedName) { actualShardName = *shardProposedName; } else if (!foundSetName.empty()) { // Default it to the name of the replica set actualShardName = foundSetName; } // Disallow adding shard replica set with name 'config' if (actualShardName == "config") { return {ErrorCodes::BadValue, "use of shard replica set with name 'config' is not allowed"}; } // Retrieve the most up to date connection string that we know from the replica set monitor (if // this is a replica set shard, otherwise it will be the same value as connectionString). ConnectionString actualShardConnStr = targeter->connectionString(); ShardType shard; shard.setName(actualShardName); shard.setHost(actualShardConnStr.toString()); return shard; }
void sampling(std::shared_ptr<Mesh<Vertex, Polygon>> mesh, double sample_rate) { std::map<std::pair<std::shared_ptr<Vertex>, std::shared_ptr<Vertex>>, std::vector<std::shared_ptr<Vertex>>> vertex_vertex_interior_vertices_map; for (Mesh<Vertex, Polygon>::PolygonIterator piter(mesh); !piter.end(); ++piter) { auto p = *piter; auto he_vec = generate_halfedges(p); for (auto he : he_vec) { auto s = he->source(); auto t = he->target(); auto vpair = std::make_pair(t, s); if (vertex_vertex_interior_vertices_map.find(vpair) != vertex_vertex_interior_vertices_map.end()) { //we have got it! auto& vec = vertex_vertex_interior_vertices_map[vpair]; //from rbegin(); auto existing_v = s; for (int i = vec.size() - 1; i >= 0; --i) { p->add_vertex_after(existing_v, vec[i]); existing_v = vec[i]; } } else { double length = (s->point() - t->point()).norm(); int steps = length / sample_rate; std::vector<std::shared_ptr<Vertex>> vertex_vec; for (int i = 1; i < steps; ++i) { auto pt = t->point() * i / (double)steps + s->point() * (1.0 - i / (double)steps); auto new_v = std::make_shared<Vertex>(mesh->next_vertex_id(), pt); mesh->add_vertex(new_v); vertex_vec.push_back(new_v); } std::swap(vpair.first, vpair.second); vertex_vertex_interior_vertices_map[vpair] = vertex_vec; //add to polygon auto existing_v = s; for (int i = 0; i < vertex_vec.size(); ++i) { p->add_vertex_after(existing_v, vertex_vec[i]); existing_v = vertex_vec[i]; } } } } }
//-***************************************************************************** Abc::Box3d PolyMesh::writeSample( const Abc::OSampleSelector &iSS ) { // First, call base class sample write, which will return bounds // of any children. Abc::index_t sampleIndex = iSS.getIndex(); Abc::Box3d bounds = Exportable::writeSample( iSS ); // If we're not deforming, don't bother with new sample. // Do calculate bounds and set them, though. if ( sampleIndex != 0 && !m_deforming ) { bounds.extendBy( m_firstSampleSelfBounds ); m_boundsProperty.set( bounds, iSS ); return bounds; } // Make a mesh MStatus status; MFnMesh mesh( m_dagPath, &status ); CHECK_MAYA_STATUS; mesh.updateSurface(); mesh.syncObject(); // Make a sample. Abc::OPolyMeshSchema::Sample abcPolyMeshSample; //-************************************************************************* // WRITE VERTICES //-************************************************************************* MPointArray vertices; mesh.getPoints( vertices ); size_t npoints = vertices.length(); std::vector<Abc::V3f> v3fVerts( npoints ); Abc::Box3d shapeBounds; shapeBounds.makeEmpty(); for ( size_t i = 0; i < npoints; ++i ) { const MPoint &vi = vertices[i]; Abc::V3f pi( vi.x, vi.y, vi.z ); v3fVerts[i] = pi; shapeBounds.extendBy( Abc::V3d( vi.x, vi.y, vi.z ) ); } if ( sampleIndex == 0 ) { m_firstSampleSelfBounds = shapeBounds; } bounds.extendBy( shapeBounds ); // Set the bounds sample. m_boundsProperty.set( bounds, iSS ); // Stuff the positions into the mesh sample. abcPolyMeshSample.setPositions( Abc::V3fArraySample( v3fVerts ) ); //-************************************************************************* // OTHER STUFF, FOR FIRST OR LATER VERTICES //-************************************************************************* std::vector<Abc::int32_t> abcIndices; std::vector<Abc::int32_t> abcCounts; std::vector<Abc::N3f> abcNormals; std::vector<Abc::V2f> abcUvs; //-************************************************************************* // GET MESH NORMALS & UVS //-************************************************************************* size_t nnormals = mesh.numNormals(); MFloatVectorArray meshNorms; if ( nnormals > 0 ) { mesh.getNormals( meshNorms, MSpace::kObject ); } size_t nuvs = mesh.numUVs(); MFloatArray meshU; MFloatArray meshV; if ( nuvs > 0 ) { mesh.getUVs( meshU, meshV ); } //-************************************************************************* // LOOP OVER FIRST OR SUBSEQUENT SAMPLES //-************************************************************************* if ( sampleIndex == 0 ) { // FIRST SAMPLE // Loop over polys. size_t npolys = mesh.numPolygons(); abcCounts.resize( npolys ); Abc::int32_t faceIndex = 0; Abc::int32_t faceStartVertexIndex = 0; for ( MItMeshPolygon piter( m_dagPath ); !piter.isDone(); piter.next(), ++faceIndex ) { Abc::int32_t faceCount = piter.polygonVertexCount(); abcCounts[faceIndex] = faceCount; faceStartVertexIndex += faceCount; for ( Abc::int32_t faceVertex = 0; faceVertex < faceCount; ++faceVertex ) { abcIndices.push_back( piter.vertexIndex( faceVertex ) ); if ( nnormals > 0 ) { size_t normIndex = piter.normalIndex( faceVertex ); const MFloatVector &norm = meshNorms[normIndex]; Abc::N3f abcNorm( norm[0], norm[1], norm[2] ); abcNormals.push_back( abcNorm ); } if ( nuvs > 0 ) { int uvIndex = 0; piter.getUVIndex( faceVertex, uvIndex ); Abc::V2f abcUv( meshU[uvIndex], meshV[uvIndex] ); abcUvs.push_back( abcUv ); } } } // We have now collected abcIndices, abcStarts, abcNormals, and abcUvs. // Put them into the sample. abcPolyMeshSample.setIndices( Abc::Int32ArraySample( abcIndices ) ); abcPolyMeshSample.setCounts( Abc::Int32ArraySample( abcCounts ) ); if ( nnormals > 0 && m_normals ) { m_normals.set( Abc::N3fArraySample( abcNormals ), iSS ); } if ( nuvs > 0 && m_sts ) { m_sts.set( Abc::V2fArraySample( abcUvs ), iSS ); } } else if ( ( nnormals > 0 && m_normals ) || ( nuvs > 0 && m_sts ) ) { // SUBSEQUENT SAMPLES // Just gathering normals and uvs. // (vertices handled above) // Loop over polys. Abc::int32_t faceIndex = 0; Abc::int32_t faceStartVertexIndex = 0; for ( MItMeshPolygon piter( m_dagPath ); !piter.isDone(); piter.next(), ++faceIndex ) { Abc::int32_t faceCount = piter.polygonVertexCount(); for ( Abc::int32_t faceVertex = 0; faceVertex < faceCount; ++faceVertex ) { if ( nnormals > 0 ) { size_t normIndex = piter.normalIndex( faceVertex ); const MFloatVector &norm = meshNorms[normIndex]; Abc::N3f abcNorm( norm[0], norm[1], norm[2] ); abcNormals.push_back( abcNorm ); } if ( nuvs > 0 ) { int uvIndex = 0; piter.getUVIndex( faceVertex, uvIndex ); Abc::V2f abcUv( meshU[uvIndex], meshV[uvIndex] ); abcUvs.push_back( abcUv ); } } } // We have now collected abcNormals, and abcUvs. // Put them into the sample. if ( nnormals > 0 && m_normals ) { m_normals.set( Abc::N3fArraySample( abcNormals ), iSS ); } if ( nuvs > 0 ) { m_sts.set( Abc::V2fArraySample( abcUvs ), iSS ); } } // Set the mesh sample. m_polyMesh.getSchema().set( abcPolyMeshSample, iSS ); return bounds; }
StatusWith<ShardType> ShardingCatalogManagerImpl::_validateHostAsShard( OperationContext* opCtx, std::shared_ptr<RemoteCommandTargeter> targeter, const std::string* shardProposedName, const ConnectionString& connectionString) { // Check if the node being added is a mongos or a version of mongod too old to speak the current // communication protocol. auto swCommandResponse = _runCommandForAddShard(opCtx, targeter.get(), "admin", BSON("isMaster" << 1)); if (!swCommandResponse.isOK()) { if (swCommandResponse.getStatus() == ErrorCodes::RPCProtocolNegotiationFailed) { // Mongos to mongos commands are no longer supported in the wire protocol // (because mongos does not support OP_COMMAND), similarly for a new mongos // and an old mongod. So the call will fail in such cases. // TODO: If/When mongos ever supports opCommands, this logic will break because // cmdStatus will be OK. return {ErrorCodes::RPCProtocolNegotiationFailed, str::stream() << targeter->connectionString().toString() << " does not recognize the RPC protocol being used. This is" << " likely because it contains a node that is a mongos or an old" << " version of mongod."}; } else { return swCommandResponse.getStatus(); } } // Check for a command response error auto resIsMasterStatus = std::move(swCommandResponse.getValue().commandStatus); if (!resIsMasterStatus.isOK()) { return {resIsMasterStatus.code(), str::stream() << "Error running isMaster against " << targeter->connectionString().toString() << ": " << causedBy(resIsMasterStatus)}; } auto resIsMaster = std::move(swCommandResponse.getValue().response); // Check that the node being added is a new enough version. // If we're running this code, that means the mongos that the addShard request originated from // must be at least version 3.4 (since 3.2 mongoses don't know about the _configsvrAddShard // command). Since it is illegal to have v3.4 mongoses with v3.2 shards, we should reject // adding any shards that are not v3.4. We can determine this by checking that the // maxWireVersion reported in isMaster is at least COMMANDS_ACCEPT_WRITE_CONCERN. // TODO(SERVER-25623): This approach won't work to prevent v3.6 mongoses from adding v3.4 // shards, so we'll have to rethink this during the 3.5 development cycle. long long maxWireVersion; Status status = bsonExtractIntegerField(resIsMaster, "maxWireVersion", &maxWireVersion); if (!status.isOK()) { return Status(status.code(), str::stream() << "isMaster returned invalid 'maxWireVersion' " << "field when attempting to add " << connectionString.toString() << " as a shard: " << status.reason()); } if (maxWireVersion < WireVersion::COMMANDS_ACCEPT_WRITE_CONCERN) { return Status(ErrorCodes::IncompatibleServerVersion, str::stream() << "Cannot add " << connectionString.toString() << " as a shard because we detected a mongod with server " "version older than 3.4.0. It is invalid to add v3.2 and " "older shards through a v3.4 mongos."); } // Check whether there is a master. If there isn't, the replica set may not have been // initiated. If the connection is a standalone, it will return true for isMaster. bool isMaster; status = bsonExtractBooleanField(resIsMaster, "ismaster", &isMaster); if (!status.isOK()) { return Status(status.code(), str::stream() << "isMaster returned invalid 'ismaster' " << "field when attempting to add " << connectionString.toString() << " as a shard: " << status.reason()); } if (!isMaster) { return {ErrorCodes::NotMaster, str::stream() << connectionString.toString() << " does not have a master. If this is a replica set, ensure that it has a" << " healthy primary and that the set has been properly initiated."}; } const std::string providedSetName = connectionString.getSetName(); const std::string foundSetName = resIsMaster["setName"].str(); // Make sure the specified replica set name (if any) matches the actual shard's replica set if (providedSetName.empty() && !foundSetName.empty()) { return {ErrorCodes::OperationFailed, str::stream() << "host is part of set " << foundSetName << "; " << "use replica set url format " << "<setname>/<server1>,<server2>, ..."}; } if (!providedSetName.empty() && foundSetName.empty()) { return {ErrorCodes::OperationFailed, str::stream() << "host did not return a set name; " << "is the replica set still initializing? " << resIsMaster}; } // Make sure the set name specified in the connection string matches the one where its hosts // belong into if (!providedSetName.empty() && (providedSetName != foundSetName)) { return {ErrorCodes::OperationFailed, str::stream() << "the provided connection string (" << connectionString.toString() << ") does not match the actual set name " << foundSetName}; } // Is it a config server? if (resIsMaster.hasField("configsvr")) { return {ErrorCodes::OperationFailed, str::stream() << "Cannot add " << connectionString.toString() << " as a shard since it is a config server"}; } // If the shard is part of a replica set, make sure all the hosts mentioned in the connection // string are part of the set. It is fine if not all members of the set are mentioned in the // connection string, though. if (!providedSetName.empty()) { std::set<std::string> hostSet; BSONObjIterator iter(resIsMaster["hosts"].Obj()); while (iter.more()) { hostSet.insert(iter.next().String()); // host:port } if (resIsMaster["passives"].isABSONObj()) { BSONObjIterator piter(resIsMaster["passives"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } if (resIsMaster["arbiters"].isABSONObj()) { BSONObjIterator piter(resIsMaster["arbiters"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } for (const auto& hostEntry : connectionString.getServers()) { const auto& host = hostEntry.toString(); // host:port if (hostSet.find(host) == hostSet.end()) { return {ErrorCodes::OperationFailed, str::stream() << "in seed list " << connectionString.toString() << ", host " << host << " does not belong to replica set " << foundSetName << "; found " << resIsMaster.toString()}; } } } std::string actualShardName; if (shardProposedName) { actualShardName = *shardProposedName; } else if (!foundSetName.empty()) { // Default it to the name of the replica set actualShardName = foundSetName; } // Disallow adding shard replica set with name 'config' if (actualShardName == NamespaceString::kConfigDb) { return {ErrorCodes::BadValue, "use of shard replica set with name 'config' is not allowed"}; } // Retrieve the most up to date connection string that we know from the replica set monitor (if // this is a replica set shard, otherwise it will be the same value as connectionString). ConnectionString actualShardConnStr = targeter->connectionString(); ShardType shard; shard.setName(actualShardName); shard.setHost(actualShardConnStr.toString()); shard.setState(ShardType::ShardState::kShardAware); return shard; }