… | |
… | |
114 | |
114 | |
115 | // sign0 returns -1, 0 or +1 |
115 | // sign0 returns -1, 0 or +1 |
116 | template<typename T> |
116 | template<typename T> |
117 | static inline T sign0 (T v) { return v ? sign (v) : 0; } |
117 | static inline T sign0 (T v) { return v ? sign (v) : 0; } |
118 | |
118 | |
|
|
119 | //clashes with C++0x |
119 | template<typename T, typename U> |
120 | template<typename T, typename U> |
120 | static inline T copysign (T a, U b) { return a > 0 ? b : -b; } |
121 | static inline T copysign (T a, U b) { return a > 0 ? b : -b; } |
121 | |
122 | |
122 | // div* only work correctly for div > 0 |
123 | // div* only work correctly for div > 0 |
123 | // div, with correct rounding (< 0.5 downwards, >=0.5 upwards) |
124 | // div, with correct rounding (< 0.5 downwards, >=0.5 upwards) |
… | |
… | |
511 | // use FNV-1a hash (http://isthe.com/chongo/tech/comp/fnv/) |
512 | // use FNV-1a hash (http://isthe.com/chongo/tech/comp/fnv/) |
512 | // it is about twice as fast as the one-at-a-time one, |
513 | // it is about twice as fast as the one-at-a-time one, |
513 | // with good distribution. |
514 | // with good distribution. |
514 | // FNV-1a is faster on many cpus because the multiplication |
515 | // FNV-1a is faster on many cpus because the multiplication |
515 | // runs concurrently with the looping logic. |
516 | // runs concurrently with the looping logic. |
|
|
517 | // we modify the hash a bit to improve its distribution |
516 | uint32_t hash = STRHSH_NULL; |
518 | uint32_t hash = STRHSH_NULL; |
517 | |
519 | |
518 | while (*s) |
520 | while (*s) |
519 | hash = (hash ^ *s++) * 16777619U; |
521 | hash = (hash ^ *s++) * 16777619U; |
520 | |
522 | |
521 | return hash; |
523 | return hash ^ (hash >> 16); |
522 | } |
524 | } |
523 | |
525 | |
524 | static inline uint32_t |
526 | static inline uint32_t |
525 | memhsh (const char *s, size_t len) |
527 | memhsh (const char *s, size_t len) |
526 | { |
528 | { |