1 #include "lazyTypes.h"
2 #include "lazyInstMgr.h"
3 #include "Registry.h"
4 #include <SubSuperIterators.h>
5 #include "SdaiSchemaInit.h"
6 #include "instMgrHelper.h"
7 #include "lazyRefs.h"
8
lazyInstMgr()9 lazyInstMgr::lazyInstMgr() {
10 _headerRegistry = new Registry( HeaderSchemaInit );
11 _instanceTypes = new instanceTypes_t( 255 ); //NOTE arbitrary max of 255 chars for a type name
12 _lazyInstanceCount = 0;
13 _loadedInstanceCount = 0;
14 _longestTypeNameLen = 0;
15 _mainRegistry = 0;
16 _errors = new ErrorDescriptor();
17 _ima = new instMgrAdapter( this );
18 }
19
~lazyInstMgr()20 lazyInstMgr::~lazyInstMgr() {
21 delete _headerRegistry;
22 delete _errors;
23 delete _ima;
24 //loop over files, sections, instances; delete header instances
25 lazyFileReaderVec_t::iterator fit = _files.begin();
26 for( ; fit != _files.end(); ++fit ) {
27 delete *fit;
28 }
29 dataSectionReaderVec_t::iterator sit = _dataSections.begin();
30 for( ; sit != _dataSections.end(); ++sit ) {
31 delete *sit;
32 }
33 _instancesLoaded.clear();
34 _instanceStreamPos.clear();
35 }
36
registerDataSection(lazyDataSectionReader * sreader)37 sectionID lazyInstMgr::registerDataSection( lazyDataSectionReader * sreader ) {
38 _dataSections.push_back( sreader );
39 return _dataSections.size() - 1;
40 }
41
addLazyInstance(namedLazyInstance inst)42 void lazyInstMgr::addLazyInstance( namedLazyInstance inst ) {
43 _lazyInstanceCount++;
44 assert( inst.loc.begin > 0 && inst.loc.instance > 0 );
45 int len = strlen( inst.name );
46 if( len > _longestTypeNameLen ) {
47 _longestTypeNameLen = len;
48 _longestTypeName = inst.name;
49 }
50 _instanceTypes->insert( inst.name, inst.loc.instance );
51 /* store 16 bits of section id and 48 of instance offset into one 64-bit int
52 ** TODO: check and warn if anything is lost (in calling code?)
53 ** does 32bit need anything special?
54 **
55 ** create conversion class?
56 ** could then initialize conversion object with number of bits
57 ** also a good place to check for data loss
58 */
59 positionAndSection ps = inst.loc.section;
60 ps <<= 48;
61 ps |= ( inst.loc.begin & 0xFFFFFFFFFFFFULL );
62 _instanceStreamPos.insert( inst.loc.instance, ps );
63
64 if( inst.refs ) {
65 if( inst.refs->size() > 0 ) {
66 //forward refs
67 _fwdInstanceRefs.insert( inst.loc.instance, *inst.refs );
68 instanceRefs::iterator it = inst.refs->begin();
69 for( ; it != inst.refs->end(); ++it ) {
70 //reverse refs
71 _revInstanceRefs.insert( *it, inst.loc.instance );
72 }
73 } else {
74 delete inst.refs;
75 }
76 }
77 }
78
getNumTypes() const79 unsigned long lazyInstMgr::getNumTypes() const {
80 unsigned long n = 0 ;
81 instanceTypes_t::cpair curr, end;
82 end = _instanceTypes->end();
83 curr = _instanceTypes->begin();
84 if( curr.value != 0 ) {
85 n = 1;
86 while( curr.value != end.value ) {
87 n++;
88 curr = _instanceTypes->next();
89 }
90 }
91 return n ;
92 }
93
openFile(std::string fname)94 void lazyInstMgr::openFile( std::string fname ) {
95 //don't want to hold a lock for the entire time we're reading the file.
96 //create a place in the vector and remember its location, then free lock
97 ///FIXME begin atomic op
98 size_t i = _files.size();
99 _files.push_back( (lazyFileReader * ) 0 );
100 ///FIXME end atomic op
101 lazyFileReader * lfr = new lazyFileReader( fname, this, i );
102 _files[i] = lfr;
103 /// TODO resolve inverse attr references
104 //between instances, or eDesc --> inst????
105 }
106
loadInstance(instanceID id,bool reSeek)107 SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id, bool reSeek ) {
108 assert( _mainRegistry && "Main registry has not been initialized. Do so with initRegistry() or setRegistry()." );
109 std::streampos oldPos;
110 positionAndSection ps;
111 sectionID sid;
112 SDAI_Application_instance * inst = _instancesLoaded.find( id );
113 if( inst ) {
114 return inst;
115 }
116 instanceStreamPos_t::cvector * cv;
117 if( 0 != ( cv = _instanceStreamPos.find( id ) ) ) {
118 switch( cv->size() ) {
119 case 0:
120 std::cerr << "Instance #" << id << " not found in any section." << std::endl;
121 break;
122 case 1:
123 long int off;
124 ps = cv->at( 0 );
125 off = ps & 0xFFFFFFFFFFFFULL;
126 sid = ps >> 48;
127 assert( _dataSections.size() > sid );
128 if( reSeek ) {
129 oldPos = _dataSections[sid]->tellg();
130 }
131 inst = _dataSections[sid]->getRealInstance( _mainRegistry, off, id );
132 if( reSeek ) {
133 _dataSections[sid]->seekg( oldPos );
134 }
135 break;
136 default:
137 std::cerr << "Instance #" << id << " exists in multiple sections. This is not yet supported." << std::endl;
138 break;
139 }
140 if( ( inst ) && ( inst != & NilSTEPentity ) ) {
141 _instancesLoaded.insert( id, inst );
142 _loadedInstanceCount++;
143 lazyRefs lr( this, inst );
144 lazyRefs::referentInstances_t insts = lr.result();
145 } else {
146 std::cerr << "Error loading instance #" << id << "." << std::endl;
147 }
148 } else {
149 std::cerr << "Instance #" << id << " not found in any section." << std::endl;
150 }
151 return inst;
152 }
153
154
instanceDependencies(instanceID id)155 instanceSet * lazyInstMgr::instanceDependencies( instanceID id ) {
156 instanceSet * checkedDependencies = new instanceSet();
157 instanceRefs dependencies; //Acts as queue for checking duplicated dependency
158
159 instanceRefs_t * _fwdRefs = getFwdRefs();
160 instanceRefs_t::cvector * _fwdRefsVec = _fwdRefs->find( id );
161 //Initially populating direct dependencies of id into the queue
162 if( _fwdRefsVec != 0 ) {
163 dependencies.insert( dependencies.end(), _fwdRefsVec->begin(), _fwdRefsVec->end() );
164 }
165
166 size_t curPos = 0;
167 while( curPos < dependencies.size() ) {
168
169 bool isNewElement = ( checkedDependencies->insert( dependencies.at( curPos ) ) ).second;
170 if( isNewElement ) {
171 _fwdRefsVec = _fwdRefs->find( dependencies.at( curPos ) );
172
173 if( _fwdRefsVec != 0 ) {
174 dependencies.insert( dependencies.end(), _fwdRefsVec->begin(), _fwdRefsVec->end() );
175 }
176 }
177
178 curPos++;
179 }
180
181 return checkedDependencies;
182 }
183
184