Home | History | Annotate | Download | only in Tools
      1 /*!****************************************************************************
      2 
      3  @file         PVRTHash.h
      4  @copyright    Copyright (c) Imagination Technologies Limited.
      5  @brief        A simple hash class which uses TEA to hash a string or given data
      6                into a 32-bit unsigned int.
      7 
      8 ******************************************************************************/
      9 
     10 #ifndef PVRTHASH_H
     11 #define PVRTHASH_H
     12 
     13 #include "PVRTString.h"
     14 #include "PVRTGlobal.h"
     15 
     16 /*!****************************************************************************
     17  @class         CPVRTHash
     18  @brief         A simple hash class which uses TEA to hash a string or other given
     19                 data into a 32-bit unsigned int.
     20 ******************************************************************************/
     21 class CPVRTHash
     22 {
     23 public:
     24 	/*!***************************************************************************
     25 	@brief      	Constructor
     26 	*****************************************************************************/
     27 	CPVRTHash() : m_uiHash(0) {}
     28 
     29 	/*!***************************************************************************
     30 	@brief      	Copy Constructor
     31 	@param[in]		rhs         CPVRTHash to copy.
     32 	*****************************************************************************/
     33 	CPVRTHash(const CPVRTHash& rhs) : m_uiHash(rhs.m_uiHash) {}
     34 
     35 	/*!***************************************************************************
     36 	@brief      	Overloaded constructor
     37 	@param[in]		String      CPVRTString to create the CPVRTHash with.
     38 	*****************************************************************************/
     39 	CPVRTHash(const CPVRTString& String) : m_uiHash(0)
     40 	{
     41 		if(String.length() > 0)		// Empty string. Don't set.
     42 		{
     43 			m_uiHash = MakeHash(String);
     44 		}
     45 	}
     46 
     47 	/*!***************************************************************************
     48 	@brief      	Overloaded constructor
     49 	@param[in]		c_pszString String to create the CPVRTHash with.
     50 	*****************************************************************************/
     51 	CPVRTHash(const char* c_pszString) : m_uiHash(0)
     52 	{
     53 		_ASSERT(c_pszString);
     54 		if(c_pszString[0] != 0)		// Empty string. Don't set.
     55 		{
     56 			m_uiHash = MakeHash(c_pszString);
     57 		}
     58 	}
     59 
     60 	/*!***************************************************************************
     61 	@brief      	Overloaded constructor
     62 	@param[in]		pData
     63 	@param[in]		dataSize
     64 	@param[in]		dataCount
     65 	*****************************************************************************/
     66 	CPVRTHash(const void* pData, unsigned int dataSize, unsigned int dataCount) : m_uiHash(0)
     67 	{
     68 		_ASSERT(pData);
     69 		_ASSERT(dataSize > 0);
     70 
     71 		if(dataCount > 0)
     72 		{
     73 			m_uiHash = MakeHash(pData, dataSize, dataCount);
     74 		}
     75 	}
     76 
     77 	/*!***************************************************************************
     78 	@brief      	Overloaded assignment.
     79 	@param[in]		rhs
     80 	@return			CPVRTHash &
     81 	*****************************************************************************/
     82 	CPVRTHash& operator=(const CPVRTHash& rhs)
     83 	{
     84 		if(this != &rhs)
     85 		{
     86 			m_uiHash = rhs.m_uiHash;
     87 		}
     88 
     89 		return *this;
     90 	}
     91 
     92 	/*!***************************************************************************
     93 	@brief      	Converts to unsigned int.
     94 	@return			int
     95 	*****************************************************************************/
     96 	operator unsigned int() const
     97 	{
     98 		return m_uiHash;
     99 	}
    100 
    101 	/*!***************************************************************************
    102 	@brief      	Generates a hash from a CPVRTString.
    103 	@param[in]		String
    104 	@return			The hash.
    105 	*****************************************************************************/
    106 	static CPVRTHash MakeHash(const CPVRTString& String)
    107 	{
    108 		if(String.length() > 0)
    109 			return MakeHash(String.c_str(), sizeof(char), (unsigned int) String.length());
    110 
    111 		return CPVRTHash();
    112 	}
    113 
    114 	/*!***************************************************************************
    115 	@brief      	Generates a hash from a null terminated char array.
    116 	@param[in]		c_pszString
    117 	@return         The hash.
    118 	*****************************************************************************/
    119 	static CPVRTHash MakeHash(const char* c_pszString)
    120 	{
    121 		_ASSERT(c_pszString);
    122 
    123 		if(c_pszString[0] == 0)
    124 			return CPVRTHash();
    125 
    126 		const char* pCursor = c_pszString;
    127 		while(*pCursor) pCursor++;
    128 		return MakeHash(c_pszString, sizeof(char), (unsigned int) (pCursor - c_pszString));
    129 	}
    130 
    131 	/*!***************************************************************************
    132 	@brief      	Generates a hash from generic data. This function uses the
    133 					32-bit Fowler/Noll/Vo algorithm which trades efficiency for
    134 					slightly increased risk of collisions. This algorithm is
    135 					public domain. More information can be found at:
    136 					http://www.isthe.com/chongo/tech/comp/fnv/.
    137 	@param[in]		pData
    138 	@param[in]		dataSize
    139 	@param[in]		dataCount
    140 	@return			unsigned int			The hash.
    141 	*****************************************************************************/
    142 	static CPVRTHash MakeHash(const void* pData, unsigned int dataSize, unsigned int dataCount)
    143 	{
    144 		_ASSERT(pData);
    145 		_ASSERT(dataSize > 0);
    146 
    147 #define FNV_PRIME		16777619U
    148 #define FNV_OFFSETBIAS	2166136261U
    149 
    150 		if(dataCount == 0)
    151 			return CPVRTHash();
    152 
    153 		CPVRTHash pvrHash;
    154 		unsigned char* p = (unsigned char*)pData;
    155 		pvrHash.m_uiHash = FNV_OFFSETBIAS;
    156 		for(unsigned int i = 0; i < dataSize * dataCount; ++i)
    157 		{
    158 			pvrHash.m_uiHash = (pvrHash.m_uiHash * FNV_PRIME) ^ p[i];
    159 		}
    160 
    161 		return pvrHash;
    162 	}
    163 
    164 private:
    165 	unsigned int		m_uiHash;		/// The hashed data.
    166 };
    167 
    168 #endif
    169 
    170