inching forward on inverse attrs

This commit is contained in:
Mark Pictor 2014-12-21 21:25:59 -05:00
parent 31bf315543
commit 5df2f69930
7 changed files with 84 additions and 20 deletions

View file

@ -92,7 +92,16 @@ unsigned long lazyInstMgr::getNumTypes() const {
}
void lazyInstMgr::openFile( std::string fname ) {
_files.push_back( new lazyFileReader( fname, this, _files.size() ) );
//don't want to hold a lock for the entire time we're reading the file.
//create a place in the vector and remember its location, then free lock
///FIXME begin atomic op
size_t i = _files.size();
_files.push_back( (lazyFileReader * ) 0 );
///FIXME end atomic op
lazyFileReader * lfr = new lazyFileReader( fname, this, i );
_files[i] = lfr;
/// TODO resolve inverse attr references
//between instances, or eDesc --> inst????
}
SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id, bool reSeek ) {

View file

@ -47,6 +47,7 @@
// note - doing this well will require major changes, since each inst automatically loads every instance that it references
//TODO what about complex instances? scanning each on disk could be a bitch; should the compositional types be scanned during lazy loading?
//TODO/FIXME in generated code, store ia data in map and eliminate data members that are currently used. modify accessors to use map.
class lazyRefs {
public:
typedef std::set< instanceID > referentInstances_t;
@ -76,7 +77,7 @@ class lazyRefs {
potentialReferentInsts( edL );
//3d - load each inst
/*invAttrListNode * invNode*/
iAstruct * ias = invAttr( _inst, ia /*, iaList*/ );
iAstruct * ias = invAttr( _inst, ia );
referentInstances_t::iterator insts = _referentInstances.begin();
for( ; insts != _referentInstances.end(); ++insts ) {
loadInstIFFreferent( *insts, ias, ia );
@ -85,13 +86,21 @@ class lazyRefs {
}
void loadInstIFFreferent( instanceID inst, iAstruct * ias, const Inverse_attribute * ia ) {
std::cout << "liir for inst #" << _inst->STEPfile_id << ", referent #" << inst << ", ia " << ia->Name() << "(" << (void*) ia;
std::cout << "), ias " << (void *) ias << std::endl;
bool prevLoaded = _lim->isLoaded( inst );
SDAI_Application_instance * rinst = _lim->loadInstance( inst );
bool ref = refersToCurrentInst( ia, rinst );
if( ref ) {
if( ia->inverted_attr_()->IsAggrType() ) {
if( !ias->a ) {
ias->a = new EntityAggregate;
_inst->setInvAttr( ia, *ias );
assert( invAttr( _inst, ia )->a == ias->a );
}
EntityAggregate * ea = ias->a;
assert( ea && "is it possible for this to be null here? if so, must create & assign");
// assert( ias->a && "is it possible for this to be null here? if so, must create & assign");
//FIXME InitIAttrs has been called, but this is null. what to do? init here? if not, where???
//TODO check if duplicate
ea->AddNode( new EntityNode( rinst ) );
} else {
@ -183,12 +192,14 @@ END_ENTITY; -- 10303-42: geometry_schema
}
iai = map.begin();
//FIXME treat as unrecoverable?
//need to call inst->InitIAttrs();
std::cerr << "Error! inverse attr " << ia->Name() << " (" << ia << ") not found in iAMap for entity " << inst->getEDesc()->Name() << ". Map contents:" << std::endl;
for( ; iai != map.end(); ++iai ) {
std::cerr << iai->first->Name() << ": " << (void*)(iai->second.a) << ", ";
}
std::cerr << std::endl;
return NULL;
abort();
// // return NULL;
}
/** 3c. compare the type of each item in R with types in A

View file

@ -314,6 +314,7 @@ SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg
_file.unget();
sev = inst->STEPread( instance, 0, _lazyFile->getInstMgr()->getAdapter(), _file, sName, true, false );
//TODO do something with 'sev'
inst->InitIAttrs();
}
return inst;
}

View file

@ -88,6 +88,7 @@ void SDAI_Application_instance::InitIAttrs() {
superInvAttrIter siai( eDesc );
while( !siai.empty() ) {
ia = siai.next();
assert( ia );
iAMap.insert( iAMap_t::value_type( ia, s ) );
}
}
@ -923,30 +924,41 @@ int SDAI_Application_instance::AttributeCount() {
return attributes.list_length();
}
/// used in getInvAttr() and setInvAttr() to verify that the struct and attr are both entityAggregate or both not
bool validIAS( const Inverse_attribute * const ia, const iAstruct ias ) {
if( ( ias.a && ias.i ) || ( !ias.a && !ias.i ) ) {
return false;
}
// //TODO determine if ia should be an instance or an entityAggregate... how?!
// std::cerr << "TODO: implement " << __PRETTY_FUNCTION__ << "!" << std::endl;
if( ia->inverted_attr_()->IsAggrType() == ( ias.a != 0 ) ) {
return true;
}
return false;
}
// /// used in getInvAttr() and setInvAttr() to verify that the struct and attr are both entityAggregate or both not
// bool validIAS( const Inverse_attribute * const ia, const iAstruct ias ) {
// // //TODO determine if ia should be an instance or an entityAggregate... how?!
// //don't think IsAggrType() is the correct test...
// // std::cerr << "TODO: implement " << __PRETTY_FUNCTION__ << "!" << std::endl;
// if( ia->inverted_attr_()->IsAggrType() == ( dynamic_cast<EntityAggregate * const >( ias.a ) != 0 ) ) {
// return true;
// }
// return false;
// }
const iAstruct SDAI_Application_instance::getInvAttr( const Inverse_attribute * const ia ) const {
iAstruct ias;
iAMap_t::const_iterator it = iAMap.find( ia );
if( it != iAMap.end() ) {
ias = (*it).second;
assert( validIAS( ia, ias ) && "Exactly one member of iAstruct must be non-null, and this must match the type of the Inverse_Attribute." );
// assert( validIAS( ia, ias ) && "Exactly one member of iAstruct must be non-null, and this must match the type of the Inverse_Attribute." );
}
return ias;
}
const SDAI_Application_instance::iAMap_t::value_type SDAI_Application_instance::getInvAttr( const char * name ) const {
iAMap_t::const_iterator it = iAMap.begin();
for( ; it != iAMap.end(); ++it ) {
if( 0 == strcmp( it->first->Name(), name) ) {
return *it;
}
}
iAstruct z;
z.a = NULL;
iAMap_t::value_type nil( NULL, z );
return nil;
}
void SDAI_Application_instance::setInvAttr( const Inverse_attribute * const ia, const iAstruct ias ) {
assert( validIAS( ia, ias ) && "Exactly one member of iAstruct must be non-null, and this must match the type of the Inverse_Attribute." );
// assert( validIAS( ia, ias ) && "Exactly one member of iAstruct must be non-null, and this must match the type of the Inverse_Attribute." );
iAMap.insert( iAMap_t::value_type( ia, ias ) );
}

View file

@ -117,6 +117,7 @@ class SC_CORE_EXPORT SDAI_Application_instance : public SDAI_DAObject_SDAI {
}
// ACCESS inverse attributes
const iAstruct getInvAttr( const Inverse_attribute * const ia ) const;
const iAMap_t::value_type getInvAttr( const char * name ) const;
void setInvAttr( const Inverse_attribute * const ia, const iAstruct ias );
const iAMap_t & getInvAttrs() const {
return iAMap;

View file

@ -18,7 +18,11 @@ protected:
bool isempty; ///< if true, don't try to access invIter - it is not initialized
public:
/// WARNING this will not iterate over the ia's in the first ed, only in its supertypes! change that?
superInvAttrIter( const EntityDescriptor * ed ): sit( ed ), nextInv( 0 ), isempty( false ) {
superInvAttrIter( const EntityDescriptor * ed ): sit( ed ), invIter(0), nextInv( 0 ), isempty( false ) {
reset();
}
void reset( const EntityDescriptor * ed = 0 ) {
sit.reset( ed );
if( invIter ) {
delete invIter;
invIter = 0;
@ -46,7 +50,7 @@ public:
if( isempty ) {
return true;
}
return ( sit.empty() && !nextInv );
return ( !sit.hasNext() && !nextInv );
}
const Inverse_attribute * next() {
if( isempty ) {

View file

@ -15,6 +15,8 @@ extern void SchemaInit( class Registry & );
#include <errordesc.h>
#include <algorithm>
#include <string>
#include <superInvAttrIter.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@ -44,7 +46,31 @@ int main( int argc, char * argv[] ) {
}
cout << "instance #" << instance->StepFileId() << endl;
// superInvAttrIter it( instance->getEDesc() );
// // const Inverse_attributeList * l = &( instance->getEDesc()->InverseAttr() );
// // InverseAItr iai(l);
// const Inverse_attribute * ia;
// bool found = false;
// while( !found && ( ia = it.next() ) ) {
// if( !strcmp( ia->Name(), "isdefinedby" ) ) {
// found = true;
// }
// }
// if( found ) {
SDAI_Application_instance::iAMap_t::value_type v = instance->getInvAttr("isdefinedby");
iAstruct attr = v.second; //instance->getInvAttr(ia);
if( attr.a && attr.a->EntryCount() ) {
cout << "Map: found " << attr.a->EntryCount() << " inverse references." << endl;
} else {
cout << "Map: found no inverse references. ias " << (void *) &(v.second) << ", ia " << (void*) v.first << endl;
}
// }
EntityAggregate * aggr = instance->isdefinedby_(); //should be filled in when the file is loaded? not sure how to do it using STEPfile...
//fails because isdefinedby_ uses old data member rather than map lookup
if( attr.a != aggr ) {
cout << "Error! got different EntityAggregate's when using map vs method" << endl;
}
if( aggr && aggr->EntryCount() ) {
cout << "Found " << aggr->EntryCount() << " inverse references." << endl;
exit( EXIT_SUCCESS );