//---------------------------------------------------------------- // File and Version Information: // $Id: AstSTLMatch.cc,v 1.1.1.1 2005/03/29 16:49:05 steinke Exp $ // // Description: // Implementation of AstSTLMatch class. For more info see .hh // // Author List: // Matthias Steinke March 2002 // // Bertram Kopf (RUB) migrated to PandaRoot //--------------------------------------------------------------- //----------------------- // This Class's Header -- //----------------------- #include "AstSTLMatch.h" //------------- // C Headers -- //------------- extern "C" { } //--------------- // C++ Headers -- //--------------- #include #include "CollectionUtils.h" //------------------------------- // Collaborating Class Headers -- //------------------------------- //----------------------------------------------------------------------- // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- //----------------------------------------------------------------------- // ---------------------------------------- // -- Public Function Member Definitions -- // ---------------------------------------- //---------------- // Constructors -- //---------------- template AstSTLMatch::AstSTLMatch() { _theMatchDict = new std::map*, PndPtrLess>; _valueHashFunction = hashFunction2; _matchQualityCleanerFunction = 0; } template AstSTLMatch:: AstSTLMatch(unsigned (*keyHashFunction)(const MatchKey &), unsigned (*valueHashFunction)(const MatchedValue &)) { _theMatchDict = new std::map*, PndPtrLess>; _valueHashFunction = valueHashFunction; _matchQualityCleanerFunction = 0; } //-------------- // Destructor -- //-------------- template AstSTLMatch::~AstSTLMatch(){ // The class has responsibility for all the dictionaries associating // matched objects and their consistencies, // and for the consistencies themselves // but *not* the matched objects. typename std::map*, PndPtrLess >::iterator dictionaryCleaner = _theMatchDict->begin(); while (dictionaryCleaner != _theMatchDict->end()){ // For each match we have to...... // .....loop over the MatchQuality map and delete the contents..... typename std::map::iterator matchQualityCleaner = dictionaryCleaner->second->begin(); while (matchQualityCleaner != dictionaryCleaner->second->end()) { // .....call a cleaner function for cases where MatchQuality is an object // which just contains pointers to more objects. e.g. MatchQuality may // be a vector of pointers. if( _matchQualityCleanerFunction != 0 ) { (*_matchQualityCleanerFunction)( *(matchQualityCleaner->second) ); } delete matchQualityCleaner->second; ++matchQualityCleaner; } // ..... and then delete the dictionary itself delete dictionaryCleaner->second; ++dictionaryCleaner; } delete _theMatchDict; _theMatchDict=0; } //------------- // Methods -- //------------- //------------- // Operators -- //------------- //------------- // Selectors -- //------------- template bool AstSTLMatch::contains(const MatchKey *theKey, const MatchedValue *theValue)const { bool contained = false; typename std::map*, PndPtrLess >::iterator position = _theMatchDict->find((MatchKey *)theKey); if (position != _theMatchDict->end()) { if (position->second->find((MatchedValue *)theValue) != position->second->end()) contained=true; } return contained; } template const MatchQuality * AstSTLMatch::getMatchQuality(const MatchKey *theKey, const MatchedValue *theValue) const{ // This returns the MatchQuality between the matched pair offered, or 0 (null) if // either the key or the value cannot be found typename std::map*, PndPtrLess >::iterator position = _theMatchDict->find((MatchKey *)theKey); if (position != _theMatchDict->end()) { typename map::iterator innerPos = position->second->find((MatchedValue *)theValue); if (innerPos != position->second->end()) return innerPos->second; } return 0; } template const std::map * AstSTLMatch::findMatchSet(const MatchKey *theKey) const{ // Returns the set of matched values for the given key, or 0 if none can be found typename std::map*, PndPtrLess >::iterator position; if ((position = _theMatchDict->find((MatchKey *)theKey)) != _theMatchDict->end()) return position->second; else return 0; } template const std::map*, PndPtrLess > * AstSTLMatch::getTheMatchDictionary() const{ return _theMatchDict; } //------------- // Modifiers -- //------------- template void AstSTLMatch::clearAndDestroy() { typename std::map*, PndPtrLess>::iterator dictionaryCleaner = _theMatchDict->begin(); while (dictionaryCleaner !=_theMatchDict->end()) { typename std::map::iterator matchQualityCleaner = dictionaryCleaner->second->begin(); while (matchQualityCleaner != dictionaryCleaner->second->end()) { // delete the MatchedValue delete matchQualityCleaner->first; ++matchQualityCleaner; } // End while (matchQualityCleaner) dictionaryCleaner->second->clear(); // delete the MatchKey delete dictionaryCleaner->first; ++dictionaryCleaner; } // End while (dictionaryCleaner) _theMatchDict->clear(); } template void AstSTLMatch::insertMatch(MatchKey *theKey, MatchedValue *theValue, MatchQuality *theMatchQuality){ typename std::map*, PndPtrLess >::iterator position; if ((position = _theMatchDict->find(theKey)) != _theMatchDict->end()) { std::map *theAssocDictionary = position->second; // We already have the key, dictionary pair // Check to see if we also have this match - thanks due to Bob J for spotting // this leak. typename std::map::iterator mqPosition; if ((mqPosition = theAssocDictionary->find(theValue)) != theAssocDictionary->end()) { MatchQuality *existingMQ = mqPosition->second; // We need to delete the old MatchQuality object for which we have // responsibility, because RW will simply overwrite it. if (theMatchQuality!=existingMQ) delete existingMQ; } (*theAssocDictionary)[theValue] = theMatchQuality; } else { // The key is new to us. Create a new dictionary, and put the all the new // information into our collection std::map *theNewDictionary = new std::map; // The following shouldn't really be needed, but for safety... assert(theNewDictionary!=0); (*theNewDictionary)[theValue] = theMatchQuality; (*_theMatchDict)[theKey] = theNewDictionary; } } template size_t AstSTLMatch::removeMatchesForKey(MatchKey *theKey){ // Remove the matches, and clean up after ourselves typename std::map*, PndPtrLess >::iterator position; if ((position = _theMatchDict->find(theKey)) != _theMatchDict->end()) { std::map *theMatchQualityDict = position->second; // If the key is known.... typename std::map::iterator cleanUp = theMatchQualityDict->begin(); // ....delete the MatchQuality objects..... while( cleanUp != theMatchQualityDict->begin() ) { delete cleanUp->second; ++cleanUp; } // .....delete the Dictionary we just found...... delete theMatchQualityDict; //......and finally remove the key from the matched collection _theMatchDict->erase(theKey); return 1; } else { // If we do not recognise the key....do nothing return 0; } } template size_t AstSTLMatch::removeSpecificMatch(MatchKey *theKey, MatchedValue *theValue){ typename std::map*, PndPtrLess >::iterator position; if ((position = _theMatchDict->find(theKey)) != _theMatchDict->end()) { std::map *theMatchQualityDict = position->second; if (theMatchQualityDict->size()==1){ // We are down to our last association. Pull out the entire workings for this key return removeMatchesForKey(theKey); } else { // There is more than one match left for this key. Only remove the match we want // (if we have it already - but that is taken care of by RW) if (theMatchQualityDict->erase(theValue) != 0){ return 1; } else { return 0; } } } else { // We do not recognise the key. Do nothing return 0; } } // ----------------------------------------------- // -- Static Data & Function Member Definitions -- // ----------------------------------------------- template unsigned AstSTLMatch::hashFunction1(const MatchKey & p) { return ((unsigned long) &p >> 5) & 0x03ff; } template unsigned AstSTLMatch::hashFunction2(const MatchedValue & p) { return ((unsigned long) &p >> 5) & 0x03ff; } // ------------------------------------------- // -- Protected Function Member Definitions -- // ------------------------------------------- // ----------------------------------------- // -- Private Function Member Definitions -- // ----------------------------------------- // ----------------------------------- // -- Internal Function Definitions -- // -----------------------------------