1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "CacheHashUtils.h"
13 * CacheHash::Hash(const char * key, uint32_t initval)
15 * See http://burtleburtle.net/bob/hash/evahash.html for more information
16 * about this hash function.
18 * This algorithm is used to check the data integrity.
21 static inline void hashmix(uint32_t& a
, uint32_t& b
, uint32_t& c
)
23 a
-= b
; a
-= c
; a
^= (c
>>13);
24 b
-= c
; b
-= a
; b
^= (a
<<8);
25 c
-= a
; c
-= b
; c
^= (b
>>13);
26 a
-= b
; a
-= c
; a
^= (c
>>12);
27 b
-= c
; b
-= a
; b
^= (a
<<16);
28 c
-= a
; c
-= b
; c
^= (b
>>5);
29 a
-= b
; a
-= c
; a
^= (c
>>3);
30 b
-= c
; b
-= a
; b
^= (a
<<10);
31 c
-= a
; c
-= b
; c
^= (b
>>15);
35 CacheHash::Hash(const char *aData
, uint32_t aSize
, uint32_t aInitval
)
37 const uint8_t *k
= reinterpret_cast<const uint8_t*>(aData
);
38 uint32_t a
, b
, c
, len
;
40 // length = PL_strlen(key);
41 /* Set up the internal state */
43 a
= b
= 0x9e3779b9; /* the golden ratio; an arbitrary value */
44 c
= aInitval
; /* variable initialization of internal state */
46 /*---------------------------------------- handle most of the key */
49 a
+= k
[0] + (uint32_t(k
[1])<<8) + (uint32_t(k
[2])<<16) + (uint32_t(k
[3])<<24);
50 b
+= k
[4] + (uint32_t(k
[5])<<8) + (uint32_t(k
[6])<<16) + (uint32_t(k
[7])<<24);
51 c
+= k
[8] + (uint32_t(k
[9])<<8) + (uint32_t(k
[10])<<16) + (uint32_t(k
[11])<<24);
56 /*------------------------------------- handle the last 11 bytes */
58 switch(len
) { /* all the case statements fall through */
59 case 11: c
+= (uint32_t(k
[10])<<24);
60 case 10: c
+= (uint32_t(k
[9])<<16);
61 case 9 : c
+= (uint32_t(k
[8])<<8);
62 /* the low-order byte of c is reserved for the length */
63 case 8 : b
+= (uint32_t(k
[7])<<24);
64 case 7 : b
+= (uint32_t(k
[6])<<16);
65 case 6 : b
+= (uint32_t(k
[5])<<8);
67 case 4 : a
+= (uint32_t(k
[3])<<24);
68 case 3 : a
+= (uint32_t(k
[2])<<16);
69 case 2 : a
+= (uint32_t(k
[1])<<8);
71 /* case 0: nothing left to add */
79 CacheHash::Hash16(const char *aData
, uint32_t aSize
, uint32_t aInitval
)
81 Hash32_t hash
= Hash(aData
, aSize
, aInitval
);
82 return (hash
& 0xFFFF);
85 NS_IMPL_ISUPPORTS0(CacheHash
)
87 CacheHash::CacheHash(uint32_t aInitval
)
99 CacheHash::Feed(uint32_t aVal
, uint8_t aLen
)
127 CacheHash::Update(const char *aData
, uint32_t aLen
)
129 const uint8_t *data
= reinterpret_cast<const uint8_t*>(aData
);
131 MOZ_ASSERT(!mFinalized
);
134 while (mBufPos
!= 4 && aLen
) {
135 mBuf
+= uint32_t(*data
) << 8*mBufPos
;
152 Feed(data
[0] + (uint32_t(data
[1]) << 8) + (uint32_t(data
[2]) << 16) +
153 (uint32_t(data
[3]) << 24));
159 case 3: mBuf
+= data
[2] << 16;
160 case 2: mBuf
+= data
[1] << 8;
161 case 1: mBuf
+= data
[0];
184 CacheHash::GetHash16()
186 Hash32_t hash
= GetHash();
187 return (hash
& 0xFFFF);