@@ -718,18 +718,19 @@ _shuffle_bits(Py_uhash_t h)
718718 large primes with "interesting bit patterns" and that passed tests
719719 for good collision statistics on a variety of problematic datasets
720720 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. */
722726
723727static Py_hash_t
724- frozenset_hash (PyObject * self )
728+ frozenset_hash_impl (PyObject * self )
725729{
726- PySetObject * so = ( PySetObject * ) self ;
730+ PySetObject * so = _PySet_CAST ( self ) ;
727731 Py_uhash_t hash = 0 ;
728732 setentry * entry ;
729733
730- if (so -> hash != -1 )
731- return so -> hash ;
732-
733734 /* Xor-in shuffled bits from every entry's hash field because xor is
734735 commutative and a frozenset hash should be independent of order.
735736
@@ -762,7 +763,21 @@ frozenset_hash(PyObject *self)
762763 if (hash == (Py_uhash_t )- 1 )
763764 hash = 590923713UL ;
764765
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 );
766781 return hash ;
767782}
768783
0 commit comments