Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
60141ce
abstract class with non-virtual destructor
mpictor Oct 13, 2013
5b14529
warning about comparison that was always true
mpictor Oct 13, 2013
bf39d90
_mainRegistry wasn't initialized
mpictor Oct 13, 2013
ffd0da9
default to case insensitive when searching by instance type
mpictor Oct 13, 2013
6419146
functions to look up instance type in file
mpictor Dec 6, 2013
2d060e7
minor changes to judyLArray.h, judy.c
mpictor Dec 8, 2013
6004ba4
remove outdated comment from inverse_attr2.cc
mpictor Dec 9, 2013
9144443
doxify comments in classes_misc.c
mpictor Dec 15, 2013
259750e
split a big fprintf up for readability
mpictor Dec 15, 2013
57d3d2f
improve some comments for doxygen
mpictor Dec 17, 2013
7867505
macro CONST -> const
mpictor Dec 19, 2013
f3cd328
add a FIXME
mpictor Mar 6, 2014
6e636d1
add variable names to some prototypes in ErrorDescriptor header
mpictor Mar 16, 2014
d1062cd
use lazyInstMgr for inverse_attr3.cc
mpictor Oct 13, 2013
b1387b7
improve comments, a few other small changes that don't affect behavior
mpictor Oct 13, 2013
35ead38
include subsuperiterators header
mpictor Oct 28, 2013
0188910
add lazyRefs.h
mpictor Oct 28, 2013
b3b4646
trivial changes
mpictor Dec 6, 2013
ca56023
use lazyRefs in lazyInstMgr
mpictor Dec 8, 2013
bd402b2
add STEPinvAttrList for inv attr descs and setter/getter pointers
mpictor Dec 15, 2013
d5f693a
use STEPinvAttrList in sdaiApplication_Instance
mpictor Dec 15, 2013
e17938a
generated c++: static setter/getter for inverse attrs
mpictor Dec 15, 2013
ef2c01d
in generated c++: in constructors, populate iAttrs
mpictor Dec 15, 2013
647ecbc
in generated c++: ensure that pointers are zeroed (DataMemberInitiali…
mpictor Dec 16, 2013
1fddd17
in generated c++: ensure pointer is non-null before calling shallowCopy
mpictor Dec 17, 2013
4b3e433
in generated c++: create data members for null pointers
mpictor Dec 17, 2013
f6078d8
eliminate unused buffer
mpictor Dec 16, 2013
ebb7a92
use InstMgrBase instead of InstMgr in most stepcore classes
mpictor Dec 17, 2013
51acb99
whoops, don't pretend an instance can't be found if it is already loaded
mpictor Dec 17, 2013
7222c91
update inverse attr test 3
mpictor Dec 17, 2013
fdcdd5a
forgot to replace InstMgr with InstMgrBase in selects.c
mpictor Dec 17, 2013
d9c89b9
when printing initializers, skip derived attrs
mpictor Dec 17, 2013
a74dc1d
forgot to add 'const' keyword in several places after changing the ..…
mpictor Dec 19, 2013
800453e
split entity methods out of ATTRprint_access_methods into 2 new funcs
mpictor Dec 19, 2013
d4f13e0
replace entity access member code with call to new func
mpictor Dec 19, 2013
aaa1ca0
fix a few comments
mpictor Dec 19, 2013
23a5a62
formatting
mpictor Dec 19, 2013
2ae605d
rename var - 'class' may not be a C keyword, but it's confusing
mpictor Mar 1, 2014
64dd1d2
two libstructor_print calls missing neededAttr param
mpictor Mar 1, 2014
118d8b2
merge with instMgrBase commit
mpictor Mar 1, 2014
6cb750a
don't print const for getter
mpictor Mar 1, 2014
d6bb20d
use instMgrBase in SDAI_Select operator test
mpictor Mar 2, 2014
236778a
generated code: also print a const getter in class header when attr i…
mpictor Mar 2, 2014
d64bbc3
move count var so that derived attrs are counted
mpictor Mar 2, 2014
5c0bea3
add braces and indenting to two LISTdo..LISTod's
mpictor Mar 2, 2014
3132089
note that unity headers are probably useless since the main schema he…
mpictor Mar 2, 2014
4a01038
fix a couple comments
mpictor Mar 2, 2014
cd08570
print const and non-const getters for select attrs
mpictor Mar 2, 2014
f638355
move string/binary access methods into 2 small funcs
mpictor Mar 2, 2014
47d42ad
invert sense of test in logging code - wouldn't print unless null
mpictor Mar 2, 2014
521a999
change const getter for entity attr's
mpictor Mar 2, 2014
62ef3c6
add const getter for string/bin attr's
mpictor Mar 2, 2014
14d7b32
remove duplicate function prototypes that masked a signature change
mpictor Mar 4, 2014
ea339e2
exp2cxx: move select getters into own function, print const and non-c…
mpictor Mar 4, 2014
9cf54cf
add attrIsObj(), which returns true if const and non-const methods ar…
mpictor Mar 4, 2014
acdc338
static setter/getter won't always have the same signature
mpictor Mar 4, 2014
ea24200
make STEPinvAttrList work with the new setter/getter variants
mpictor Mar 4, 2014
b9db456
CONST -> const in a few more places
mpictor Mar 4, 2014
6117e53
move much of ATTRprint_access_methods into a series of smaller funcs
mpictor Mar 4, 2014
3133165
modify const-ness in AGGRprint_access_methods
mpictor Mar 4, 2014
9e1d078
add 2 protos to classes_attribute header
mpictor Mar 4, 2014
66deaaf
change behavior of attrIsObj() fn in classes_attribute
mpictor Mar 4, 2014
73b3c1b
fix assertion - can either be aggregate or instance
mpictor Mar 6, 2014
06bfc7d
handle both aggr and non-aggr inverses
mpictor Mar 6, 2014
b31ffa3
more changes to attrIsObj()
mpictor Mar 6, 2014
6955a03
check for both aggr and non-aggr inverse attributes
mpictor Mar 16, 2014
4bde538
add comment with express that fails
mpictor Mar 16, 2014
4093158
fix test dependency so 'make test ARGS=-jN' works
mpictor Mar 30, 2014
7089bdb
when loading instance dependencies, seek to original position afterwards
mpictor Mar 30, 2014
9db1170
improve some comments in lazy loading code
mpictor Mar 30, 2014
674fa94
delete the array of names after creating a STEPcomplex
mpictor Mar 30, 2014
c2c0a64
reformat some error message code, add one message for complex insts
mpictor Mar 30, 2014
7842742
redo some comments
mpictor May 11, 2014
4df86e5
schema name changed for some p21 tests - update it
mpictor May 11, 2014
1e95f8f
remove LIBcopy_constructor() - unused since 1992(!)
mpictor May 18, 2014
7ae3434
indents in generated code
mpictor May 19, 2014
168e7a9
split up a 32-line fprintf
mpictor May 19, 2014
712d965
improve comments, whitespace
mpictor Jun 1, 2014
01db378
silence a signed-unsigned warning by using size_t
mpictor Jun 1, 2014
14689c6
split ENTITYprint_new() into two, print into different files
mpictor Jun 1, 2014
c6d8417
initialize entity iAttrs using eDesc
mpictor Jun 1, 2014
2374029
cleanup
mpictor Jun 1, 2014
65c703b
work on inverse attrs
mpictor Aug 21, 2014
98283dc
more work on inverse attrs, code generation
mpictor Nov 29, 2014
9efd75e
add some small schemas and a .p21; should be examined, maybe moved/si…
mpictor Nov 29, 2014
c8cfac3
some types still print in SdaiAll
mpictor Nov 29, 2014
86bbc32
cleanup
mpictor Nov 29, 2014
d36d12c
fix failing schema
mpictor Dec 8, 2014
0b42b2f
oops, move eDesc initialization back into SdaiAll
mpictor Dec 8, 2014
7976c8b
loop through ed's with inverse attrs, connecting them to what they po…
mpictor Dec 8, 2014
febbb63
allow const or non-const for ed iter
mpictor Dec 8, 2014
c91109b
add functions to access schema class members
mpictor Dec 8, 2014
87c66bb
flesh out InitIAttrs() in eDesc, instance
mpictor Dec 8, 2014
31bf315
const correctness in superInvAttrIter
mpictor Dec 8, 2014
5df2f69
inching forward on inverse attrs
mpictor Dec 22, 2014
921de86
closer...
mpictor Dec 22, 2014
9313b8e
move some attr-specific stuff from classes_entity to classes_attribut…
mpictor Dec 23, 2014
ff3fd1f
_complex is now bool, not int - update STEPcomplex ctors
mpictor Dec 26, 2014
6bac26d
add index to struct Variable_, fix some whitespace
mpictor Dec 26, 2014
37901af
redo attribute numbering, print inverse attr access members separately
mpictor Dec 26, 2014
efb8285
don't print code for inverse data members, they're in iAMap now
mpictor Dec 26, 2014
8273ce1
lazyRefs works now
mpictor Dec 26, 2014
5f702fb
fix dumpComplexInst func, stupid mistake - was using wrong data member
mpictor Dec 26, 2014
653625f
fix crash with lazy loading and unexpected newlines, found in cd209 f…
mpictor Dec 26, 2014
e74d4dc
fix inverse attr initialization; attr was being found but it wasn't e…
mpictor Dec 26, 2014
50452e8
fix inv attr code in SDAI_Application_instance
mpictor Dec 26, 2014
dfe69a9
bug in superInvAttrIter allowed null pointer return for ia
mpictor Dec 26, 2014
bfbd8df
minor cleanup
mpictor Dec 26, 2014
0f5179e
oops, forgot an include
mpictor Dec 26, 2014
c8f14a0
bump version (0.8), update AUTHORS, NEWS for v0.8, add travis-ci buil…
mpictor Dec 26, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add lazyRefs.h
  • Loading branch information
mpictor committed Dec 26, 2014
commit 0188910a3ad9d08d03884db3dbabbd49550d4bec
262 changes: 262 additions & 0 deletions src/cllazyfile/lazyRefs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
#ifndef LAZYREFS_H
#define LAZYREFS_H

#include <string>
#include <set>
#include <utility>
#include <vector>

#include "lazyTypes.h"
#include "lazyInstMgr.h"
#include "ExpDict.h"
#include "sdaiApplication_instance.h"
#include "SubSuperIterators.h"
#include <STEPattribute.h>
#include <STEPaggregate.h>

/*
* given inverted attr ia:
* attr method value
* ----------- -----
* ia->Name() isdefinedby
* ia->inverted_attr_id_() relatedobjects
* ia->inverted_entity_id_() reldefinesbytype
*
* 1. for the instance in question, find inverse attrs with recursion
* 2. look up references to the current instance (_r)
* a. for each item in _r, look up its type and add mapping (instanceID -> char* typestring) to _refMap
* 3. for each ia,
* a. entity name is returned by ia->inverted_entity_id_()
* b. add this entity and its children to a list ( edL )
* c. compare the type of each item in _refMap with types in edL; for types in both, remember the instance number ( _referentInstances )
* d. load each instance in _referentInstances
* e. check if the relevant inverted attr of instances loaded from _referentInstances reference the instance in step 1; if not, unload **IF** the instance hadn't been loaded
* --> if it was loaded, this implies that it is used elsewhere
* f. (optional / TODO ) for performance, cache list edL - it may be useful in the future
* -- best to store such that the most recently (frequently?) used lists are retained and others are discarded
*/
/* ****
* ALTERNATE for 2a, 3c:
* for each type t in edL, use lim->getInstances( t ) to get a list of instances of that type, Lt
* for each instance i in Lt, check if it is in _r
* if so, load it
* BENEFIT: no need to write lazyInstMgr::getTypeStr() (however, it might be necessary in the future regardless)
*/

//TODO screen out intances that appear to be possible inverse refs but aren't actually
// 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?

class lazyRefs {
public:
typedef std::set< instanceID > referentInstances_t;
protected:
typedef std::set< const Inverse_attribute * > iaList_t;
typedef judyLArray< instanceID, std::string * > refMap_t;
typedef std::set< const EntityDescriptor * > edList_t;
iaList_t _iaList;
lazyInstMgr * _lim;
instanceID _id;
refMap_t _refMap;
referentInstances_t _referentInstances;
SDAI_Application_instance * _inst;

void checkAnInvAttr( const Inverse_attribute * ia ) {
const EntityDescriptor * ed;
const Registry * reg = _lim->getMainRegistry();
ed = reg->FindEntity( ia->_inverted_entity_id );
subtypesIterator subtypeIter( ed );
edList_t edL;
edL.insert( ed );
// 3b - use subtypeIter to add to edL
for( ; !subtypeIter.empty(); ++subtypeIter ) {
edL.insert( *subtypeIter );
}
//3c - for each item in both _refMap and edL, add it to _referentInstances
potentialReferentInsts( edL );
//3d - load each inst
invAttrListNode * invNode = invAttr( _inst, ia /*, iaList*/ );
referentInstances_t::iterator insts = _referentInstances.begin();
for( ; insts != _referentInstances.end(); ++insts ) {
loadInstIFFreferent( *insts, invNode );
}
//3f - cache edL - TODO
}

void loadInstIFFreferent( instanceID inst, invAttrListNode * invNode ) {
bool prevLoaded = _lim->isLoaded( inst );
SDAI_Application_instance * rinst = _lim->loadInstance( inst );
bool ref = refersToCurrentInst( invNode->inverseADesc(), rinst );
if( ref ) {
EntityAggregate * ea = invNode->getter()( _inst );
ea->AddNode( new EntityNode( rinst ) );
} else {
if( !prevLoaded ) {
//TODO _lim->unload( inst ); //this should keep the inst loaded for now, but put it in a list of ones that can be unloaded if not accessed
}
}
}

///3e - check if actually inverse ref
bool refersToCurrentInst( Inverse_attribute * ia, SDAI_Application_instance * referrer ) {
//find the attr
int rindex = attrIndex( referrer, ia->_inverted_attr_id, ia->_inverted_entity_id );
STEPattribute sa = referrer->attributes[ rindex ];
assert( ( sa.getADesc()->BaseType() == ENTITY_TYPE ) &&
( sa.getADesc()->IsAggrType() ) );

//search for current inst id
EntityAggregate * aggr = dynamic_cast< EntityAggregate * >( sa.Aggregate());
assert( aggr );
EntityNode * en = ( EntityNode * ) aggr->GetHead();
bool found = false;
while( en ) {
if( en->node == _inst ) {
found = true;
break;
}
en = ( EntityNode * ) en->NextNode();
}
if( !found ) {
std::cerr << "inst #" << _inst->FileId() << " not found in #" << referrer->FileId();
std::cerr << ", attr #" << rindex << " [contents: ";
referrer->STEPwrite( std::cerr );
std::cerr << "]" << std::endl;
}
return found;
}

int attrIndex( SDAI_Application_instance * inst, const char * name, const char * entity ) {
for( int i = 0; i < inst->attributes.list_length(); i++ ) {
std::cout << "attr " << i << " name " << inst->attributes[i].Name() << ", entity " << inst->EntityName() << std::endl;
if( ( strcasecmp( name, inst->attributes[i].Name() ) == 0 ) &&
( strcasecmp( entity, inst->attributes[i].getADesc()->Owner().Name() ) == 0 ) ) {
return i;
} else {
}
}
return -1;
}

invAttrListNode * invAttr( SDAI_Application_instance * inst, const Inverse_attribute * ia /*, iaList_t & iaList */ ) {
invAttrListNode * n = ( invAttrListNode * ) inst->iAttrs.GetHead();
while( n ) {
if( n->inverseADesc() == ia ) {
return n;
}
n = ( invAttrListNode * ) n->NextNode();
}
std::cerr << "Error! inverse attr " << ia->Name() << " (" << ia << ") not found in iAttrs (" << ( void * )( & ( inst->iAttrs ) ) << ")." << std::endl;
return 0;
}

/** 3c. compare the type of each item in R with types in A
* for items that match, remember the instance number (list C)
*/
void potentialReferentInsts( edList_t & edL ) {
refMap_t::pair kv = _refMap.begin();
while( kv.value != 0 ) {
std::set< const EntityDescriptor * >::iterator edi = edL.begin();
for( ; edi != edL.end(); ++edi ) {
if( 0 == strcasecmp( kv.value->c_str(), ( *edi )->Name() ) ) {
_referentInstances.insert( kv.key );
break;
}
}
kv = _refMap.next();
}
}

///find any inverse attributes, put in `iaList`
/// attrs not necessarily in order!
void getInverseAttrs( const EntityDescriptor * ed, iaList_t & iaList ) {
iaList.clear();
supertypesIterator supersIter( ed );
const Inverse_attribute * iAttr;
for( ; !supersIter.empty(); ++supersIter ) {
//look at attrs of *si
InverseAItr iai( ( *supersIter )->InverseAttr() );
while( 0 != ( iAttr = iai.NextInverse_attribute() ) ) {
iaList.insert( iAttr );
}
}
// look at our own attrs
InverseAItr invAttrIter( ed->InverseAttr() );
while( 0 != ( iAttr = invAttrIter.NextInverse_attribute() ) ) {
iaList.insert( iAttr );
}
}

// 2. find reverse refs
//2a. convert to map where K=instanceID and V=char*
// rather than keeping each V in memory or trying to free non-unique ones, look up each type in the Registry and use that pointer
bool mapRefsToTypes() {
_refMap.clear( true ); // true -> use delete on pointers
instanceRefs_t::cvector * refs = _lim->getRevRefs()->find( _id );
if( !refs || refs->empty() ) {
return false;
}
instanceRefs_t::cvector::const_iterator it;
for( it = refs->begin(); it != refs->end(); ++it ) {
const char * type = _lim->typeFromFile( *it );
_refMap.insert( *it, new std::string( type ) );
}
return true;
}
public:
lazyRefs( lazyInstMgr * lmgr ): _lim( lmgr ), _id( 0 ) {
_iaList.clear();
}
lazyRefs( lazyInstMgr * lmgr, SDAI_Application_instance * ai ): _lim( lmgr ), _id( 0 ) {
_iaList.clear();
init( 0, ai );
}
lazyRefs( lazyInstMgr * lmgr, instanceID iid ): _lim( lmgr ) {
_iaList.clear();
init( iid, 0 );
}

~lazyRefs() {
// delete strings in refMap
_refMap.clear( true );
}

/// initialize with the given instance; will use ai if given, else loads instance iid
void init( instanceID iid, SDAI_Application_instance * ai = 0 ) {
if( iid == 0 && ai == 0 ) {
std::cerr << "Error at " << __FILE__ << ":" << __LINE__ << " - both args are null" << std::endl;
return;
}

if( !ai ) {
_inst = _lim->loadInstance( iid );
_id = iid;
} else {
_inst = ai;
_id = _inst->GetFileId();
}
_refMap.clear( true );


// 1. find inverse attrs with recursion
getInverseAttrs( ai->eDesc, _iaList );

//2. find reverse refs, map id to type (stop if there are no inverse attrs or no refs)
if( _iaList.size() == 0 || !mapRefsToTypes() ) {
return;
}

iaList_t::iterator iai = _iaList.begin();
for( ; iai != _iaList.end(); ++iai ) {
// 3. for each IA, ...
checkAnInvAttr( *iai );
}
}

referentInstances_t result() {
return _referentInstances;
}


};
#endif //LAZYREFS_H
74 changes: 74 additions & 0 deletions src/cllazyfile/lazyRefs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
for inverse attrs, we have the attr name and the type of the instance

--load instance, find inverse attr(s)
--for each inverse attr:
--find all instance types that inherit from the inverted attr's owner (list A)
--look up instances that reference the one in question (list B) - use memoization
--find instances that match both lists, put in list C
--load instances in list C
--for list C, check that the relevant attr references the original instance - if not, unload (?)
--

--when done with this inverse attr, cache list A




EXAMPLE
*******

information model
-----------------
ENTITY Object;
ObjectType : OPTIONAL STRING;
INVERSE
IsDefinedBy : SET [0:?] OF RelDefinesByType FOR RelatedObjects;
END_ENTITY;

ENTITY RelDefinesByType;
RelatedObjects : SET [1:?] OF Object;
END_ENTITY;

ENTITY Window
SUBTYPE OF (Object);
Description : OPTIONAL string;
END_ENTITY;

data file
---------
#1=OBJECT('one');
#2=RELDEFINESBYTYPE((#1));
#3=RELDEFINESBYTYPE((#4));
#4=WINDOW('two','blah');

#1 and #4 have an inverse attr, but this is not visible in the data file
#2 and #3 have #1 and #4, respectively, in an aggregate (thus the parenthesis around the instance); in this case, a SET called RelatedObjects
RelatedObjects is the inverted attr that the inverse attr IsDefinedBy links to

looking at the entity descriptor for WINDOW, it is not apparent that there is an inverse attr; its parents must be examined


given inverted attr ia:
attr method value
----------- -----
ia->Name() isdefinedby
ia->inverted_attr_id_() relatedobjects
ia->inverted_entity_id_() reldefinesbytype

1. for the instance in question, find inverse attrs with recursion
2. for each ia,
a. entity name is returned by ia->inverted_entity_id_()
b. add this entity and its children to a list (list A)
c. look up references to the current instance (list B)
d. for each item in B, look up its type; if its type is present in A, remember the instance number (list C)
e. load each instance in C
f. (optional) check if the relevant inverted attr of instances loaded from list C reference the instance in step 1; if not, unload **IF** the instance hadn't been loaded
--> if it was loaded, this implies that it is used elsewhere
g. cache list A, since it may be useful in the future
-- best to store such that the most recently (frequently?) used lists are retained and others are discarded


NEED TO DO
----------
make it possible to access inverse attrs without knowing their names
probably best to do this much like explicit attrs - creating an array. each element should have a pointer to the inverted attr desc, a pointer to the setter, and a pointer to the getter