diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /intern/string/STR_HashedString.h |
Initial revisionv2.25
Diffstat (limited to 'intern/string/STR_HashedString.h')
-rw-r--r-- | intern/string/STR_HashedString.h | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/intern/string/STR_HashedString.h b/intern/string/STR_HashedString.h new file mode 100644 index 00000000000..bf18a4e4da6 --- /dev/null +++ b/intern/string/STR_HashedString.h @@ -0,0 +1,154 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + + * $Id$ + * Copyright (C) 2001 NaN Technologies B.V. + * This file was formerly known as: GEN_StdString.cpp. + * @date November, 14, 2001 + */ + +#ifndef __STR_HASHSTRING +#define __STR_HASHSTRING + +#include "STR_String.h" + + +// Hash Mix utility function, by Bob Jenkins - Mix 3 32-bit values reversibly +// +// - If gHashMix() is run forward or backward, at least 32 bits in a,b,c have at +// least 1/4 probability of changing. +// +// - If gHashMix() is run forward, every bit of c will change between 1/3 and +// 2/3 of the time. +// +static inline void STR_gHashMix(dword& a, dword& b, dword& c) +{ + a -= b; a -= c; a ^= (c>>13); + b -= c; b -= a; b ^= (a<<8); + c -= a; c -= b; c ^= (b>>13); + a -= b; a -= c; a ^= (c>>12); + b -= c; b -= a; b ^= (a<<16); + c -= a; c -= b; c ^= (b>>5); + a -= b; a -= c; a ^= (c>>3); + b -= c; b -= a; b ^= (a<<10); + c -= a; c -= b; c ^= (b>>15); +} + +// +// Fast Hashable<int32> functionality +// http://www.concentric.net/~Ttwang/tech/inthash.htm +// +static inline dword STR_gHash(dword inDWord) +{ + dword key = inDWord; + key += ~(key << 16); + key ^= (key >> 5); + key += (key << 3); + key ^= (key >> 13); + key += ~(key << 9); + key ^= (key >> 17); + return key; +} + +enum { GOLDEN_RATIO = 0x9e3779b9 }; // arbitrary value to initialize hash funtion, well not so arbitrary + // as this value is taken from the pigs library (Orange Games/Lost Boys) + + + +static dword STR_gHash(const void* in, int len, dword init_val) +{ + unsigned int length = len; + dword a = (dword)GOLDEN_RATIO; + dword b = (dword)GOLDEN_RATIO; + dword c = init_val; // the previous hash value + byte *p_in = (byte *)in; + + // Do the largest part of the key + while (length >= 12) + { + a += (p_in[0] + ((dword)p_in[1]<<8) + ((dword)p_in[2] <<16) + ((dword)p_in[3] <<24)); + b += (p_in[4] + ((dword)p_in[5]<<8) + ((dword)p_in[6] <<16) + ((dword)p_in[7] <<24)); + c += (p_in[8] + ((dword)p_in[9]<<8) + ((dword)p_in[10]<<16) + ((dword)p_in[11]<<24)); + STR_gHashMix(a, b, c); + p_in += 12; length -= 12; + } + + // Handle the last 11 bytes + c += len; + switch(length) { + case 11: c+=((dword)p_in[10]<<24); + case 10: c+=((dword)p_in[9]<<16); + case 9 : c+=((dword)p_in[8]<<8); // the first byte of c is reserved for the length + case 8 : b+=((dword)p_in[7]<<24); + case 7 : b+=((dword)p_in[6]<<16); + case 6 : b+=((dword)p_in[5]<<8); + case 5 : b+=p_in[4]; + case 4 : a+=((dword)p_in[3]<<24); + case 3 : a+=((dword)p_in[2]<<16); + case 2 : a+=((dword)p_in[1]<<8); + case 1 : a+=p_in[0]; + } + STR_gHashMix(a, b, c); + + return c; +} + + + + +class STR_HashedString : public STR_String +{ +public: + STR_HashedString() : STR_String(),m_Hashed(false) {} + STR_HashedString(const char* str) : STR_String(str),m_Hashed(false) {} + STR_HashedString(const STR_String& str) : STR_String(str),m_Hashed(false) {} + + inline dword hash(dword init=0) const + { + if (!m_Hashed) + { + const char* str = *this; + int length = this->Length(); + m_CachedHash = STR_gHash(str,length,init); + m_Hashed=true; + } + return m_CachedHash; + } + +private: + mutable bool m_Hashed; + mutable dword m_CachedHash; +}; + +#endif //__STR_HASHSTRING + |