//---------------------------------------------------------------------------- // // Copyright (C) Intel Corporation, 2007 - 2008. // // File: CanonicalHash.h // // Contents: A canonical hash - A hash which compose two hashes // linked together. i.e: A key of the outer hash points to // an inner hash which holds ELEMENTs // // Notes: //---------------------------------------------------------------------------- #ifndef CANONICAL_HASH_H #define CANONICAL_HASH_H //------------------ // Includes //------------------ #include "global.h" #include using namespace std; //------------------ // Defines //------------------ // define for the template (just to keep it shorter) #define templateDefCanonical_Hash //------------------ // Classes //------------------ //template < class OUTER, class INNER, class ELEMENT, class OUTER_COMPARE, class INNER_COMPARE > //class CanonicalHashIterator; /* * A canonical hash - A hash which compose two hashes linked together. * i.e: A key of the outer hash (OUTER) points to an inner hash whose elements are of type * INNER and hold ELEMENTs. * OUTER_COMPARE is used to compare OUTER objects. * INNER_COMPARE is used to compare INNER objects. */ template templateDefCanonical_Hash class Canonical_Hash { //friend class CanonicalHashIterator< OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE >; public: //------------------ // Public Typedefs //------------------ typedef map inner_map; typedef map outer_map; typedef typename inner_map::const_iterator constInnerIter; typedef typename outer_map::const_iterator constOuterIter; typedef typename inner_map::iterator innerIter; typedef typename outer_map::iterator outerIter; //------------------ // Public Functions //------------------ // CTOR Canonical_Hash(); // Destructor ~Canonical_Hash(); // Add a key to the outer layer void addOuter(const OUTER &outer); // Add a key and a value to the inner layer. // Its inner map is decided by the outer parameter. // If an element already exists in that location, than it is not entered. // If outer key does not exist than it is added void addInner(const OUTER &outer, const INNER &inner, ELEMENT value); // Returns true if the given key exists in the outer layer. bool hasOuter(const OUTER &outer) const; // Returns true if the given key exists in the inner layer. // Its inner map is decided by the outer parameter. bool hasInner(const OUTER &outer, const INNER &inner) const; // Puts the value in the [outer][inner] location inside toPutIn. // returns STATUS_FAILURE on failure (if value does not exist). // Returns STATUS_SUCCESS on success. STATUS getValue(const OUTER &outer, const INNER &inner, ELEMENT * toPutIn) const; // Deletes the element in the [outer][inner] location. // returns STATUS_FAILURE on failure (if value does not exist). // Returns STATUS_SUCCESS on success. STATUS deleteElement(const OUTER &outer, const INNER &inner); // Cleans the hash of all its element. // The responsibility on deleting the elements if needed is on the caller. void cleanHash(); // Returns a pointer to a const iterator the beginning of the outer layer. // If unsuccesful return NULL. constOuterIter * beginOuters() const; // Returns a pointer to a const iterator the ending of the outer layer. // If unsuccesful return NULL. constOuterIter * endOuters() const; // Returns a pointer to a const iterator the beginning of the inner layer. // Its inner map is decided by the outer parameter. // If unsuccesful return NULL. constInnerIter * beginInners(const OUTER &outer) const; // Returns a pointer to a const iterator the ending of the inner layer. // Its inner map is decided by the outer parameter. // If unsuccesful return NULL. constInnerIter * endInners(const OUTER &outer) const; private: //-------------- // Data Members //-------------- outer_map _outer_map; }; //------------------------------------------ // Canonical_Hash functions implementations //------------------------------------------ // Note: Functions are in the header file due to the template nature of the class. template templateDefCanonical_Hash void Canonical_Hash ::cleanHash() { _outer_map.clear(); } template templateDefCanonical_Hash Canonical_Hash ::Canonical_Hash() : _outer_map() { } template templateDefCanonical_Hash Canonical_Hash ::~Canonical_Hash() { } template templateDefCanonical_Hash void Canonical_Hash ::addOuter(const OUTER &outer) { _outer_map[outer]; } template templateDefCanonical_Hash void Canonical_Hash ::addInner(const OUTER &outer, const INNER &inner, ELEMENT value) { if (!hasInner(outer, inner)) { if (!hasOuter(outer)) { addOuter(outer); } (_outer_map[outer]).insert(make_pair(inner, value)); } } template templateDefCanonical_Hash bool Canonical_Hash ::hasOuter(const OUTER &outer) const { typename Canonical_Hash::constOuterIter iter = _outer_map.find(outer); return (iter != _outer_map.end()); } template templateDefCanonical_Hash bool Canonical_Hash ::hasInner(const OUTER &outer, const INNER &inner) const { bool found = false; typename Canonical_Hash::constOuterIter iter = _outer_map.find(outer); if (iter != _outer_map.end()) { typename Canonical_Hash::constInnerIter innerIter = (iter ->second).find(inner); if (innerIter != (iter ->second).end()) { found = true; } } return found; } template templateDefCanonical_Hash STATUS Canonical_Hash ::getValue(const OUTER &outer, const INNER &inner, ELEMENT * toPutIn) const { if (hasInner(outer, inner)) { typename Canonical_Hash::constOuterIter iter = _outer_map.find(outer); typename Canonical_Hash::constInnerIter innerIter = (iter ->second).find(inner); *toPutIn = innerIter -> second; return STATUS_SUCCESS; } else { return STATUS_FAILURE; } } template templateDefCanonical_Hash typename Canonical_Hash::constOuterIter * Canonical_Hash ::beginOuters() const { return new constOuterIter(_outer_map.begin()); } template templateDefCanonical_Hash typename Canonical_Hash::constOuterIter * Canonical_Hash ::endOuters() const { return new constOuterIter(_outer_map.end()); } template templateDefCanonical_Hash typename Canonical_Hash::constInnerIter * Canonical_Hash ::beginInners(const OUTER &outer) const { typename Canonical_Hash::constOuterIter iter = _outer_map.find(outer); if (iter != _outer_map.end()) { return new constInnerIter((iter ->second).begin()); } else { return NULL; } } template templateDefCanonical_Hash typename Canonical_Hash::constInnerIter * Canonical_Hash ::endInners(const OUTER &outer) const { typename Canonical_Hash::constOuterIter iter = _outer_map.find(outer); if (iter != _outer_map.end()) { return new constInnerIter((iter ->second).end()); } else { return NULL; } } template templateDefCanonical_Hash STATUS Canonical_Hash ::deleteElement(const OUTER &outer, const INNER &inner) { if (hasInner(outer, inner)) { typename Canonical_Hash::outerIter iter = _outer_map.find(outer); typename Canonical_Hash::innerIter innerIter = (iter ->second).find(inner); inner_map &inMap = (iter->second); inMap.erase(innerIter); return STATUS_SUCCESS; } else { return STATUS_FAILURE; } } #endif /* CANONICAL_HASH_H */