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 #ifndef PsNameServerTHEADER 00019 #define PsNameServerTHEADER 00020 00021 #include <map> 00022 #include "PsNameServer.h" 00023 #include "PsnMutexLock.h" 00024 00025 using namespace std ; 00032 #ifdef _OLDALLOCATORS 00033 template <class STLallocator > 00034 #else 00035 template <template <typename T> class STLallocator > 00036 #endif 00037 class PsNameServerT : public PsNameServer { 00038 public: 00041 PsNameServerT(); 00042 00043 00045 PsNameServerT(const PsNameServer::CanonicalRepresentationType * ); 00046 00047 00049 virtual ~PsNameServerT(); 00050 00051 00054 virtual long getIdentifier(const PsString &); 00055 00056 00059 virtual long getSystemIdentifier(const PsString &); 00060 00061 00064 virtual long getIdentifierAsFrom(const PsString &, long * nextId); 00065 00066 00069 virtual const PsString & getStringAssociatedTo (PsName::idType id) const; 00070 00071 00073 void * operator new(size_t); 00074 00075 00077 void operator delete(void * ptr, size_t n); 00078 00079 00081 virtual void created(PsName::idType id, PsName * ); 00082 00083 00085 virtual void deleted(PsName::idType id, PsName * ); 00086 00087 00091 CanonicalRepresentationType * getCanonicalRepresentation () const ; 00092 00093 00095 virtual const list<PsName *> & getNamesOfId (PsName::idType) const ; 00096 00097 protected: 00099 virtual void lock() const ; 00100 00102 virtual void unlock() const ; 00103 00105 mutable PsnMutexLock _ourDataLock ; 00106 00109 long _nextIdentifier ; 00110 00113 long _nextSystemIdentifier ; 00114 00115 00116 #ifdef _OLDALLOCATORS 00117 00118 //typedef hash_map<PsString, long, PsString_hash, equal_to<PsString>, STLallocator> correspondenceContainerType; 00119 typedef hash_map<PsString, long, PsString_hash > correspondenceContainerType ; 00120 00122 typedef map<long,correspondenceContainerType::iterator> fastStringAccessTableType; 00123 00125 typedef hash_map<PsName::idType, int> referenceCountingContainerType; 00126 00128 typedef hash_map<PsName::idType, list<PsName *> * > placeOfNamesContainerType; 00129 00130 #else 00131 00132 typedef hash_map<PsString,long, PsString_hash ,equal_to<PsString>,STLallocator<pair <PsString,long> > > correspondenceContainerType; 00133 00135 typedef map<long, typename correspondenceContainerType::iterator,less<long>,STLallocator<pair<const long, typename correspondenceContainerType::iterator> > > fastStringAccessTableType; 00136 00138 typedef hash_map<PsName::idType, int, hash<PsName::idType>,equal_to<PsName::idType>,STLallocator<pair<PsName::idType,int> > > referenceCountingContainerType; 00139 00141 typedef hash_map<PsName::idType, list<PsName *> *, hash<PsName::idType>,equal_to<PsName::idType>,STLallocator<pair<PsName::idType,int> > > placeOfNamesContainerType ; 00142 00143 00144 #endif 00145 00146 fastStringAccessTableType _fastStringAccessTable ; 00147 00149 correspondenceContainerType _stringToIdCorrespondenceContainer ; 00150 00152 referenceCountingContainerType _tableNbInstances; 00153 00155 placeOfNamesContainerType _idToNamesUsingIdContainer ; 00156 00157 }; 00158 00159 00160 00161 #ifdef _OLDALLOCATORS 00162 template <class STLallocator > 00163 #else 00164 template <template <typename T> class STLallocator > 00165 #endif 00166 PsNameServerT<STLallocator>::PsNameServerT() 00167 { 00168 //cerr<<"PsNameServerT<STLallocator>:"<<this<<":PsNameServerT() "<<endl; 00169 _nextIdentifier = PsName::_maxReservedId + 1 ; 00170 _nextSystemIdentifier = 1 ; 00171 00172 // keep id 0 reserved and associated to the string "Uninitialised PsName" 00173 _tableNbInstances.insert (referenceCountingContainerType::value_type(0, 0) ); 00174 #ifdef _TYPENAMENOTIMPLICIT 00175 typename correspondenceContainerType::iterator i=(_stringToIdCorrespondenceContainer.insert(typename correspondenceContainerType::value_type(PsString("Uninitialised PsName"),0))).first; 00176 _fastStringAccessTable.clear(); 00177 _fastStringAccessTable.insert(pair<const long, typename correspondenceContainerType::iterator>(0,i)); 00178 #else 00179 correspondenceContainerType::iterator i=(_stringToIdCorrespondenceContainer.insert(correspondenceContainerType::value_type(PsString("Uninitialised PsName"),0))).first; 00180 _fastStringAccessTable.clear(); 00181 _fastStringAccessTable.insert(pair<const long, correspondenceContainerType::iterator>(0,i)); 00182 #endif 00183 } 00184 00185 00186 00187 #ifdef _OLDALLOCATORS 00188 template <class STLallocator > 00189 #else 00190 template <template <typename T> class STLallocator > 00191 #endif 00192 PsNameServerT<STLallocator>::PsNameServerT(const PsNameServer::CanonicalRepresentationType * canonicalRepresentation) 00193 { 00194 //cerr<<"PsNameServerT<STLallocator>:"<<this<<":PsNameServerT(const PsNameServer::CanonicalRepresentationType * canonicalRepresentation)"<<endl; 00195 for ( CanonicalRepresentationType::const_iterator i = canonicalRepresentation->begin() ; 00196 i != canonicalRepresentation->end() ; 00197 i++ ) 00198 { 00199 //(*i) is < <PsName::idType,PsString> , numberOfInstances> therefore 00200 //(*i).first.first is the id, 00201 //(*i).first.second is the associated string 00202 //(*i).second is the number of instances of PsNames with id as id 00203 00204 //first create an entry is the hash_table for the associated string 00205 #ifdef _TYPENAMENOTIMPLICIT 00206 typename correspondenceContainerType::iterator ii=(_stringToIdCorrespondenceContainer.insert(typename correspondenceContainerType::value_type((*i).first.second,(*i).first.first))).first; 00207 // then reference that entry in the iterator table 00208 _fastStringAccessTable.insert(pair<const long, typename correspondenceContainerType::iterator>((*i).first.first,ii)); 00209 #else 00210 correspondenceContainerType::iterator ii=(_stringToIdCorrespondenceContainer.insert(correspondenceContainerType::value_type((*i).first.second,(*i).first.first))).first; 00211 // then reference that entry in the iterator table 00212 _fastStringAccessTable.insert(pair<const long, correspondenceContainerType::iterator>((*i).first.first,ii)); 00213 #endif 00214 //then take care of keeping care of the number of copies of id in the system 00215 _tableNbInstances[(*i).first.first] = (*i).second ; 00216 00217 //cerr<<"PsNameServerT<STLallocator>::PsNameServerT "<<(*i).second<<" references to "<<(*i).first.first<<endl; 00218 00219 //try and find a reasonnable next id 00220 _nextIdentifier = (*i).first.first + 1 ; 00221 } 00222 } 00223 00224 00225 #ifdef _OLDALLOCATORS 00226 template <class STLallocator > 00227 #else 00228 template <template <typename T> class STLallocator > 00229 #endif 00230 PsNameServerT<STLallocator>::~PsNameServerT() 00231 { 00232 //nothing to do 00233 } 00234 00235 00236 #ifdef _OLDALLOCATORS 00237 template <class STLallocator > 00238 #else 00239 template <template <typename T> class STLallocator > 00240 #endif 00241 PsName::idType 00242 PsNameServerT<STLallocator>::getIdentifier(const PsString & name) 00243 { 00244 PsName::idType res; 00245 //cerr<<this<<" "<<_nextIdentifier<<" "; 00246 res = getIdentifierAsFrom(name, &_nextIdentifier) ; 00247 //cerr<<"("<<res<<","<<name<<") added to name server "<<_nextIdentifier<<endl; 00248 return res; 00249 } 00250 00251 00252 #ifdef _OLDALLOCATORS 00253 template <class STLallocator > 00254 #else 00255 template <template <typename T> class STLallocator > 00256 #endif 00257 PsName::idType 00258 PsNameServerT<STLallocator>::getSystemIdentifier(const PsString & name) 00259 { 00260 00261 PsName::idType result = getIdentifierAsFrom(name, &_nextSystemIdentifier) ; 00262 // this assertion could fail if a PsName corresponding to a reserved id was staticaly created 00263 assert ( result <= PsName::_maxReservedId ) ; 00264 //this would fail if more reserved Id's are created than originaly planned for 00265 assert ( _nextSystemIdentifier <= PsName::_maxReservedId ) ; 00266 00267 return result ; 00268 } 00269 00270 00271 #ifdef _OLDALLOCATORS 00272 template <class STLallocator > 00273 #else 00274 template <template <typename T> class STLallocator > 00275 #endif 00276 PsName::idType 00277 PsNameServerT<STLallocator>::getIdentifierAsFrom (const PsString & name, long * nextId ) { 00278 00279 #ifdef _TYPENAMENOTIMPLICIT 00280 typename 00281 #endif 00282 correspondenceContainerType::iterator i = _stringToIdCorrespondenceContainer.find( name ); 00283 00284 if (i == _stringToIdCorrespondenceContainer.end()) 00285 { 00286 //we are going to change the values contained in the PsNameServer 00287 lock() ; 00288 00289 i = _stringToIdCorrespondenceContainer.find( name ) ; //name might have been added by an other process 00290 00291 if (i == _stringToIdCorrespondenceContainer.end() ) //we have to add name 00292 { 00293 00294 #ifdef _TYPENAMENOTIMPLICIT 00295 pair<typename correspondenceContainerType::iterator,bool> res = _stringToIdCorrespondenceContainer.insert(typename correspondenceContainerType::value_type(name,*nextId)) ; 00296 #else 00297 pair<correspondenceContainerType::iterator,bool> res = _stringToIdCorrespondenceContainer.insert(correspondenceContainerType::value_type(name,*nextId)) ; 00298 #endif 00299 00300 _fastStringAccessTable[*nextId] = res.first ; 00301 00302 *nextId = *nextId + 1 ; 00303 00304 i = res.first ; 00305 } 00306 00307 unlock() ; 00308 } 00309 return (*i).second; 00310 } 00311 00312 #ifdef _OLDALLOCATORS 00313 template <class STLallocator > 00314 #else 00315 template <template <typename T> class STLallocator > 00316 #endif 00317 const PsString & 00318 PsNameServerT<STLallocator>::getStringAssociatedTo (PsName::idType id) const 00319 { 00320 assert ( id<_nextIdentifier) ; 00321 //assert ( _fastStringAccessTable.find(id) != _fastStringAccessTable.end() ) ; 00322 return (*(*_fastStringAccessTable.find(id)).second).first ; 00323 } 00324 00325 #ifdef _OLDALLOCATORS 00326 template <class STLallocator > 00327 #else 00328 template <template <typename T> class STLallocator > 00329 #endif 00330 PsNameServer::CanonicalRepresentationType * 00331 PsNameServerT<STLallocator>::getCanonicalRepresentation() const 00332 { 00333 PsNameServer::CanonicalRepresentationType * canonicalRepresentation = new PsNameServer::CanonicalRepresentationType () ; 00334 #ifdef _TYPENAMENOTIMPLICIT 00335 typename 00336 #endif 00337 PsNameServerT<STLallocator>::correspondenceContainerType::const_iterator i; 00338 for (i=_stringToIdCorrespondenceContainer.begin(); i!=_stringToIdCorrespondenceContainer.end();i++) 00339 { 00340 canonicalRepresentation->push_back(PsPair<PsPair<PsName::idType,PsString>, int>(PsPair<PsName::idType,PsString>((*i).second,(*i).first),(*(_tableNbInstances.find((*i).second))).second)) ; 00341 } 00342 canonicalRepresentation->sort() ; 00343 return canonicalRepresentation ; 00344 } 00345 00346 00347 00348 #ifdef _OLDALLOCATORS 00349 template <class STLallocator > 00350 void * 00351 PsNameServerT<STLallocator>::operator new(size_t size) 00352 { 00353 return STLallocator::allocate(size); 00354 } 00355 #else 00356 template <template <typename T> class STLallocator > 00357 void * 00358 PsNameServerT<STLallocator>::operator new(size_t size) 00359 { 00360 STLallocator<PsNameServerT<STLallocator> > anAllocator; 00361 return anAllocator.allocate(size); 00362 } 00363 #endif 00364 00365 00366 00367 #ifdef _OLDALLOCATORS 00368 template <class STLallocator > 00369 void PsNameServerT<STLallocator>::operator delete(void * ptr, size_t n) 00370 { 00371 STLallocator::deallocate(ptr,n); 00372 } 00373 #else 00374 template <template <typename T> class STLallocator > 00375 void PsNameServerT<STLallocator>::operator delete(void * ptr, size_t n) 00376 { 00377 STLallocator<PsNameServerT<STLallocator> > anAllocator; 00378 anAllocator.deallocate((PsNameServerT<STLallocator> *)ptr,n); 00379 } 00380 #endif 00381 00382 #ifdef _OLDALLOCATORS 00383 template <class STLallocator > 00384 #else 00385 template <template <typename T> class STLallocator > 00386 #endif 00387 void PsNameServerT<STLallocator>::created(PsName::idType id, PsName * name) 00388 { 00389 lock() ; 00390 #ifdef _TYPENAMENOTIMPLICIT 00391 typename 00392 #endif 00393 referenceCountingContainerType::iterator i = _tableNbInstances.find(id); 00394 if ( i == _tableNbInstances.end() ) 00395 { 00396 i = _tableNbInstances.insert(referenceCountingContainerType::value_type(id,1)).first; 00397 } 00398 else 00399 { 00400 ++(*i).second; 00401 } 00402 // do the same for _idToNamesUsingIdContainer 00403 #ifdef _TYPENAMENOTIMPLICIT 00404 typename 00405 #endif 00406 placeOfNamesContainerType::iterator j = _idToNamesUsingIdContainer.find(id); 00407 if ( j == _idToNamesUsingIdContainer.end() ) 00408 { 00409 j = _idToNamesUsingIdContainer.insert(placeOfNamesContainerType::value_type(id,new list<PsName *>() ) ).first ; 00410 } 00411 assert ( (*j).second != NULL ) ; 00412 (*j).second->push_front( name ) ; 00413 00414 unlock() ; 00415 //cerr<<"PsNameServerT<"<<this<<">::created called for "<<getStringAssociatedTo(id)<<" "<<name<<" of id "<<id<<" with "<<(*i).second<<" instances now and "<<(*j).second->size( )<<" registred PsNames"<< endl; 00416 } 00417 00418 #ifdef _OLDALLOCATORS 00419 template <class STLallocator > 00420 #else 00421 template <template <typename T> class STLallocator > 00422 #endif 00423 void PsNameServerT<STLallocator>::deleted(PsName::idType id, PsName * name) 00424 { 00425 //cerr<<"PsNameServerT<"<<this<<">::deleted called for "<<getStringAssociatedTo(id)<<" "<<name<<" of id "<<id; 00426 lock() ; 00427 00428 #ifdef _TYPENAMENOTIMPLICIT 00429 typename 00430 #endif 00431 referenceCountingContainerType::iterator i = _tableNbInstances.find(id); 00432 00433 assert ( i != _tableNbInstances.end() ) ; 00434 00435 //cerr<<" with "<<(*i).second<<" instances left "<<&((*i).second)<<endl; 00436 --(*i).second; 00437 00438 //must remove name from _idToNamesUsingIdContainer, once 00439 #ifdef _TYPENAMENOTIMPLICIT 00440 typename 00441 #endif 00442 placeOfNamesContainerType::iterator j = _idToNamesUsingIdContainer.find(id); 00443 if ( j != _idToNamesUsingIdContainer.end() ) 00444 { 00445 assert ((*j).second != NULL ) ; //assert because otherwise it would meen a problem has occured 00446 //cerr<<"PsNameServerT<"<<this<<">::deleted " <<(*j).second->size()<<" PsNames referenced"<<endl; 00447 list<PsName *>::iterator k = (*j).second->begin() ; 00448 while ( *k != name ) 00449 { 00450 assert ( k != (*j).second->end() ) ; 00451 ++k ; 00452 } 00453 00454 assert ( k != (*j).second->end() ) ; //assert because otherwise it would meen a problem has occured 00455 00456 (*j).second->erase ( k ) ; 00457 } 00458 else 00459 { 00460 //there has been a problem 00461 assert ( false ) ; 00462 } 00463 00464 //keep the string associated to id 0 00465 if( ( (*i).second <= 0) && ( id != 0 ) ) 00466 { 00467 //cerr<<"PsNameServerT<"<<">::deleting "<<getStringAssociatedTo(id)<<endl; 00468 00469 00470 //if a string correponds, delete it 00471 if ( _fastStringAccessTable.find(id) != _fastStringAccessTable.end() ) 00472 { 00473 _stringToIdCorrespondenceContainer.erase(_fastStringAccessTable[id]); 00474 _fastStringAccessTable.erase(_fastStringAccessTable.find(id)); 00475 } 00476 00477 _tableNbInstances.erase(i); 00478 00479 assert ((*j).second != NULL ) ; //assert because otherwise it would meen a problem has occured 00480 delete (*j).second ; 00481 _idToNamesUsingIdContainer.erase (j) ; 00482 00483 assert ( _tableNbInstances.find(id) == _tableNbInstances.end() ) ; 00484 00485 if (id==_nextIdentifier-1) 00486 { 00487 _nextIdentifier=_nextIdentifier-1; 00488 } 00489 } 00490 00491 unlock() ; 00492 } 00493 00494 00495 #ifdef _OLDALLOCATORS 00496 template <class STLallocator > 00497 #else 00498 template <template <typename T> class STLallocator > 00499 #endif 00500 void 00501 PsNameServerT<STLallocator>::lock () const 00502 { 00503 _ourDataLock.protect() ; 00504 } 00505 00506 00507 #ifdef _OLDALLOCATORS 00508 template <class STLallocator > 00509 #else 00510 template <template <typename T> class STLallocator > 00511 #endif 00512 void PsNameServerT<STLallocator>::unlock () const 00513 { 00514 _ourDataLock.unprotect() ; 00515 } 00516 00517 #ifdef _OLDALLOCATORS 00518 template <class STLallocator > 00519 #else 00520 template <template <typename T> class STLallocator > 00521 #endif 00522 const list<PsName *> & PsNameServerT<STLallocator>::getNamesOfId (PsName::idType id) const 00523 { 00524 #ifdef _TYPENAMENOTIMPLICIT 00525 typename 00526 #endif 00527 placeOfNamesContainerType::const_iterator j = _idToNamesUsingIdContainer.find(id); 00528 00529 assert ( j != _idToNamesUsingIdContainer.end() ) ; 00530 00531 assert ( (*j).second != NULL ) ; 00532 00533 return *(*j).second ; 00534 } 00535 #endif 00536 00537 00538 00539 00540
| Documentation generated on Mon Nov 25 15:25:00 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |