Go to the documentation of this file.00001 #include "SuperFastHash.h"
00002 #include "NativeTypes.h"
00003 #include <stdlib.h>
00004
00005 #if !defined(_WIN32)
00006 #include <stdint.h>
00007 #endif
00008
00009 #undef get16bits
00010 #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
00011 || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
00012 #define get16bits(d) (*((const uint16_t *) (d)))
00013 #endif
00014
00015 #if !defined (get16bits)
00016 #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
00017 +(uint32_t)(((const uint8_t *)(d))[0]) )
00018 #endif
00019
00020 static const int INCREMENTAL_READ_BLOCK=65536;
00021
00022 unsigned int SuperFastHash (const char * data, int length)
00023 {
00024
00025 int bytesRemaining=length;
00026 unsigned int lastHash = length;
00027 int offset=0;
00028 while (bytesRemaining>=INCREMENTAL_READ_BLOCK)
00029 {
00030 lastHash=SuperFastHashIncremental (data+offset, INCREMENTAL_READ_BLOCK, lastHash );
00031 bytesRemaining-=INCREMENTAL_READ_BLOCK;
00032 offset+=INCREMENTAL_READ_BLOCK;
00033 }
00034 if (bytesRemaining>0)
00035 {
00036 lastHash=SuperFastHashIncremental (data+offset, bytesRemaining, lastHash );
00037 }
00038 return lastHash;
00039
00040
00041 }
00042 unsigned int SuperFastHashIncremental (const char * data, int len, unsigned int lastHash )
00043 {
00044 uint32_t hash = (uint32_t) lastHash;
00045 uint32_t tmp;
00046 int rem;
00047
00048 if (len <= 0 || data == NULL) return 0;
00049
00050 rem = len & 3;
00051 len >>= 2;
00052
00053
00054 for (;len > 0; len--) {
00055 hash += get16bits (data);
00056 tmp = (get16bits (data+2) << 11) ^ hash;
00057 hash = (hash << 16) ^ tmp;
00058 data += 2*sizeof (uint16_t);
00059 hash += hash >> 11;
00060 }
00061
00062
00063 switch (rem) {
00064 case 3: hash += get16bits (data);
00065 hash ^= hash << 16;
00066 hash ^= data[sizeof (uint16_t)] << 18;
00067 hash += hash >> 11;
00068 break;
00069 case 2: hash += get16bits (data);
00070 hash ^= hash << 11;
00071 hash += hash >> 17;
00072 break;
00073 case 1: hash += *data;
00074 hash ^= hash << 10;
00075 hash += hash >> 1;
00076 }
00077
00078
00079 hash ^= hash << 3;
00080 hash += hash >> 5;
00081 hash ^= hash << 4;
00082 hash += hash >> 17;
00083 hash ^= hash << 25;
00084 hash += hash >> 6;
00085
00086 return (unsigned int) hash;
00087
00088 }
00089
00090 unsigned int SuperFastHashFile (const char * filename)
00091 {
00092 FILE *fp = fopen(filename, "rb");
00093 if (fp==0)
00094 return 0;
00095 unsigned int hash = SuperFastHashFilePtr(fp);
00096 fclose(fp);
00097 return hash;
00098 }
00099
00100 unsigned int SuperFastHashFilePtr (FILE *fp)
00101 {
00102 fseek(fp, 0, SEEK_END);
00103 int length = ftell(fp);
00104 fseek(fp, 0, SEEK_SET);
00105 int bytesRemaining=length;
00106 unsigned int lastHash = length;
00107 char readBlock[INCREMENTAL_READ_BLOCK];
00108 while (bytesRemaining>=(int) sizeof(readBlock))
00109 {
00110 fread(readBlock, sizeof(readBlock), 1, fp);
00111 lastHash=SuperFastHashIncremental (readBlock, (int) sizeof(readBlock), lastHash );
00112 bytesRemaining-=(int) sizeof(readBlock);
00113 }
00114 if (bytesRemaining>0)
00115 {
00116 fread(readBlock, bytesRemaining, 1, fp);
00117 lastHash=SuperFastHashIncremental (readBlock, bytesRemaining, lastHash );
00118 }
00119 return lastHash;
00120 }