Esempio n. 1
0
void Shell::doMove( Id orig, ObjId newParent )
{
	if ( orig == Id() ) {
		cout << "Error: Shell::doMove: Cannot move root Element\n";
		return;
	}

	if ( newParent.element() == 0 ) {
		cout << "Error: Shell::doMove: Cannot move object to null parent \n";
		return;
	}
	if ( Neutral::isDescendant( newParent, orig ) ) {
		cout << "Error: Shell::doMove: Cannot move object to descendant in tree\n";
		return;
		
	}
	const string& name = orig.element()->getName();
	if ( Neutral::child( newParent.eref(), name ) != Id() ) {
			stringstream ss;
			ss << "Shell::doMove: Object with same name already present: '"
			   	<< newParent.path() << "/" << name << "'. Move failed.";
			warning( ss.str() );
			return;
	}

	SetGet2< Id, ObjId >::set( ObjId(), "move", orig, newParent );
	// innerMove( orig, newParent );
}
Esempio n. 2
0
void Shell::destroy( const Eref& e, ObjId oid)
{
	Neutral *n = reinterpret_cast< Neutral* >( e.data() );
	assert( n );
	// cout << myNode_ << ": Shell::destroy done for element id: " << eid << ", name = " << eid.element()->getName() << endl;
	n->destroy( oid.eref(), 0 );
	if ( cwe_.id == oid.id )
		cwe_ = ObjId();
}
Esempio n. 3
0
/// non-static func. Returns the Id found by traversing the specified path.
ObjId Shell::doFind( const string& path ) const
{
	if ( path == "/" || path == "/root" )
		return ObjId();

	ObjId curr;
	vector< string > names;
	vector< unsigned int > indices;
	bool isAbsolute = chopPath( path, names, indices );
	assert( names.size() == indices.size() );

	if ( !isAbsolute )
		curr = cwe_;

	for ( unsigned int i = 0; i < names.size(); ++i ) {
		if ( names[i] == "." ) {
		} else if ( names[i] == ".." ) {
			curr = Neutral::parent( curr.eref() );
		} else {
			ObjId pa = curr;
			curr = Neutral::child( curr.eref(), names[i] );
			if ( curr == ObjId() ) // Neutral::child returned Id(), ie, bad.
				return ObjId( 0, BADINDEX );
			if ( curr.element()->hasFields() ) {
				curr.dataIndex = pa.dataIndex;
				curr.fieldIndex = indices[i];
			} else {
				curr.dataIndex = indices[i];
				if ( curr.element()->numData() <= curr.dataIndex  )
					return ObjId( 0, BADINDEX );
			}
		}
	}
	
	assert( curr.element() );
	if ( curr.element()->numData() <= curr.dataIndex )
		return ObjId( 0, BADINDEX );
	if ( curr.fieldIndex > 0 && !curr.element()->hasFields() )
		return ObjId( 0, BADINDEX );

	return curr;
}
Esempio n. 4
0
// static function
bool Neutral::isDescendant( Id me, Id ancestor )
{
	static const Finfo* pf = neutralCinfo->findFinfo( "parentMsg" );
	static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf );
	static const FuncId pafid = pf2->getFid();

	Eref e = me.eref();
	
	while ( e.element()->id() != Id() && e.element()->id() != ancestor ) {
		ObjId mid = e.element()->findCaller( pafid );
		assert( mid != ObjId() );
		ObjId fid = Msg::getMsg( mid )->findOtherEnd( e.objId() );
		e = fid.eref();
	}
	return ( e.element()->id() == ancestor );
}
Esempio n. 5
0
void Neutral::setName( const Eref& e, string name )
{
	if ( e.id().value() <= 3 ) {
		cout << "Warning: Neutral::setName on '" << e.id().path() << 
			   "'.Cannot rename core objects\n";
		return;
	}
	ObjId pa = parent( e );
	Id sibling = Neutral::child( pa.eref(), name );
	if ( sibling == Id() ) { // OK, no existing object with same name.
		e.element()->setName( name );
	} else {
		cout << "Warning: Neutral::setName: an object with the name '" <<
			name << "'\n already exists on the same parent. Not changed\n";
	}
}
Esempio n. 6
0
void NSDFWriter::writeModelTree()
{
    vector< string > tokens;
    ObjId mRoot(modelRoot_);
    string rootPath = MODELTREEPATH + string("/") + mRoot.element()->getName();
    hid_t rootGroup = require_group(filehandle_, rootPath);
    hid_t tmp;
    htri_t exists;
    herr_t status;
    deque<Id> nodeQueue;
    deque<hid_t> h5nodeQueue;
    nodeQueue.push_back(mRoot);
    h5nodeQueue.push_back(rootGroup);
    // TODO: need to clarify what happens with array elements. We can
    // have one node per vec and set a count field for the number of
    // elements
    while (nodeQueue.size() > 0){
        ObjId node = nodeQueue.front();
        nodeQueue.pop_front();
        hid_t prev = h5nodeQueue.front();;
        h5nodeQueue.pop_front();
        vector < Id > children;
        Neutral::children(node.eref(), children);
        for ( unsigned int ii = 0; ii < children.size(); ++ii){
            string name = children[ii].element()->getName();
            // skip the system elements
            if (children[ii].path() == "/Msgs"
                || children[ii].path() == "/clock"
                || children[ii].path() == "/classes"
                || children[ii].path() == "/postmaster"){
                continue;
            }
            exists = H5Lexists(prev, name.c_str(), H5P_DEFAULT);
            if (exists > 0){
                tmp = H5Gopen2(prev, name.c_str(), H5P_DEFAULT);
            } else {
                tmp = H5Gcreate2(prev, name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
            }
            writeScalarAttr< string >(tmp, "uid", children[ii].path());
            nodeQueue.push_back(children[ii]);
            h5nodeQueue.push_back(tmp);
        }
        status = H5Gclose(prev);
    }
}
Esempio n. 7
0
// Static function 
string Neutral::path( const Eref& e )
{
	static const Finfo* pf = neutralCinfo->findFinfo( "parentMsg" );
	static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf );
	static const FuncId pafid = pf2->getFid();

	vector< ObjId > pathVec;
	ObjId curr = e.objId();
	stringstream ss;

	pathVec.push_back( curr );
	while ( curr.id != Id() ) {
		ObjId mid = curr.eref().element()->findCaller( pafid );
		if ( mid == ObjId() ) {
			cout << "Error: Neutral::path:Cannot follow msg of ObjId: " <<
				   	e.objId() << " for func: " << pafid << endl;
			break;
		}
		curr = Msg::getMsg( mid )->findOtherEnd( curr );
		pathVec.push_back( curr );
	}
	if ( pathVec.size() <= 1 )
		return "/";
	for ( unsigned int i = 1; i < pathVec.size(); ++i ) {
		ss << "/";
		ObjId& oid = pathVec[ pathVec.size() - i - 1 ];
		ss << oid.element()->getName();
		if ( !oid.element()->hasFields() )
			ss << "[" << oid.dataIndex << "]";
		/*
		if ( !oid.element()->hasFields() )
			ss << "[" << oid.dataIndex << "]";
		if ( oid.element()->numData() > 1 )
			ss << "[" << oid.dataIndex << "]";
			*/
	}
	// Append braces if Eref was for a fieldElement. This should
	// work even if it is off-node.
	if ( e.element()->hasFields() ) {
		ss << "[" << e.fieldIndex() << "]";
	}

	return ss.str();
}
Esempio n. 8
0
bool Shell::innerMove( Id orig, ObjId newParent )
{
	static const Finfo* pf = Neutral::initCinfo()->findFinfo( "parentMsg" );
	static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf );
	static const FuncId pafid = pf2->getFid();
	static const Finfo* f1 = Neutral::initCinfo()->findFinfo( "childOut" );

	assert( !( orig == Id() ) );
	assert( !( newParent.element() == 0 ) );

	ObjId mid = orig.element()->findCaller( pafid );
	Msg::deleteMsg( mid );

	Msg* m = new OneToAllMsg( newParent.eref(), orig.element(), 0 );
	assert( m );
	if ( !f1->addMsg( pf, m->mid(), newParent.element() ) ) {
		cout << "move: Error: unable to add parent->child msg from " <<
			newParent.element()->getName() << " to " << 
			orig.element()->getName() << "\n";
		return 0;
	}
	return 1;
}
Esempio n. 9
0
/**
 * Static utility function. Attaches child element to parent element.
 * Must only be called from functions executing in parallel on all nodes,
 * as it does a local message addition
 * MsgIndex is needed to be sure that the same msg identifies parent-child
 * connection on all nodes.
 */
bool Shell::adopt( ObjId parent, Id child, unsigned int msgIndex ) {
	static const Finfo* pf = Neutral::initCinfo()->findFinfo( "parentMsg" );
	// static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf );
	// static const FuncId pafid = pf2->getFid();
	static const Finfo* f1 = Neutral::initCinfo()->findFinfo( "childOut" );

	assert( !( child.element() == 0 ) );
	assert( !( child == Id() ) );
	assert( !( parent.element() == 0 ) );

	Msg* m = new OneToAllMsg( parent.eref(), child.element(), msgIndex );
	assert( m );

	// cout << myNode_ << ", Shell::adopt: mid = " << m->mid() << ", pa =" << parent << "." << parent()->getName() << ", kid=" << child << "." << child()->getName() << "\n";

	if ( !f1->addMsg( pf, m->mid(), parent.element() ) ) {
		cout << "move: Error: unable to add parent->child msg from " <<
			parent.element()->getName() << " to " << 
			child.element()->getName() << "\n";
		return 0;
	}
	return 1;
}
Esempio n. 10
0
/**
 * This is the version used by the parser. Acts as a blocking,
 * serial-like interface to a potentially multithread, multinode call.
 * Returns the new Id index upon success, otherwise returns Id().
 * The data of the new Element is not necessarily allocated at this point,
 * that can be deferred till the global Instantiate or Reset calls.
 * Idea is that the model should be fully defined before load balancing.
 *
 */
Id Shell::doCreate( string type, ObjId parent, string name, 
				unsigned int numData, 
				NodePolicy nodePolicy,
				unsigned int preferredNode )
{
#ifdef ENABLE_LOGGER
    clock_t t = clock();
#endif
	const Cinfo* c = Cinfo::find( type );
	if ( !isNameValid( name ) ) {
		stringstream ss;
		ss << "Shell::doCreate: bad character in name'" << name << 
				"'. No Element created";
		warning( ss.str() );
		return Id();
	}

	if ( c ) {
		if ( c->banCreation() ) {
			stringstream ss;
			ss << "Shell::doCreate: Cannot create an object of class '" <<
				type << "' because it is an abstract base class or a FieldElement.\n";
			warning( ss.str() );
			return Id();
		}
		Element* pa = parent.element();
		if ( !pa ) {
			stringstream ss;
			ss << "Shell::doCreate: Parent Element'" << parent << "' not found. No Element created";
			warning( ss.str() );
			return Id();
		}
		if ( Neutral::child( parent.eref(), name ) != Id() ) {
			stringstream ss;
			ss << "Shell::doCreate: Object with same name already present: '"
				   	<< parent.path() << "/" << name << "'. No Element created";
			warning( ss.str() );
			return Id();
		}
		// Get the new Id ahead of time and pass to all nodes.
		Id ret = Id::nextId();
		NodeBalance nb( numData, nodePolicy, preferredNode );
		// Get the parent MsgIndex ahead of time and pass to all nodes.
		unsigned int parentMsgIndex = OneToAllMsg::numMsg();

		SetGet6< string, ObjId, Id, string, NodeBalance, unsigned int >::set(
			ObjId(), // Apply command to Shell
			"create",	// Function to call.
			type, 		// class of new object
			parent,		// Parent
			ret,		// id of new object
			name,		// name of new object
			nb,			// Node balance configuration
			parentMsgIndex	// Message index of child-parent msg.
		);
		// innerCreate( type, parent, ret, name, numData, isGlobal );

#ifdef ENABLE_LOGGER 
        logger.creationTime.push_back((float(clock() - t)/CLOCKS_PER_SEC));
#endif

		return ret;
	} else {
		stringstream ss;
		ss << "Shell::doCreate: Class '" << type << "' not known. No Element created";
		warning( ss.str() );
	}

#ifdef ENABLE_LOGGER 
        logger.creationTime.push_back((float(clock() - t)/CLOCKS_PER_SEC));
#endif
	return Id();
}