diff options
Diffstat (limited to 'indra/llprimitive/llmaterialid.h')
| -rw-r--r-- | indra/llprimitive/llmaterialid.h | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h index bd6256d961..41dd5a8710 100644 --- a/indra/llprimitive/llmaterialid.h +++ b/indra/llprimitive/llmaterialid.h @@ -67,15 +67,11 @@ public: static const LLMaterialID null; - // Returns a 64 bits digest of the material Id, by XORing its two 64 bits - // long words. HB - inline U64 getDigest64() const - { - U64* tmp = (U64*)mID; - return tmp[0] ^ tmp[1]; - } - private: + // definitions follow class + friend std::hash<LLMaterialID>; + friend size_t hash_value(const LLMaterialID&) noexcept; + void parseFromBinary(const LLSD::Binary& pMaterialID); void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID); int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const; @@ -90,15 +86,27 @@ namespace std { inline size_t operator()(const LLMaterialID& id) const noexcept { - return (size_t)id.getDigest64(); + size_t h = 0; + // Golden ratio hash with avalanche mixing + // Process 8 bytes at a time by manually constructing 64-bit values + // Shift by 31: mixes upper half into lower half for better bit distribution + // Shift by 47: ensures highest bits influence final hash output + for (int i = 0; i < MATERIAL_ID_SIZE; i += 8) { + size_t chunk = (size_t)id.mID[i] | ((size_t)id.mID[i + 1] << 8) | + ((size_t)id.mID[i+2] << 16) | ((size_t)id.mID[i+3] << 24) | + ((size_t)id.mID[i+4] << 32) | ((size_t)id.mID[i+5] << 40) | + ((size_t)id.mID[i + 6] << 48) | ((size_t)id.mID[i + 7] << 56); + h ^= (chunk * 0x9e3779b97f4a7c15ULL) ^ (h >> 31) ^ (h >> 47); + } + return h; } }; } -// For use with boost containers. +// For use with boost::container_hash inline size_t hash_value(const LLMaterialID& id) noexcept { - return (size_t)id.getDigest64(); + return std::hash<LLMaterialID>{}(id); } #endif // LL_LLMATERIALID_H |
