}
}
- if (HvREHASH(hv)) {
- PERL_HASH_INTERNAL(hash, key, klen);
- /* We don't have a pointer to the hv, so we have to replicate the
- flag into every HEK, so that hv_iterkeysv can see it. */
- /* And yes, you do need this even though you are not "storing" because
- you can flip the flags below if doing an lval lookup. (And that
- was put in to give the semantics Andreas was expecting.) */
+ if (HvREHASH(hv) || (!hash && !(keysv && (SvIsCOW_shared_hash(keysv)))))
+ PERL_HASH_INTERNAL_(hash, key, klen, HvREHASH(hv));
+ else if (!hash)
+ hash = SvSHARED_HASH(keysv);
+
+ /* We don't have a pointer to the hv, so we have to replicate the
+ flag into every HEK, so that hv_iterkeysv can see it.
+ And yes, you do need this even though you are not "storing" because
+ you can flip the flags below if doing an lval lookup. (And that
+ was put in to give the semantics Andreas was expecting.) */
+ if (HvREHASH(hv))
flags |= HVhek_REHASH;
- } else if (!hash) {
- if (keysv && (SvIsCOW_shared_hash(keysv))) {
- hash = SvSHARED_HASH(keysv);
- } else {
- PERL_HASH(hash, key, klen);
- }
- }
masked_flags = (flags & HVhek_MASK);
HvHASKFLAGS_on(MUTABLE_SV(hv));
}
- if (HvREHASH(hv)) {
- PERL_HASH_INTERNAL(hash, key, klen);
- } else if (!hash) {
- if (keysv && (SvIsCOW_shared_hash(keysv))) {
- hash = SvSHARED_HASH(keysv);
- } else {
- PERL_HASH(hash, key, klen);
- }
- }
+ if (HvREHASH(hv) || (!hash && !(keysv && (SvIsCOW_shared_hash(keysv)))))
+ PERL_HASH_INTERNAL_(hash, key, klen, HvREHASH(hv));
+ else if (!hash)
+ hash = SvSHARED_HASH(keysv);
masked_flags = (k_flags & HVhek_MASK);
# define PERL_HASH_SEED 0
# endif
#endif
-#define PERL_HASH(hash,str,len) \
- STMT_START { \
- register const char * const s_PeRlHaSh_tmp = str; \
- register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \
- register I32 i_PeRlHaSh = len; \
- register U32 hash_PeRlHaSh = PERL_HASH_SEED; \
- while (i_PeRlHaSh--) { \
- hash_PeRlHaSh += *s_PeRlHaSh++; \
- hash_PeRlHaSh += (hash_PeRlHaSh << 10); \
- hash_PeRlHaSh ^= (hash_PeRlHaSh >> 6); \
- } \
- hash_PeRlHaSh += (hash_PeRlHaSh << 3); \
- hash_PeRlHaSh ^= (hash_PeRlHaSh >> 11); \
- (hash) = (hash_PeRlHaSh + (hash_PeRlHaSh << 15)); \
- } STMT_END
+
+#define PERL_HASH(hash,str,len) PERL_HASH_INTERNAL_(hash,str,len,0)
/* Only hv.c and mod_perl should be doing this. */
#ifdef PERL_HASH_INTERNAL_ACCESS
-#define PERL_HASH_INTERNAL(hash,str,len) \
+#define PERL_HASH_INTERNAL(hash,str,len) PERL_HASH_INTERNAL_(hash,str,len,1)
+#endif
+
+/* Common base for PERL_HASH and PERL_HASH_INTERNAL that parameterises
+ * the source of the seed. Not for direct use outside of hv.c. */
+
+#define PERL_HASH_INTERNAL_(hash,str,len,internal) \
STMT_START { \
register const char * const s_PeRlHaSh_tmp = str; \
register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \
register I32 i_PeRlHaSh = len; \
- register U32 hash_PeRlHaSh = PL_rehash_seed; \
+ register U32 hash_PeRlHaSh = (internal ? PL_rehash_seed : PERL_HASH_SEED); \
while (i_PeRlHaSh--) { \
hash_PeRlHaSh += *s_PeRlHaSh++; \
hash_PeRlHaSh += (hash_PeRlHaSh << 10); \
hash_PeRlHaSh ^= (hash_PeRlHaSh >> 11); \
(hash) = (hash_PeRlHaSh + (hash_PeRlHaSh << 15)); \
} STMT_END
-#endif
/*
=head1 Hash Manipulation Functions