OMKNameServer.cpp

Go to the documentation of this file.
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 

logo OpenMask

Documentation generated on Mon Jun 9 11:45:57 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007