@@ -718,18 +718,19 @@ _shuffle_bits(Py_uhash_t h)
718
718
large primes with "interesting bit patterns" and that passed tests
719
719
for good collision statistics on a variety of problematic datasets
720
720
including powersets and graph structures (such as David Eppstein's
721
- graph recipes in Lib/test/test_set.py) */
721
+ graph recipes in Lib/test/test_set.py).
722
+
723
+ This hash algorithm can be used on either a frozenset or a set.
724
+ When it is used on a set, it computes the hash value of the equivalent
725
+ frozenset without creating a new frozenset object. */
722
726
723
727
static Py_hash_t
724
- frozenset_hash (PyObject * self )
728
+ frozenset_hash_impl (PyObject * self )
725
729
{
726
- PySetObject * so = ( PySetObject * ) self ;
730
+ PySetObject * so = _PySet_CAST ( self ) ;
727
731
Py_uhash_t hash = 0 ;
728
732
setentry * entry ;
729
733
730
- if (so -> hash != -1 )
731
- return so -> hash ;
732
-
733
734
/* Xor-in shuffled bits from every entry's hash field because xor is
734
735
commutative and a frozenset hash should be independent of order.
735
736
@@ -762,7 +763,21 @@ frozenset_hash(PyObject *self)
762
763
if (hash == (Py_uhash_t )- 1 )
763
764
hash = 590923713UL ;
764
765
765
- so -> hash = hash ;
766
+ return (Py_hash_t )hash ;
767
+ }
768
+
769
+ static Py_hash_t
770
+ frozenset_hash (PyObject * self )
771
+ {
772
+ PySetObject * so = _PySet_CAST (self );
773
+ Py_uhash_t hash ;
774
+
775
+ if (FT_ATOMIC_LOAD_SSIZE_RELAXED (so -> hash ) != -1 ) {
776
+ return FT_ATOMIC_LOAD_SSIZE_RELAXED (so -> hash );
777
+ }
778
+
779
+ hash = frozenset_hash_impl (self );
780
+ FT_ATOMIC_STORE_SSIZE_RELAXED (so -> hash , hash );
766
781
return hash ;
767
782
}
768
783
0 commit comments