Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

Hash.h

Go to the documentation of this file.
00001 //
00002 //  Copyright (c) 2003-2005 by Autodesk, Inc.
00003 //
00004 //  By using this code, you are agreeing to the terms and conditions of
00005 //  the License Agreement included in the documentation for this code.
00006 //
00007 //  AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED,
00008 //  AS TO THE CORRECTNESS OF THIS CODE OR ANY DERIVATIVE
00009 //  WORKS WHICH INCORPORATE IT.
00010 //
00011 //  AUTODESK PROVIDES THE CODE ON AN "AS-IS" BASIS
00012 //  AND EXPLICITLY DISCLAIMS ANY LIABILITY, INCLUDING
00013 //  CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
00014 //  OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
00015 //
00016 //  Use, duplication, or disclosure by the U.S. Government is subject to
00017 //  restrictions set forth in FAR 52.227-19 (Commercial Computer Software
00018 //  Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
00019 //  Data and Computer Software), as applicable.
00020 //
00021 
00022 #ifndef _DWFCORE_HASH_H
00023 #define _DWFCORE_HASH_H
00024 
00025 
00031 
00032 
00033 
00034 #include "dwfcore/Core.h"
00035 
00036 
00037 
00038 namespace DWFCore
00039 {
00040 
00050 template<class T, class S>
00051 struct tDWFHashKernel
00052 {
00059     virtual T operator()( const S* _s ) const
00060     {
00061         (void)_s;
00062 
00063         return 1L;
00064     }
00065 };
00066 
00080 template<class S>
00081 struct tDWFDJB2HashKernel : tDWFHashKernel<uint32_t, S>
00082 {
00090     uint32_t operator()( S* _s, uint32_t _seed = 5381 ) const
00091     {
00092         uint32_t nHash = _seed;
00093         S* pIn = (S*)_s;
00094 
00095         if (pIn)
00096         {
00097             unsigned int nVal = (unsigned int)*pIn++;
00098 
00099             while (nVal > 0)
00100             {
00101 #ifdef  DWFCORE_HASH_DJB2_USE_ORIGINAL_VERSION
00102                 nHash = ((nHash << 5) + nHash) + nVal;
00103 #else
00104                 nHash = nHash*33 ^ nVal;
00105 #endif
00106 
00107                 nVal = (unsigned int)*pIn++;
00108             };
00109         }
00110 
00111         return nHash;
00112     }
00113 };
00114 
00142 template<class S>
00143 struct tDWFFNV1A32HashKernel : tDWFHashKernel<uint32_t, S>
00144 {
00152     uint32_t operator()( S* _s, uint32_t _seed = 0x811c9dc5L ) const
00153     {
00154         //
00155         // note that initial value is non-zero
00156         //
00157         uint32_t nHash = _seed;
00158         S* pIn = _s;
00159 
00160             //
00161             // FNV-1a hash each octet in the buffer
00162             //
00163         if (pIn)
00164         {
00165             unsigned int nVal = (unsigned int)*pIn++;
00166 
00167             while (nVal > 0)
00168             {
00169                 //
00170                 // XOR the bottom with the current octet
00171                 //
00172                 nHash ^= (uint32_t)nVal;
00173 
00174                 //
00175                 // multiply by the 32 bit FNV magic prime mod 2^32
00176                 // #define FNV_32_PRIME (0x01000193)
00177                 //
00178 #ifdef  DWFCORE_HASH_FNV_DONT_USE_GCC_OPTIMIZATION
00179                 nHash *= (uint32_t)0x01000193L;
00180 #else
00181                 nHash += ((nHash<<1) + (nHash<<4) + (nHash<<7) + (nHash<<8) + (nHash<<24));
00182 #endif
00183                 nVal = (unsigned int)*pIn++;
00184             }
00185         }
00186 
00187 
00188         return nHash;
00189     }
00190 };
00191 
00192 
00222 template<class S>
00223 struct tDWFFNV1A64HashKernel : tDWFHashKernel<uint64_t, S>
00224 {
00232 #if     defined(_DWFCORE_WIN32_SYSTEM) && (_MSC_VER < 1310)
00233     //
00234     // MSVC 7.0 and below don't know about long long
00235     //
00236     uint64_t operator()( S* _s, uint64_t _seed = 0xcbf29ce484222325 ) const
00237 #else
00238     uint64_t operator()( S* _s, uint64_t _seed = 0xcbf29ce484222325ULL ) const
00239 #endif
00240     {
00241         //
00242         // note that initial value is non-zero
00243         //
00244         uint64_t nHash = _seed;
00245         S* pIn = _s;
00246 
00247             //
00248             // FNV-1a hash each octet in the buffer
00249             //
00250         if (pIn)
00251         {
00252             unsigned int nVal = (unsigned int)*pIn++;
00253 
00254             while (nVal > 0)
00255             {
00256                 //
00257                 // XOR the bottom with the current octet
00258                 //
00259                 nHash ^= (uint64_t)nVal;
00260 
00261                 //
00262                 // multiply by the 64 bit FNV magic prime mod 2^64
00263                 // #define FNV_32_PRIME (0x01000193)
00264                 //
00265 #ifdef  DWFCORE_HASH_FNV_DONT_USE_GCC_OPTIMIZATION
00266                 nHash *= (uint64_t)0x100000001b3;
00267 #else
00268                 nHash += ((nHash << 1) + (nHash << 4) + (nHash << 5) +
00269                           (nHash << 7) + (nHash << 8) + (nHash << 40));
00270 
00271 #endif
00272                 nVal = (unsigned int)*pIn++;
00273             }
00274         }
00275 
00276 
00277         return nHash;
00278     }
00279 };
00280 
00285 #define _DWFCORE_HASH_JENK96_MIX(a, b, c)   \
00286 {                                           \
00287   a -= b; a -= c; a ^= (c>>13);             \
00288   b -= c; b -= a; b ^= (a<<8);              \
00289   c -= a; c -= b; c ^= (b>>13);             \
00290   a -= b; a -= c; a ^= (c>>12);             \
00291   b -= c; b -= a; b ^= (a<<16);             \
00292   c -= a; c -= b; c ^= (b>>5);              \
00293   a -= b; a -= c; a ^= (c>>3);              \
00294   b -= c; b -= a; b ^= (a<<10);             \
00295   c -= a; c -= b; c ^= (b>>15);             \
00296 }
00297 
00306 struct tDWFJenk96CharHashKernel : tDWFHashKernel<uint32_t,const char>
00307 {
00315     uint32_t operator()( const char* _s, uint32_t _seed = 0x02364629L ) const
00316     {
00317         uint32_t nHash    = _seed;         // 37111337 - arbitrary prime (gde 4/04)
00318         uint32_t nBucket1 = 0x9e3779b9L;   // the golden ratio; an arbitrary value
00319         uint32_t nBucket2 = 0x9e3779b9L;   // the golden ratio; an arbitrary value
00320         const char* pIn = _s;
00321         unsigned char iByte = 0;
00322 
00323         if (pIn)
00324         {
00325             unsigned char nVal = *pIn++;
00326             while (nVal > 0)
00327             {
00328                 //
00329                 // "length" counter
00330                 //
00331                 iByte = 0;
00332 
00333                 //
00334                 // jenkins 12-byte cycle
00335                 //
00336                 nBucket1 += nVal;   iByte++;
00337                 nVal = *pIn++;
00338                 if (nVal > 0)
00339                 {
00340                     nBucket1 += (nVal << 8);   iByte++;
00341                     nVal = *pIn++;
00342                     if (nVal > 0)
00343                     {
00344                         nBucket1 += (nVal << 16);   iByte++;
00345                         nVal = *pIn++;
00346                         if (nVal > 0)
00347                         {
00348                             nBucket1 += (nVal << 24);   iByte++;
00349                             nVal = *pIn++;
00350                             if (nVal > 0)
00351                             {
00352                                 nBucket2 += nVal;   iByte++;
00353                                 nVal = *pIn++;
00354                                 if (nVal > 0)
00355                                 {
00356                                     nBucket2 += (nVal << 8);   iByte++;
00357                                     nVal = *pIn++;
00358                                     if (nVal > 0)
00359                                     {
00360                                         nBucket2 += (nVal << 16);   iByte++;
00361                                         nVal = *pIn++;
00362                                         if (nVal > 0)
00363                                         {
00364                                             nBucket2 += (nVal << 24);   iByte++;
00365                                             nVal = *pIn++;
00366                                             if (nVal > 0)
00367                                             {
00368                                                 nHash += (nVal << 8);   iByte++;
00369                                                 nVal = *pIn++;
00370                                                 if (nVal > 0)
00371                                                 {
00372                                                     nHash += (nVal << 16);   iByte++;
00373                                                     nVal = *pIn++;
00374                                                     if (nVal > 0)
00375                                                     {
00376                                                         nHash += (nVal << 24);   iByte++;
00377                                                         nVal = *pIn++;
00378                                                     }
00379                                                 }
00380                                             }
00381                                         }
00382                                     }
00383                                 }
00384                             }
00385                         }
00386                     }
00387                 }
00388 
00389                 if (iByte < 12)
00390                 {
00391                     nHash += iByte;
00392                 }
00393 
00394                 _DWFCORE_HASH_JENK96_MIX( nBucket1, nBucket2, nHash );
00395             }
00396         }
00397 
00398         return nHash;
00399     }
00400 };
00401 
00410 struct tDWFJenk96WCharHashKernel : tDWFHashKernel<uint32_t,const wchar_t>
00411 {
00419     uint32_t operator()( const wchar_t* _s, uint32_t _seed = 0x02364629L ) const
00420     {
00421         uint32_t nHash    = _seed;         // 37111337 - arbitrary prime (gde 4/04)
00422         uint32_t nBucket1 = 0x9e3779b9L;   // the golden ratio; an arbitrary value
00423         uint32_t nBucket2 = 0x9e3779b9L;   // the golden ratio; an arbitrary value
00424         const wchar_t* pIn = _s;
00425         unsigned char iByte = 0;
00426 
00427         if (pIn)
00428         {
00429             unsigned char nVal1 = (unsigned char)((*pIn)&(0x00ff));
00430             unsigned char nVal2 = (unsigned char)((*pIn)>>8);
00431             while ((nVal1+nVal2) > 0)
00432             {
00433                 //
00434                 // "length" counter
00435                 //
00436                 iByte = 0;
00437 
00438                 //
00439                 // jenkins 12-byte cycle
00440                 //
00441                 nBucket1 += nVal1;          iByte++;
00442                 nBucket1 += (nVal2 << 8);   iByte++;
00443 
00444                 pIn++;
00445                 nVal1 = (unsigned char)((*pIn)&(0x00ff));
00446                 nVal2 = (unsigned char)((*pIn)>>8);
00447                 if ((nVal1+nVal2) > 0)
00448                 {
00449                     nBucket1 += (nVal1 << 16);  iByte++;
00450                     nBucket1 += (nVal2 << 24);  iByte++;
00451 
00452                     pIn++;
00453                     nVal1 = (unsigned char)((*pIn)&(0x00ff));
00454                     nVal2 = (unsigned char)((*pIn)>>8);
00455                     if ((nVal1+nVal2) > 0)
00456                     {
00457                         nBucket2 += nVal1;          iByte++;
00458                         nBucket2 += (nVal2 << 8);   iByte++;
00459 
00460                         pIn++;
00461                         nVal1 = (unsigned char)((*pIn)&(0x00ff));
00462                         nVal2 = (unsigned char)((*pIn)>>8);
00463                         if ((nVal1+nVal2) > 0)
00464                         {
00465                             nBucket2 += (nVal1 << 16);  iByte++;
00466                             nBucket2 += (nVal2 << 24);  iByte++;
00467 
00468                             pIn++;
00469                             nVal1 = (unsigned char)((*pIn)&(0x00ff));
00470                             nVal2 = (unsigned char)((*pIn)>>8);
00471                             if ((nVal1+nVal2) > 0)
00472                             {
00473                                 nHash += nVal1;          iByte++;
00474                                 nHash += (nVal2 << 8);   iByte++;
00475 
00476                                 pIn++;
00477                                 nVal1 = (unsigned char)((*pIn)&(0x00ff));
00478                                 nVal2 = (unsigned char)((*pIn)>>8);
00479                                 if ((nVal1+nVal2) > 0)
00480                                 {
00481                                     nHash += (nVal1 << 16);  iByte++;
00482                                     nHash += (nVal2 << 24);  iByte++;
00483                                 }
00484                             }
00485                         }
00486                     }
00487                 }
00488 
00489                 if (iByte < 12)
00490                 {
00491                     nHash += iByte;
00492                 }
00493 
00494                 _DWFCORE_HASH_JENK96_MIX( nBucket1, nBucket2, nHash );
00495             }
00496         }
00497 
00498         return nHash;
00499     }
00500 };
00501 
00502 
00503 }
00504 
00505 #endif
00506 

Generated on Tue May 17 12:05:10 2005 for Autodesk DWF Core Library by  doxygen 1.4.1