2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file string/STR_HashedString.h
31 * Copyright (C) 2001 NaN Technologies B.V.
32 * This file was formerly known as: GEN_StdString.cpp.
33 * \date November, 14, 2001
36 #ifndef __STR_HASHEDSTRING_H__
37 #define __STR_HASHEDSTRING_H__
39 #include "STR_String.h"
42 // Hash Mix utility function, by Bob Jenkins - Mix 3 32-bit values reversibly
44 // - If gHashMix() is run forward or backward, at least 32 bits in a,b,c have at
45 // least 1/4 probability of changing.
47 // - If gHashMix() is run forward, every bit of c will change between 1/3 and
50 static inline void STR_gHashMix(dword& a, dword& b, dword& c)
52 a -= b; a -= c; a ^= (c >> 13);
53 b -= c; b -= a; b ^= (a << 8);
54 c -= a; c -= b; c ^= (b >> 13);
55 a -= b; a -= c; a ^= (c >> 12);
56 b -= c; b -= a; b ^= (a << 16);
57 c -= a; c -= b; c ^= (b >> 5);
58 a -= b; a -= c; a ^= (c >> 3);
59 b -= c; b -= a; b ^= (a << 10);
60 c -= a; c -= b; c ^= (b >> 15);
64 // Fast Hashable<int32> functionality
65 // http://www.concentric.net/~Ttwang/tech/inthash.htm
67 static inline dword STR_gHash(dword inDWord)
79 enum { GOLDEN_RATIO = 0x9e3779b9 }; /* arbitrary value to initialize hash funtion, well not so arbitrary
80 * as this value is taken from the pigs library (Orange Games/Lost Boys) */
84 static dword STR_gHash(const void *in, int len, dword init_val)
86 unsigned int length = len;
87 dword a = (dword)GOLDEN_RATIO;
88 dword b = (dword)GOLDEN_RATIO;
89 dword c = init_val; /* the previous hash value */
90 byte *p_in = (byte *)in;
92 // Do the largest part of the key
95 a += (p_in[0] + ((dword)p_in[1] << 8) + ((dword)p_in[2] << 16) + ((dword)p_in[3] << 24));
96 b += (p_in[4] + ((dword)p_in[5] << 8) + ((dword)p_in[6] << 16) + ((dword)p_in[7] << 24));
97 c += (p_in[8] + ((dword)p_in[9] << 8) + ((dword)p_in[10] << 16) + ((dword)p_in[11] << 24));
98 STR_gHashMix(a, b, c);
99 p_in += 12; length -= 12;
102 // Handle the last 11 bytes
105 case 11: c += ((dword)p_in[10] << 24);
106 case 10: c += ((dword)p_in[9] << 16);
107 case 9: c += ((dword)p_in[8] << 8); /* the first byte of c is reserved for the length */
108 case 8: b += ((dword)p_in[7] << 24);
109 case 7: b += ((dword)p_in[6] << 16);
110 case 6: b += ((dword)p_in[5] << 8);
111 case 5: b += p_in[4];
112 case 4: a += ((dword)p_in[3] << 24);
113 case 3: a += ((dword)p_in[2] << 16);
114 case 2: a += ((dword)p_in[1] << 8);
115 case 1: a += p_in[0];
117 STR_gHashMix(a, b, c);
125 class STR_HashedString : public STR_String
128 STR_HashedString() : STR_String(), m_Hashed(false) {}
129 STR_HashedString(const char *str) : STR_String(str), m_Hashed(false) {}
130 STR_HashedString(const STR_String &str) : STR_String(str), m_Hashed(false) {}
132 inline dword hash(dword init = 0) const
136 const char *str = *this;
137 int length = this->Length();
138 m_CachedHash = STR_gHash(str, length, init);
145 mutable bool m_Hashed;
146 mutable dword m_CachedHash;
149 #endif //__STR_HASHEDSTRING_H__