(&self, vm: &VirtualMachine)
| 438 | } |
| 439 | |
| 440 | fn hash(&self, vm: &VirtualMachine) -> PyResult<PyHash> { |
| 441 | // Work to increase the bit dispersion for closely spaced hash values. |
| 442 | // This is important because some use cases have many combinations of a |
| 443 | // small number of elements with nearby hashes so that many distinct |
| 444 | // combinations collapse to only a handful of distinct hash values. |
| 445 | const fn _shuffle_bits(h: u64) -> u64 { |
| 446 | ((h ^ 89869747) ^ (h.wrapping_shl(16))).wrapping_mul(3644798167) |
| 447 | } |
| 448 | // Factor in the number of active entries |
| 449 | let mut hash: u64 = (self.len() as u64 + 1).wrapping_mul(1927868237); |
| 450 | // Xor-in shuffled bits from every entry's hash field because xor is |
| 451 | // commutative and a frozenset hash should be independent of order. |
| 452 | hash = self.content.try_fold_keys(hash, |h, element| { |
| 453 | Ok(h ^ _shuffle_bits(element.hash(vm)? as u64)) |
| 454 | })?; |
| 455 | // Disperse patterns arising in nested frozen-sets |
| 456 | hash ^= (hash >> 11) ^ (hash >> 25); |
| 457 | hash = hash.wrapping_mul(69069).wrapping_add(907133923); |
| 458 | // -1 is reserved as an error code |
| 459 | if hash == u64::MAX { |
| 460 | hash = 590923713; |
| 461 | } |
| 462 | Ok(hash as PyHash) |
| 463 | } |
| 464 | |
| 465 | // Run operation, on failure, if item is a set/set subclass, convert it |
| 466 | // into a frozenset and try the operation again. Propagates original error |
nothing calls this directly
no test coverage detected