00001 /* 00002 * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software 00003 * 00004 * The Software has been developped within the Siames Project. 00005 * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights 00006 * 00007 * The Software has been registered with the Agence pour la Protection des 00008 * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200 00009 * 00010 * This file may be distributed under the terms of the Q Public License 00011 * version 1.0 as defined by Trolltech AS of Norway and appearing in the file 00012 * LICENSE.QPL included in the packaging of this file. 00013 * 00014 * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 00015 * for the software may use this file in accordance with that specific license 00016 * 00017 */ 00018 #include <OMKNameServer.h> 00019 #include "OMKTracer.h" 00020 00021 using namespace std ; 00022 using namespace OMK ; 00023 00024 00025 00026 NameServer::NameServer() 00027 { 00028 _nextIdentifier = Name::_maxReservedId + 1 ; 00029 _nextSystemIdentifier = 1 ; 00030 00031 // keep id 0 reserved and associated to the string "Uninitialised Name" 00032 _tableNbInstances.insert ( referenceCountingContainerType::value_type(0, 0) ); 00033 correspondenceContainerType::iterator i=(_stringToIdCorrespondenceContainer.insert( correspondenceContainerType::value_type( std::string( "Uninitialised Name" ), 0 ) ) ).first; 00034 _fastStringAccessTable.clear(); 00035 _fastStringAccessTable.insert(std::pair<Name::idType, correspondenceContainerType::iterator>(0,i)); 00036 } 00037 00038 NameServer::NameServer(const NameServer::CanonicalRepresentationType * canonicalRepresentation) 00039 { 00040 for ( CanonicalRepresentationType::const_iterator i = canonicalRepresentation->begin() ; 00041 i != canonicalRepresentation->end() ; 00042 i++ ) 00043 { 00044 //(*i) is < <Name::idType,std::string> , numberOfInstances> therefore 00045 //(*i).first.first is the id, 00046 //(*i).first.second is the associated string 00047 //(*i).second is the number of instances of OMKNames with id as id 00048 00049 //first create an entry is the hash_table for the associated string 00050 correspondenceContainerType::iterator ii=(_stringToIdCorrespondenceContainer.insert( correspondenceContainerType::value_type((*i).first.second,(*i).first.first))).first; 00051 // then reference that entry in the iterator table 00052 _fastStringAccessTable.insert(std::pair<Name::idType, correspondenceContainerType::iterator>((*i).first.first,ii)); 00053 00054 //then take care of keeping care of the number of copies of id in the system 00055 _tableNbInstances[(*i).first.first] = (*i).second ; 00056 00057 //try and find a reasonnable next id 00058 _nextIdentifier = (*i).first.first + 1 ; 00059 } 00060 } 00061 00062 NameServer::~NameServer() 00063 { 00064 //nothing to do 00065 } 00066 00067 Name::idType 00068 NameServer::getIdentifier(const std::string & name) 00069 { 00070 return getIdentifierAsFrom( name, &_nextIdentifier ) ; 00071 } 00072 00073 Name::idType 00074 NameServer::getSystemIdentifier(const std::string & name) 00075 { 00076 00077 Name::idType result = getIdentifierAsFrom(name, &_nextSystemIdentifier) ; 00078 // this assertion could fail if a Name corresponding to a reserved id was staticaly created 00079 OMASSERTM( result <= Name::_maxReservedId, "" ) ; 00080 //this would fail if more reserved Id's are created than originaly planned for 00081 OMASSERTM( _nextSystemIdentifier <= Name::_maxReservedId, "" ) ; 00082 00083 return result ; 00084 } 00085 00086 Name::idType 00087 NameServer::getIdentifierAsFrom (const std::string & name, Name::idType * nextId ) 00088 { 00089 correspondenceContainerType::iterator i = _stringToIdCorrespondenceContainer.find( name.c_str() ); 00090 00091 if (i == _stringToIdCorrespondenceContainer.end()) 00092 { 00093 //we are going to change the values contained in the NameServer 00094 //lock() ; 00095 00096 i = _stringToIdCorrespondenceContainer.find( name ) ; //name might have been added by an other process 00097 00098 if (i == _stringToIdCorrespondenceContainer.end() ) //we have to add name 00099 { 00100 std::pair<correspondenceContainerType::iterator,bool> res = _stringToIdCorrespondenceContainer.insert(correspondenceContainerType::value_type(name,*nextId)) ; 00101 00102 _fastStringAccessTable[*nextId] = res.first ; 00103 00104 *nextId = *nextId + 1 ; 00105 00106 i = res.first ; 00107 } 00108 00109 //unlock() ; 00110 } 00111 return (*i).second; 00112 } 00113 00114 const std::string& NameServer::getStringAssociatedTo (Name::idType id) const 00115 { 00116 OMASSERTM( id<_nextIdentifier, "" ) ; 00117 return (*(*_fastStringAccessTable.find(id)).second).first ; 00118 } 00119 00120 NameServer::CanonicalRepresentationType * 00121 NameServer::getCanonicalRepresentation() const 00122 { 00123 NameServer::CanonicalRepresentationType * canonicalRepresentation = new NameServer::CanonicalRepresentationType() ; 00124 NameServer::correspondenceContainerType::const_iterator i; 00125 for (i=_stringToIdCorrespondenceContainer.begin(); i!=_stringToIdCorrespondenceContainer.end();i++) 00126 { 00127 canonicalRepresentation->push_back(CanonicalRepresentationItemType(std::pair<Name::idType,std::string>((*i).second,(*i).first),(*(_tableNbInstances.find((*i).second))).second)) ; 00128 } 00129 canonicalRepresentation->sort() ; 00130 return canonicalRepresentation ; 00131 } 00132 00133 void NameServer::created(Name::idType id, Name * name) 00134 { 00135 //lock() ; 00136 referenceCountingContainerType::iterator i = _tableNbInstances.find(id); 00137 if ( i == _tableNbInstances.end() ) 00138 { 00139 i = _tableNbInstances.insert(referenceCountingContainerType::value_type(id,1)).first; 00140 } 00141 else 00142 { 00143 ++(*i).second; 00144 } 00145 // do the same for _idToNamesUsingIdContainer 00146 placeOfNamesContainerType::iterator j = _idToNamesUsingIdContainer.find(id); 00147 if ( j == _idToNamesUsingIdContainer.end() ) 00148 { 00149 j = _idToNamesUsingIdContainer.insert(placeOfNamesContainerType::value_type(id,new std::list<Name *>() ) ).first ; 00150 } 00151 OMASSERTM( (*j).second != NULL, "" ) ; 00152 (*j).second->push_front( name ) ; 00153 00154 //unlock() ; 00155 } 00156 00157 void NameServer::deleted(Name::idType id, Name * name) 00158 { 00159 //lock() ; 00160 00161 referenceCountingContainerType::iterator i( _tableNbInstances.find( id ) ) ; 00162 if ( i != _tableNbInstances.end() ) 00163 { 00164 --( i->second ); 00165 00166 //must remove name from _idToNamesUsingIdContainer, once 00167 placeOfNamesContainerType::iterator j = _idToNamesUsingIdContainer.find(id); 00168 if ( j != _idToNamesUsingIdContainer.end() ) 00169 { 00170 OMASSERTM((*j).second != NULL, "a problem has occured" ) ; 00171 std::list<Name *>::iterator k = (*j).second->begin() ; 00172 while ( *k != name ) 00173 { 00174 OMASSERTM( k != (*j).second->end(), "" ) ; 00175 ++k ; 00176 } 00177 00178 OMASSERTM( k != (*j).second->end(), "a problem has occured" ) ; 00179 00180 (*j).second->erase ( k ) ; 00181 } 00182 else 00183 { 00184 //there has been a problem 00185 OMASSERTM( false, "" ) ; 00186 } 00187 00188 //keep the string associated to id 0 00189 if( ( (*i).second <= 0) && ( id != 0 ) ) 00190 { 00191 //if a string correponds, delete it 00192 if ( _fastStringAccessTable.find(id) != _fastStringAccessTable.end() ) 00193 { 00194 _stringToIdCorrespondenceContainer.erase(_fastStringAccessTable[id]); 00195 _fastStringAccessTable.erase(_fastStringAccessTable.find(id)); 00196 } 00197 00198 _tableNbInstances.erase(i); 00199 00200 OMASSERTM((*j).second != NULL, "a problem has occured" ) ; 00201 delete (*j).second ; 00202 _idToNamesUsingIdContainer.erase (j) ; 00203 00204 OMASSERTM( _tableNbInstances.find(id) == _tableNbInstances.end(), "" ) ; 00205 00206 if (id==_nextIdentifier-1) 00207 { 00208 _nextIdentifier=_nextIdentifier-1; 00209 } 00210 } 00211 } 00212 else 00213 { 00214 OMERROR( id ) ; 00215 } 00216 00217 //unlock() ; 00218 } 00219 00220 const std::list<Name *> & NameServer::getNamesOfId (Name::idType id) const 00221 { 00222 placeOfNamesContainerType::const_iterator j = _idToNamesUsingIdContainer.find(id); 00223 00224 OMASSERTM( j != _idToNamesUsingIdContainer.end(), "" ) ; 00225 00226 OMASSERTM( (*j).second != NULL, "" ) ; 00227 00228 return *(*j).second ; 00229 } 00230 00231 00232 bool OMK::operator == (const NameServer & source1, const NameServer & source2) 00233 { 00234 NameServer::CanonicalRepresentationType * canonicalRepresentation1 = source1.getCanonicalRepresentation() ; 00235 NameServer::CanonicalRepresentationType * canonicalRepresentation2 = source2.getCanonicalRepresentation() ; 00236 bool resul = *canonicalRepresentation1 == *canonicalRepresentation2 ; 00237 delete canonicalRepresentation1 ; 00238 delete canonicalRepresentation2 ; 00239 return resul ; 00240 } 00241 00242 00243 00244 bool NameServer::includes (const NameServer & otherNameServer ) 00245 { 00246 OMTRACEID( OMK_DEBUG_OMK_NAME, "NameServer::includes" ) ; 00247 NameServer::CanonicalRepresentationType * canonicalRepresentation1 = otherNameServer.getCanonicalRepresentation() ; 00248 NameServer::CanonicalRepresentationType * canonicalRepresentation2 = getCanonicalRepresentation() ; 00249 NameServer::CanonicalRepresentationType::const_iterator iter1 = canonicalRepresentation1->begin() ; 00250 NameServer::CanonicalRepresentationType::const_iterator iter2 = canonicalRepresentation2->begin() ; 00251 bool noMissingPairFound = true ; 00252 bool found ; 00253 while ( noMissingPairFound && ( iter1 != canonicalRepresentation1->end() ) ) 00254 { 00255 // make sure (*iter1).first is in canonicalRepresentation2 00256 OMTRACEID( OMK_DEBUG_OMK_NAME, "looking for <" <<(*iter1).first.first << "," << (*iter1).first.second<< ">" ) ; 00257 found = false ; 00258 while ( (iter2 != canonicalRepresentation2->end()) && !found ) 00259 { 00260 OMTRACEID( OMK_DEBUG_OMK_NAME, "examined <"<<(*iter2).first.first<<","<<(*iter2).first.second<<"> " ) ; 00261 if ( (*iter2).first == (*iter1).first ) 00262 { 00263 OMTRACEID( OMK_DEBUG_OMK_NAME, "identic" ) ; 00264 found = true ; 00265 } 00266 ++iter2 ; 00267 } 00268 if ( ( iter2 == canonicalRepresentation2->end() ) && !found ) 00269 { 00270 noMissingPairFound = false ; 00271 #if !defined NDEBUG 00272 std::ostringstream msg ; 00273 msg << "<"<<(*iter1).first.first<<","<<(*iter1).first.second<<"> not found in " ; 00274 otherNameServer.printToStream( msg, " " ); 00275 OMTRACEID( OMK_DEBUG_OMK_NAME, msg.str() ) ; 00276 #endif 00277 } 00278 else 00279 { 00280 ++iter1 ; 00281 } 00282 } 00283 delete canonicalRepresentation1 ; 00284 delete canonicalRepresentation2 ; 00285 return noMissingPairFound ; 00286 } 00287 00288 00289 00290 void 00291 NameServer::printToStream ( ostream & out , const std::string & separator) const 00292 { 00293 //lock() ; 00294 CanonicalRepresentationType * canonicalRepresentation = getCanonicalRepresentation() ; 00295 for ( CanonicalRepresentationType::const_iterator i = canonicalRepresentation->begin() ; 00296 i != canonicalRepresentation->end() ; 00297 i++ ) 00298 { 00299 out << i->first.first << " " << i->first.second << " " << i->second << separator; 00300 } 00301 out<<endl; 00302 delete canonicalRepresentation; 00303 //unlock() ; 00304 } 00305 00306 void NameServer::changeNamesId ( Name * namePointer, Name::idType oldId, Name::idType newId ) 00307 { 00308 OMASSERTM( namePointer != NULL, "Must be a valid pointer" ) ; 00309 namePointer->changeId ( oldId, newId ) ; 00310 } 00311 00312 00313 00314 00315 00316 00317 00318
Documentation generated on Mon Jun 9 11:45:57 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |