282 lines
8.2 KiB
C++

//----------------------------------------------------------------------------
//
// 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 <map>
using namespace std;
//------------------
// Defines
//------------------
// define for the template (just to keep it shorter)
#define templateDefCanonical_Hash <class OUTER, class INNER, class ELEMENT, class OUTER_COMPARE, class INNER_COMPARE>
//------------------
// 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<const INNER, const ELEMENT, INNER_COMPARE> inner_map;
typedef map<const OUTER, inner_map, OUTER_COMPARE> 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<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::cleanHash()
{
_outer_map.clear();
}
template templateDefCanonical_Hash
Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::Canonical_Hash() : _outer_map()
{
}
template templateDefCanonical_Hash
Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::~Canonical_Hash()
{
}
template templateDefCanonical_Hash
void Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::addOuter(const OUTER &outer)
{
_outer_map[outer];
}
template templateDefCanonical_Hash
void Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::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<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::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<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::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<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::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<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>::constOuterIter *
Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::beginOuters() const
{
return new constOuterIter(_outer_map.begin());
}
template templateDefCanonical_Hash
typename Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>::constOuterIter *
Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::endOuters() const
{
return new constOuterIter(_outer_map.end());
}
template templateDefCanonical_Hash
typename Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>::constInnerIter *
Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::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<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>::constInnerIter *
Canonical_Hash<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::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<OUTER, INNER, ELEMENT, OUTER_COMPARE, INNER_COMPARE>
::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 */