Skip to content

Commit 0c25fee

Browse files
committed
Teach fasthash_accum to use platform endianness for bytewise loads
This function previously used a mix of word-wise loads and bytewise loads. The bytewise loads happened to be little-endian regardless of platform. This in itself is not a problem. However, a future commit will require the same result whether A) the input is loaded as a word with the relevent bytes masked-off, or B) the input is loaded one byte at a time. While at it, improve debuggability of the internal hash state. Discussion: https://postgr.es/m/CANWCAZZpuV1mES1mtSpAq8tWJewbrv4gEz6R_k4gzNG8GZ5gag%40mail.gmail.com
1 parent 98f320e commit 0c25fee

File tree

1 file changed

+39
-5
lines changed

1 file changed

+39
-5
lines changed

src/include/common/hashfn_unstable.h

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,6 @@ fasthash_combine(fasthash_state *hs)
131131
{
132132
hs->hash ^= fasthash_mix(hs->accum, 0);
133133
hs->hash *= 0x880355f21e6d1965;
134-
135-
/* reset hash state for next input */
136-
hs->accum = 0;
137134
}
138135

139136
/* accumulate up to 8 bytes of input and combine it into the hash */
@@ -142,9 +139,44 @@ fasthash_accum(fasthash_state *hs, const char *k, size_t len)
142139
{
143140
uint32 lower_four;
144141

145-
Assert(hs->accum == 0);
146142
Assert(len <= FH_SIZEOF_ACCUM);
143+
hs->accum = 0;
147144

145+
/*
146+
* For consistency, bytewise loads must match the platform's endianness.
147+
*/
148+
#ifdef WORDS_BIGENDIAN
149+
switch (len)
150+
{
151+
case 8:
152+
memcpy(&hs->accum, k, 8);
153+
break;
154+
case 7:
155+
hs->accum |= (uint64) k[6] << 8;
156+
/* FALLTHROUGH */
157+
case 6:
158+
hs->accum |= (uint64) k[5] << 16;
159+
/* FALLTHROUGH */
160+
case 5:
161+
hs->accum |= (uint64) k[4] << 24;
162+
/* FALLTHROUGH */
163+
case 4:
164+
memcpy(&lower_four, k, sizeof(lower_four));
165+
hs->accum |= (uint64) lower_four << 32;
166+
break;
167+
case 3:
168+
hs->accum |= (uint64) k[2] << 40;
169+
/* FALLTHROUGH */
170+
case 2:
171+
hs->accum |= (uint64) k[1] << 48;
172+
/* FALLTHROUGH */
173+
case 1:
174+
hs->accum |= (uint64) k[0] << 56;
175+
break;
176+
case 0:
177+
return;
178+
}
179+
#else
148180
switch (len)
149181
{
150182
case 8:
@@ -175,6 +207,7 @@ fasthash_accum(fasthash_state *hs, const char *k, size_t len)
175207
case 0:
176208
return;
177209
}
210+
#endif
178211

179212
fasthash_combine(hs);
180213
}
@@ -288,7 +321,8 @@ fasthash_accum_cstring(fasthash_state *hs, const char *str)
288321
if (PointerIsAligned(str, uint64))
289322
{
290323
len = fasthash_accum_cstring_aligned(hs, str);
291-
Assert(hs_check.hash == hs->hash && len_check == len);
324+
Assert(len_check == len);
325+
Assert(hs_check.hash == hs->hash);
292326
return len;
293327
}
294328
#endif /* SIZEOF_VOID_P */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy