[webkit-changes] cvs commit: WebCore/kwq KWQCharsets.mm KWQString.h KWQString.mm KWQTextCodec.mm

Maciej mjs at opensource.apple.com
Mon Jun 27 18:54:36 PDT 2005


mjs         05/06/27 18:54:36

  Modified:    .        ChangeLog
               WebCore.pbproj project.pbxproj
               khtml/xml dom_atomicstring.cpp dom_atomicstring.h
                        dom_stringimpl.cpp
               kwq      KWQCharsets.mm KWQString.h KWQString.mm
                        KWQTextCodec.mm
  Log:
          Reviewed by Darin.
  
  	- replaced all our hash functions with the state of the art in hashing
  	- ~1% speedup on cvs-base
  
          No test cases added, perf effects only.
  
          * khtml/xml/dom_atomicstring.cpp:
          (DOM::AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger):
  	Improved stats gathering to track collisions in more detail and count reinserts
  	on remove.
          (DOM::addToCollisionCount): ditto
          (DOM::AtomicString::add): ditto
          (DOM::AtomicString::insert): ditto
          (DOM::AtomicString::remove): ditto
          * khtml/xml/dom_stringimpl.cpp:
          (DOM::DOMStringImpl::computeHash): Replace with SuperFastHash algorithm.
          * kwq/KWQCharsets.mm:
          (encodingNameHash): Clean up mistaken shift in the wrong direction.
          * kwq/KWQString.h: Removed unused hashing code.
          * kwq/KWQString.mm: ditto
          * kwq/KWQTextCodec.mm:
          (QTextCodec::hash): Use a variant of the SuperFastHash algorithm.
  
  Revision  Changes    Path
  1.4319    +26 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.4318
  retrieving revision 1.4319
  diff -u -r1.4318 -r1.4319
  --- ChangeLog	27 Jun 2005 19:12:30 -0000	1.4318
  +++ ChangeLog	28 Jun 2005 01:54:29 -0000	1.4319
  @@ -1,3 +1,29 @@
  +2005-06-26  Maciej Stachowiak  <mjs at apple.com>
  +
  +        Reviewed by Darin.
  +
  +	- replaced all our hash functions with the state of the art in hashing
  +	- ~1% speedup on cvs-base
  +	
  +        No test cases added, perf effects only.
  +
  +        * khtml/xml/dom_atomicstring.cpp:
  +        (DOM::AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger):
  +	Improved stats gathering to track collisions in more detail and count reinserts
  +	on remove.
  +        (DOM::addToCollisionCount): ditto
  +        (DOM::AtomicString::add): ditto
  +        (DOM::AtomicString::insert): ditto
  +        (DOM::AtomicString::remove): ditto
  +        * khtml/xml/dom_stringimpl.cpp:
  +        (DOM::DOMStringImpl::computeHash): Replace with SuperFastHash algorithm.
  +        * kwq/KWQCharsets.mm:
  +        (encodingNameHash): Clean up mistaken shift in the wrong direction.
  +        * kwq/KWQString.h: Removed unused hashing code.
  +        * kwq/KWQString.mm: ditto
  +        * kwq/KWQTextCodec.mm:
  +        (QTextCodec::hash): Use a variant of the SuperFastHash algorithm.
  +
   2005-06-27  David Harrison  <harrison at apple.com>
   
           Reviewed by Ken.
  
  
  
  1.557     +48 -0     WebCore/WebCore.pbproj/project.pbxproj
  
  Index: project.pbxproj
  ===================================================================
  RCS file: /cvs/root/WebCore/WebCore.pbproj/project.pbxproj,v
  retrieving revision 1.556
  retrieving revision 1.557
  diff -u -r1.556 -r1.557
  --- project.pbxproj	22 Jun 2005 15:31:57 -0000	1.556
  +++ project.pbxproj	28 Jun 2005 01:54:34 -0000	1.557
  @@ -1279,6 +1279,48 @@
   			settings = {
   			};
   		};
  +		65F378260870D958000B2F94 = {
  +			fileEncoding = 30;
  +			isa = PBXFileReference;
  +			lastKnownFileType = sourcecode.c.h;
  +			path = hashset.h;
  +			refType = 4;
  +			sourceTree = "<group>";
  +		};
  +		65F378270870D958000B2F94 = {
  +			fileEncoding = 30;
  +			isa = PBXFileReference;
  +			lastKnownFileType = sourcecode.cpp.cpp;
  +			path = hashtable.cpp;
  +			refType = 4;
  +			sourceTree = "<group>";
  +		};
  +		65F378280870D958000B2F94 = {
  +			fileEncoding = 30;
  +			isa = PBXFileReference;
  +			lastKnownFileType = sourcecode.c.h;
  +			path = hashtable.h;
  +			refType = 4;
  +			sourceTree = "<group>";
  +		};
  +		65F378290870D958000B2F94 = {
  +			fileRef = 65F378260870D958000B2F94;
  +			isa = PBXBuildFile;
  +			settings = {
  +			};
  +		};
  +		65F3782A0870D958000B2F94 = {
  +			fileRef = 65F378270870D958000B2F94;
  +			isa = PBXBuildFile;
  +			settings = {
  +			};
  +		};
  +		65F3782B0870D958000B2F94 = {
  +			fileRef = 65F378280870D958000B2F94;
  +			isa = PBXBuildFile;
  +			settings = {
  +			};
  +		};
   		65F80697054D9F86008BF776 = {
   			fileEncoding = 30;
   			isa = PBXFileReference;
  @@ -2724,6 +2766,8 @@
   				1A69D381085627410009880D,
   				550A0BCA085F6039007353D6,
   				550A0BCE085F604D007353D6,
  +				65F378290870D958000B2F94,
  +				65F3782B0870D958000B2F94,
   			);
   			isa = PBXHeadersBuildPhase;
   			runOnlyForDeploymentPostprocessing = 0;
  @@ -5097,6 +5141,7 @@
   				1A69D382085627410009880D,
   				550A0BC9085F6039007353D6,
   				550A0BCD085F604D007353D6,
  +				65F3782A0870D958000B2F94,
   			);
   			isa = PBXSourcesBuildPhase;
   			runOnlyForDeploymentPostprocessing = 0;
  @@ -8790,6 +8835,9 @@
   		};
   		F523D29C02DE43D9018635CA = {
   			children = (
  +				65F378260870D958000B2F94,
  +				65F378270870D958000B2F94,
  +				65F378280870D958000B2F94,
   				BC7294F703804B3C00A80166,
   				BC7294F803804B3C00A80166,
   				F523D27802DE43D7018635CA,
  
  
  
  1.4       +70 -16    WebCore/khtml/xml/dom_atomicstring.cpp
  
  Index: dom_atomicstring.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_atomicstring.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- dom_atomicstring.cpp	5 Feb 2004 01:45:16 -0000	1.3
  +++ dom_atomicstring.cpp	28 Jun 2005 01:54:34 -0000	1.4
  @@ -43,8 +43,13 @@
   
   #if DUMP_STATISTICS
       
  -static int numProbes;
  +static int numAccesses;
   static int numCollisions;
  +static int collisionGraph[4096];
  +static int maxCollisions;
  +static int numRehashes;
  +static int numRemoves;
  +static int numReinserts;
   
   struct AtomicStringStatisticsExitLogger { ~AtomicStringStatisticsExitLogger(); };
   
  @@ -52,11 +57,24 @@
   
   AtomicStringStatisticsExitLogger::~AtomicStringStatisticsExitLogger()
   {
  -    printf("\nDOM::AtomicString statistics\n\n");
  -    printf("%d probes\n", numProbes);
  -    printf("%d collisions (%.1f%%)\n", numCollisions, 100.0 * numCollisions / numProbes);
  +    printf("\nkhtml::HashTable statistics\n\n");
  +    printf("%d accesses\n", numAccesses);
  +    printf("%d total collisions, average %.2f probes per access\n", numCollisions, 1.0 * (numAccesses + numCollisions) / numAccesses);
  +    printf("longest collision chain: %d\n", maxCollisions);
  +    for (int i = 1; i <= maxCollisions; i++) {
  +        printf("  %d lookups with exactly %d collisions (%.2f%% , %.2f%% with this many or more)\n", collisionGraph[i], i, 100.0 * (collisionGraph[i] - collisionGraph[i+1]) / numAccesses, 100.0 * collisionGraph[i] / numAccesses);
  +    }
  +    printf("%d rehashes\n", numRehashes);
  +    printf("%d removes, %d reinserts\n", numRemoves, numReinserts);
   }
   
  +static void recordCollisionAtCount(int count)
  +{
  +    if (count > maxCollisions)
  +        maxCollisions = count;
  +    numCollisions++;
  +    collisionGraph[count]++;
  +}
   #endif
   
   const int _minTableSize = 64;
  @@ -79,6 +97,11 @@
       return s[length] == 0;
   }
   
  +bool AtomicString::equal(const AtomicString &a, const char *b)
  +{ 
  +    return equal(a.m_string.implementation(), b); 
  +}
  +
   bool AtomicString::equal(DOMStringImpl *r, const QChar *s, uint length)
   {
       if (!r && !s) return true;
  @@ -123,12 +146,16 @@
       
       int i = hash & _tableSizeMask;
   #if DUMP_STATISTICS
  -    ++numProbes;
  -    numCollisions += _table[i] && !equal(_table[i], c);
  +    ++numAccesses;
  +    int collisionCount = 0;
   #endif
       while (DOMStringImpl *key = _table[i]) {
           if (equal(key, c))
               return key;
  +#if DUMP_STATISTICS
  +        ++collisionCount;
  +        recordCollisionAtCount(collisionCount);
  +#endif
           i = (i + 1) & _tableSizeMask;
       }
       
  @@ -160,12 +187,16 @@
       
       int i = hash & _tableSizeMask;
   #if DUMP_STATISTICS
  -    ++numProbes;
  -    numCollisions += _table[i] && !equal(_table[i], s, length);
  +    ++numAccesses;
  +    int collisionCount = 0;
   #endif
       while (DOMStringImpl *key = _table[i]) {
           if (equal(key, s, length))
               return key;
  +#if DUMP_STATISTICS
  +        ++collisionCount;
  +        recordCollisionAtCount(collisionCount);
  +#endif
           i = (i + 1) & _tableSizeMask;
       }
       
  @@ -197,13 +228,17 @@
       
       int i = hash & _tableSizeMask;
   #if DUMP_STATISTICS
  -    ++numProbes;
  -    numCollisions += _table[i] && !equal(_table[i], r);
  +    ++numAccesses;
  +    int collisionCount = 0;
   #endif
       while (DOMStringImpl *key = _table[i]) {
           if (equal(key, r)) {
               return key;
           }
  +#if DUMP_STATISTICS
  +        ++collisionCount;
  +        recordCollisionAtCount(collisionCount);
  +#endif
           i = (i + 1) & _tableSizeMask;
       }
   
  @@ -223,12 +258,16 @@
       
       int i = hash & _tableSizeMask;
   #if DUMP_STATISTICS
  -    ++numProbes;
  -    numCollisions += _table[i] != 0;
  +    ++numAccesses;
  +    int collisionCount = 0;
  +#endif
  +    while (_table[i] && !(key == _table[i])) {
  +#if DUMP_STATISTICS
  +        ++collisionCount;
  +        recordCollisionAtCount(collisionCount);
   #endif
  -    while (_table[i])
           i = (i + 1) & _tableSizeMask;
  -    
  +    }
       _table[i] = key;
   }
   
  @@ -240,12 +279,17 @@
       
       int i = hash & _tableSizeMask;
   #if DUMP_STATISTICS
  -    ++numProbes;
  -    numCollisions += _table[i] && equal(_table[i], r);
  +    ++numRemoves;
  +    ++numAccesses;
  +    int collisionCount = 0;
   #endif
       while ((key = _table[i])) {
           if (key == r)
               break;
  +#if DUMP_STATISTICS
  +        ++collisionCount;
  +        recordCollisionAtCount(collisionCount);
  +#endif
           i = (i + 1) & _tableSizeMask;
       }
       if (!key)
  @@ -265,6 +309,9 @@
           key = _table[i];
           if (!key)
               break;
  +#if DUMP_STATISTICS
  +        ++numReinserts;
  +#endif
           _table[i] = 0;
           insert(key);
       }
  @@ -272,11 +319,13 @@
   
   void AtomicString::expand()
   {
  +    printf("grow from size %d to size %d at keyCount %d\n", m_tableSize, m_minTableSize : m_tableSize * 2, m_keyCount); 
       rehash(_tableSize == 0 ? _minTableSize : _tableSize * 2);
   }
   
   void AtomicString::shrink()
   {
  +    printf("shrink from size %d to size %d at keyCount %d\n", m_tableSize, m_tableSize/2, m_keyCount); 
       rehash(_tableSize / 2);
   }
   
  @@ -285,6 +334,11 @@
       int oldTableSize = _tableSize;
       DOMStringImpl **oldTable = _table;
       
  +#if DUMP_STATISTICS
  +    if (oldTableSize != 0)
  +        ++numRehashes;
  +#endif
  +
       _tableSize = newTableSize;
       _tableSizeMask = newTableSize - 1;
       _table = (DOMStringImpl **)calloc(newTableSize, sizeof(DOMStringImpl *));
  
  
  
  1.4       +1 -2      WebCore/khtml/xml/dom_atomicstring.h
  
  Index: dom_atomicstring.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_atomicstring.h,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- dom_atomicstring.h	21 Jun 2005 22:27:55 -0000	1.3
  +++ dom_atomicstring.h	28 Jun 2005 01:54:34 -0000	1.4
  @@ -80,8 +80,7 @@
       
       static bool equal(const AtomicString &a, const AtomicString &b)
       { return a.m_string.implementation() == b.m_string.implementation(); }
  -    static bool equal(const AtomicString &a, const char *b)
  -    { return equal(a.m_string.implementation(), b); }
  +    static bool equal(const AtomicString &a, const char *b);
       
       static DOMStringImpl *add(const char *);
       static DOMStringImpl *add(const QChar *, int length);
  
  
  
  1.28      +77 -56    WebCore/khtml/xml/dom_stringimpl.cpp
  
  Index: dom_stringimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_stringimpl.cpp,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- dom_stringimpl.cpp	21 Jun 2005 22:27:55 -0000	1.27
  +++ dom_stringimpl.cpp	28 Jun 2005 01:54:34 -0000	1.28
  @@ -443,73 +443,94 @@
   // or anything like that.
   const unsigned PHI = 0x9e3779b9U;
   
  -// This hash algorithm comes from:
  -// http://burtleburtle.net/bob/hash/hashfaq.html
  -// http://burtleburtle.net/bob/hash/doobs.html
  -unsigned DOMStringImpl::computeHash(const QChar *s, int length)
  +// Paul Hsieh's SuperFastHash
  +// http://www.azillionmonkeys.com/qed/hash.html
  +unsigned DOMStringImpl::computeHash(const QChar *s, int len)
   {
  -    int prefixLength = length < 8 ? length : 8;
  -    int suffixPosition = length < 16 ? 8 : length - 8;
  -    
  -    unsigned h = PHI;
  -    h += length;
  -    h += (h << 10); 
  -    h ^= (h << 6); 
  -    
  -    for (int i = 0; i < prefixLength; i++) {
  -        h += s[i].unicode(); 
  -	h += (h << 10); 
  -	h ^= (h << 6); 
  -    }
  -    for (int i = suffixPosition; i < length; i++){
  -        h += s[i].unicode(); 
  -	h += (h << 10); 
  -	h ^= (h << 6); 
  +    unsigned l = len;
  +    uint32_t hash = PHI;
  +    uint32_t tmp;
  +    
  +    int rem = l & 1;
  +    l >>= 1;
  +    
  +    // Main loop
  +    for (; l > 0; l--) {
  +        hash += s[0].unicode();
  +        tmp = (s[1].unicode() << 11) ^ hash;
  +        hash = (hash << 16) ^ tmp;
  +        s += 2;
  +        hash += hash >> 11;
       }
       
  -    h += (h << 3);
  -    h ^= (h >> 11);
  -    h += (h << 15);
  -    
  -    if (h == 0)
  -        h = 0x80000000;
  +    // Handle end case
  +    if (rem) {
  +        hash += s[0].unicode();
  +        hash ^= hash << 11;
  +        hash += hash >> 17;
  +    }
  +
  +    // Force "avalanching" of final 127 bits
  +    hash ^= hash << 3;
  +    hash += hash >> 5;
  +    hash ^= hash << 2;
  +    hash += hash >> 15;
  +    hash ^= hash << 10;
  +
  +    // this avoids ever returning a hash code of 0, since that is used to
  +    // signal "hash not computed yet", using a value that is likely to be
  +    // effectively the same as 0 when the low bits are masked
  +    if (hash == 0)
  +        hash = 0x80000000;
       
  -    return h;
  +    return hash;
   }
   
  -// This hash algorithm comes from:
  -// http://burtleburtle.net/bob/hash/hashfaq.html
  -// http://burtleburtle.net/bob/hash/doobs.html
  +// Paul Hsieh's SuperFastHash
  +// http://www.azillionmonkeys.com/qed/hash.html
   unsigned DOMStringImpl::computeHash(const char *s)
   {
  -    int length = strlen(s);
  -    int prefixLength = length < 8 ? length : 8;
  -    int suffixPosition = length < 16 ? 8 : length - 8;
  -    
  -    unsigned h = PHI;
  -    h += length;
  -    h += (h << 10); 
  -    h ^= (h << 6); 
  -    
  -    for (int i = 0; i < prefixLength; i++) {
  -        h += (unsigned char)s[i];
  -	h += (h << 10); 
  -	h ^= (h << 6); 
  -    }
  -    for (int i = suffixPosition; i < length; i++) {
  -        h += (unsigned char)s[i];
  -	h += (h << 10); 
  -	h ^= (h << 6); 
  +    // This hash is designed to work on 16-bit chunks at a time. But since the normal case
  +    // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
  +    // were 16-bit chunks, which should give matching results
  +
  +    unsigned l = strlen(s);
  +    uint32_t hash = PHI;
  +    uint32_t tmp;
  +    
  +    int rem = l & 1;
  +    l >>= 1;
  +    
  +    // Main loop
  +    for (; l > 0; l--) {
  +        hash += (unsigned char)s[0];
  +        tmp = ((unsigned char)s[1] << 11) ^ hash;
  +        hash = (hash << 16) ^ tmp;
  +        s += 2;
  +        hash += hash >> 11;
       }
       
  -    h += (h << 3);
  -    h ^= (h >> 11);
  -    h += (h << 15);
  -    
  -    if (h == 0)
  -        h = 0x80000000;
  +    // Handle end case
  +    if (rem) {
  +        hash += (unsigned char)s[0];
  +        hash ^= hash << 11;
  +        hash += hash >> 17;
  +    }
  +
  +    // Force "avalanching" of final 127 bits
  +    hash ^= hash << 3;
  +    hash += hash >> 5;
  +    hash ^= hash << 2;
  +    hash += hash >> 15;
  +    hash ^= hash << 10;
  +
  +    // this avoids ever returning a hash code of 0, since that is used to
  +    // signal "hash not computed yet", using a value that is likely to be
  +    // effectively the same as 0 when the low bits are masked
  +    if (hash == 0)
  +        hash = 0x80000000;
       
  -    return h;
  +    return hash;
   }
   
   const char *DOMStringImpl::ascii() const
  
  
  
  1.22      +1 -1      WebCore/kwq/KWQCharsets.mm
  
  Index: KWQCharsets.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQCharsets.mm,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- KWQCharsets.mm	20 Aug 2003 22:31:04 -0000	1.21
  +++ KWQCharsets.mm	28 Jun 2005 01:54:35 -0000	1.22
  @@ -142,7 +142,7 @@
           }
           h += tolower(c);
   	h += (h << 10); 
  -	h ^= (h << 6); 
  +	h ^= (h >> 6); 
       }
   
       h += (h << 3);
  
  
  
  1.113     +0 -4      WebCore/kwq/KWQString.h
  
  Index: KWQString.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQString.h,v
  retrieving revision 1.112
  retrieving revision 1.113
  diff -u -r1.112 -r1.113
  --- KWQString.h	24 Jun 2005 18:57:22 -0000	1.112
  +++ KWQString.h	28 Jun 2005 01:54:35 -0000	1.113
  @@ -561,8 +561,6 @@
   
       void reserve(uint);
   
  -    uint hash() const;
  -
       bool operator!() const;
   
       const QChar operator[](int) const;
  @@ -763,6 +761,4 @@
       const QString &string() const { return *this; }
   };
   
  -extern const CFDictionaryKeyCallBacks CFDictionaryQStringKeyCallBacks;
  -
   #endif
  
  
  
  1.139     +0 -81     WebCore/kwq/KWQString.mm
  
  Index: KWQString.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQString.mm,v
  retrieving revision 1.138
  retrieving revision 1.139
  diff -u -r1.138 -r1.139
  --- KWQString.mm	26 Apr 2005 18:46:04 -0000	1.138
  +++ KWQString.mm	28 Jun 2005 01:54:35 -0000	1.139
  @@ -2755,60 +2755,6 @@
       return chs[len] == '\0';
   }
   
  -// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
  -// or anything like that.
  -const unsigned PHI = 0x9e3779b9U;
  -
  -// This hash algorithm comes from:
  -// http://burtleburtle.net/bob/hash/hashfaq.html
  -// http://burtleburtle.net/bob/hash/doobs.html
  -uint QString::hash() const
  -{
  -    uint len = length();
  -
  -    uint h = PHI;
  -    h += len;
  -    h += (h << 10); 
  -    h ^= (h << 6); 
  -
  -    if (len) {
  -        uint prefixLength = len < 8 ? len : 8;
  -        uint suffixPosition = len < 16 ? 8 : len - 8;
  -    
  -        if (dataHandle[0]->_isAsciiValid) {
  -            const char *s = ascii();
  -            for (uint i = 0; i < prefixLength; i++) {
  -		h += (unsigned char)s[i];
  -		h += (h << 10); 
  -		h ^= (h << 6); 
  -	    }
  -            for (uint i = suffixPosition; i < len; i++) {
  -		h += (unsigned char)s[i];
  -		h += (h << 10); 
  -		h ^= (h << 6); 
  -	    }
  -        } else {
  -            const QChar *s = unicode();
  -            for (uint i = 0; i < prefixLength; i++) {
  -		h += s[i].unicode();
  -		h += (h << 10); 
  -		h ^= (h << 6); 
  -	    }
  -            for (uint i = suffixPosition; i < len; i++) {
  -		h += s[i].unicode();
  -		h += (h << 10); 
  -		h ^= (h << 6); 
  -	    }
  -        }
  -    }
  -
  -    h += (h << 3);
  -    h ^= (h >> 11);
  -    h += (h << 15);
  - 
  -    return h;
  -}
  -
   QString operator+(const QString &qs1, const QString &qs2)
   {
       return QString(qs1) += qs2;
  @@ -2870,33 +2816,6 @@
       }
   }
   
  -const void *retainQString(CFAllocatorRef allocator, const void *value)
  -{
  -    return new QString(*(QString *)value);
  -}
  -
  -void releaseQString(CFAllocatorRef allocator, const void *value)
  -{
  -    delete (QString *)value;
  -}
  -
  -CFStringRef describeQString(const void *value)
  -{
  -    return ((QString *)value)->getCFString();
  -}
  -
  -Boolean equalQString(const void *value1, const void *value2)
  -{
  -    return *(QString *)value1 == *(QString *)value2;
  -}
  -
  -CFHashCode hashQString(const void *value)
  -{
  -    return ((QString *)value)->hash();
  -}
  -
  -const CFDictionaryKeyCallBacks CFDictionaryQStringKeyCallBacks = { 0, retainQString, releaseQString, describeQString, equalQString, hashQString };
  -
   #define NODE_BLOCK_SIZE ((vm_page_size)/sizeof(HandleNode))
   
   #define TO_NODE_OFFSET(ptr)   ((uint)(((uint)ptr - (uint)base)/sizeof(HandleNode)))
  
  
  
  1.51      +25 -10    WebCore/kwq/KWQTextCodec.mm
  
  Index: KWQTextCodec.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQTextCodec.mm,v
  retrieving revision 1.50
  retrieving revision 1.51
  diff -u -r1.50 -r1.51
  --- KWQTextCodec.mm	17 Jun 2005 16:41:05 -0000	1.50
  +++ KWQTextCodec.mm	28 Jun 2005 01:54:35 -0000	1.51
  @@ -187,20 +187,35 @@
       return a._encoding == b._encoding && a._flags == b._flags;
   }
   
  +// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
  +// or anything like that.
  +const unsigned PHI = 0x9e3779b9U;
  +
  +// Paul Hsieh's SuperFastHash
  +// http://www.azillionmonkeys.com/qed/hash.html
  +// Adapted assuming _encoding is 32 bits and _flags is at most 16 bits
   unsigned QTextCodec::hash() const
   {
  -    unsigned h = _encoding;
  -
  -    h += (h << 10);
  -    h ^= (h << 6);
  +    uint32_t hash = PHI;
  +    uint32_t tmp;
       
  -    h ^= _flags;
  +    hash += _encoding & 0xffff;
  +    tmp = ((_encoding >> 16) << 11) ^ hash;
  +    hash = (hash << 16) ^ tmp;
  +    hash += hash >> 11;
  +    
  +    hash += _flags & 0xffff;
  +    hash ^= hash << 11;
  +    hash += hash >> 17;
  +
  +    // Force "avalanching" of final 127 bits
  +    hash ^= hash << 3;
  +    hash += hash >> 5;
  +    hash ^= hash << 2;
  +    hash += hash >> 15;
  +    hash ^= hash << 10;
   
  -    h += (h << 3);
  -    h ^= (h >> 11);
  -    h += (h << 15);
  -    
  -    return h;
  +    return hash;
   }
   
   static Boolean QTextCodecsEqual(const void *a, const void *b)
  
  
  



More information about the webkit-changes mailing list