Skip to content

Commit 818fdbd

Browse files
committed
interrogate: Tidy up hash_string function
The main motivation behind this change is to get rid of a signed integer overflow that sometimes happens in the prime multiplication step, which is (per the C++ spec) undefined behavior. However, it's probably for the best to use only unsigned int when the function is clearly trying to avoid negative values. Not that I suspect it matters much, but I have also heavily tested that the behavior of the function is unchanged (at least on PC hardware - signed integer overflow doesn't behave portably) although it may now be slightly faster due to the fact that I have removed the floating-point math.
1 parent 9520314 commit 818fdbd

File tree

1 file changed

+9
-11
lines changed

1 file changed

+9
-11
lines changed

dtool/src/interrogate/interrogateBuilder.cxx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -656,13 +656,13 @@ get_preferred_name(CPPType *type) {
656656
*/
657657
string InterrogateBuilder::
658658
hash_string(const string &name, int shift_offset) {
659-
int hash = 0;
659+
unsigned int hash = 0;
660660

661-
int shift = 0;
661+
unsigned int shift = 0;
662662
string::const_iterator ni;
663663
for (ni = name.begin(); ni != name.end(); ++ni) {
664-
int c = (int)(unsigned char)(*ni);
665-
int shifted_c = (c << shift) & 0xffffff;
664+
unsigned int c = (unsigned char)*ni;
665+
unsigned int shifted_c = (c << shift) & 0xffffff;
666666
if (shift > 16) {
667667
// We actually want a circular shift, not an arithmetic shift.
668668
shifted_c |= ((c >> (24 - shift)) & 0xff) ;
@@ -675,10 +675,9 @@ hash_string(const string &name, int shift_offset) {
675675
// bits back at the bottom, to scramble up the bits a bit. This helps
676676
// reduce hash conflicts from names that are similar to each other, by
677677
// separating adjacent hash codes.
678-
int prime = 4999;
679-
int low_order = (hash * prime) & 0xffffff;
680-
int high_order = (int)((double)hash * (double)prime / (double)(1 << 24));
681-
hash = low_order ^ high_order;
678+
const unsigned int prime = 4999;
679+
unsigned long long product = (unsigned long long)hash * prime;
680+
hash = (product ^ (product >> 24)) & 0xffffff;
682681

683682
// Also add in the additional_number, times some prime factor. hash = (hash
684683
// + additional_number * 1657) & 0xffffff;
@@ -690,10 +689,9 @@ hash_string(const string &name, int shift_offset) {
690689
// deal, since we have to resolve hash conflicts anyway.
691690

692691
string result;
693-
int extract_h = hash;
694692
for (int i = 0; i < 4; i++) {
695-
int value = (extract_h & 0x3f);
696-
extract_h >>= 6;
693+
unsigned int value = (hash & 0x3f);
694+
hash >>= 6;
697695
if (value < 26) {
698696
result += (char)('A' + value);
699697

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy