Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a91e2fa

Browse files
committed
Adapt hashfn.c and hashutils.h for frontend use.
hash_any() and its various variants are defined to return Datum, which is a backend-only concept, but the underlying functions actually want to return uint32 and uint64, and only return Datum because it's convenient for callers who are using them to implement a hash function for some SQL datatype. However, changing these functions to return uint32 and uint64 seems like it might lead to programming errors or back-patching difficulties, both because they are widely used and because failure to use UInt{32,64}GetDatum() might not provoke a compilation error. Instead, rename the existing functions as well as changing the return type, and add static inline wrappers for those callers that need the previous behavior. Although this commit adapts hashutils.h and hashfn.c so that they can be compiled as frontend code, it does not actually do anything that would cause them to be so compiled. That is left for another commit. Patch by me, reviewed by Suraj Kharage and Mark Dilger. Discussion: http://postgr.es/m/CA+TgmoaRiG4TXND8QuM6JXFRkM_1wL2ZNhzaUKsuec9-4yrkgw@mail.gmail.com
1 parent 9341c78 commit a91e2fa

File tree

2 files changed

+55
-33
lines changed

2 files changed

+55
-33
lines changed

src/backend/utils/hash/hashfn.c

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@
1616
* It is expected that every bit of a hash function's 32-bit result is
1717
* as random as every other; failure to ensure this is likely to lead
1818
* to poor performance of hash tables. In most cases a hash
19-
* function should use hash_any() or its variant hash_uint32().
19+
* function should use hash_bytes() or its variant hash_bytes_uint32(),
20+
* or the wrappers hash_any() and hash_uint32 defined in hashfn.h.
2021
*
2122
*-------------------------------------------------------------------------
2223
*/
2324
#include "postgres.h"
2425

25-
#include "fmgr.h"
2626
#include "utils/hashutils.h"
27-
#include "utils/hsearch.h"
2827

2928

3029
/*
@@ -126,7 +125,7 @@
126125
}
127126

128127
/*
129-
* hash_any() -- hash a variable-length key into a 32-bit value
128+
* hash_bytes() -- hash a variable-length key into a 32-bit value
130129
* k : the key (the unaligned variable-length array of bytes)
131130
* len : the length of the key, counting by bytes
132131
*
@@ -143,8 +142,8 @@
143142
* by using the final values of both b and c. b is perhaps a little less
144143
* well mixed than c, however.
145144
*/
146-
Datum
147-
hash_any(const unsigned char *k, int keylen)
145+
uint32
146+
hash_bytes(const unsigned char *k, int keylen)
148147
{
149148
uint32 a,
150149
b,
@@ -358,20 +357,19 @@ hash_any(const unsigned char *k, int keylen)
358357
final(a, b, c);
359358

360359
/* report the result */
361-
return UInt32GetDatum(c);
360+
return c;
362361
}
363362

364363
/*
365-
* hash_any_extended() -- hash into a 64-bit value, using an optional seed
364+
* hash_bytes_extended() -- hash into a 64-bit value, using an optional seed
366365
* k : the key (the unaligned variable-length array of bytes)
367366
* len : the length of the key, counting by bytes
368367
* seed : a 64-bit seed (0 means no seed)
369368
*
370-
* Returns a uint64 value. Otherwise similar to hash_any.
369+
* Returns a uint64 value. Otherwise similar to hash_bytes.
371370
*/
372-
Datum
373-
hash_any_extended(const unsigned char *k, int keylen,
374-
uint64 seed)
371+
uint64
372+
hash_bytes_extended(const unsigned char *k, int keylen, uint64 seed)
375373
{
376374
uint32 a,
377375
b,
@@ -598,18 +596,18 @@ hash_any_extended(const unsigned char *k, int keylen,
598596
final(a, b, c);
599597

600598
/* report the result */
601-
PG_RETURN_UINT64(((uint64) b << 32) | c);
599+
return ((uint64) b << 32) | c;
602600
}
603601

604602
/*
605-
* hash_uint32() -- hash a 32-bit value to a 32-bit value
603+
* hash_bytes_uint32() -- hash a 32-bit value to a 32-bit value
606604
*
607605
* This has the same result as
608-
* hash_any(&k, sizeof(uint32))
606+
* hash_bytes(&k, sizeof(uint32))
609607
* but is faster and doesn't force the caller to store k into memory.
610608
*/
611-
Datum
612-
hash_uint32(uint32 k)
609+
uint32
610+
hash_bytes_uint32(uint32 k)
613611
{
614612
uint32 a,
615613
b,
@@ -621,16 +619,16 @@ hash_uint32(uint32 k)
621619
final(a, b, c);
622620

623621
/* report the result */
624-
return UInt32GetDatum(c);
622+
return c;
625623
}
626624

627625
/*
628-
* hash_uint32_extended() -- hash a 32-bit value to a 64-bit value, with a seed
626+
* hash_bytes_uint32_extended() -- hash 32-bit value to 64-bit value, with seed
629627
*
630-
* Like hash_uint32, this is a convenience function.
628+
* Like hash_bytes_uint32, this is a convenience function.
631629
*/
632-
Datum
633-
hash_uint32_extended(uint32 k, uint64 seed)
630+
uint64
631+
hash_bytes_uint32_extended(uint32 k, uint64 seed)
634632
{
635633
uint32 a,
636634
b,
@@ -650,7 +648,7 @@ hash_uint32_extended(uint32 k, uint64 seed)
650648
final(a, b, c);
651649

652650
/* report the result */
653-
PG_RETURN_UINT64(((uint64) b << 32) | c);
651+
return ((uint64) b << 32) | c;
654652
}
655653

656654
/*
@@ -669,8 +667,7 @@ string_hash(const void *key, Size keysize)
669667
Size s_len = strlen((const char *) key);
670668

671669
s_len = Min(s_len, keysize - 1);
672-
return DatumGetUInt32(hash_any((const unsigned char *) key,
673-
(int) s_len));
670+
return hash_bytes((const unsigned char *) key, (int) s_len);
674671
}
675672

676673
/*
@@ -679,8 +676,7 @@ string_hash(const void *key, Size keysize)
679676
uint32
680677
tag_hash(const void *key, Size keysize)
681678
{
682-
return DatumGetUInt32(hash_any((const unsigned char *) key,
683-
(int) keysize));
679+
return hash_bytes((const unsigned char *) key, (int) keysize);
684680
}
685681

686682
/*
@@ -692,5 +688,5 @@ uint32
692688
uint32_hash(const void *key, Size keysize)
693689
{
694690
Assert(keysize == sizeof(uint32));
695-
return DatumGetUInt32(hash_uint32(*((const uint32 *) key)));
691+
return hash_bytes_uint32(*((const uint32 *) key));
696692
}

src/include/utils/hashutils.h

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,37 @@
2020
(((v) >> 31) & UINT64CONST(0x100000001)))
2121

2222

23-
extern Datum hash_any(const unsigned char *k, int keylen);
24-
extern Datum hash_any_extended(const unsigned char *k,
25-
int keylen, uint64 seed);
26-
extern Datum hash_uint32(uint32 k);
27-
extern Datum hash_uint32_extended(uint32 k, uint64 seed);
23+
extern uint32 hash_bytes(const unsigned char *k, int keylen);
24+
extern uint64 hash_bytes_extended(const unsigned char *k,
25+
int keylen, uint64 seed);
26+
extern uint32 hash_bytes_uint32(uint32 k);
27+
extern uint64 hash_bytes_uint32_extended(uint32 k, uint64 seed);
28+
29+
#ifndef FRONTEND
30+
static inline Datum
31+
hash_any(const unsigned char *k, int keylen)
32+
{
33+
return UInt32GetDatum(hash_bytes(k, keylen));
34+
}
35+
36+
static inline Datum
37+
hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
38+
{
39+
return UInt64GetDatum(hash_bytes_extended(k, keylen, seed));
40+
}
41+
42+
static inline Datum
43+
hash_uint32(uint32 k)
44+
{
45+
return UInt32GetDatum(hash_bytes_uint32(k));
46+
}
47+
48+
static inline Datum
49+
hash_uint32_extended(uint32 k, uint64 seed)
50+
{
51+
return UInt64GetDatum(hash_bytes_uint32_extended(k, seed));
52+
}
53+
#endif
2854

2955
extern uint32 string_hash(const void *key, Size keysize);
3056
extern uint32 tag_hash(const void *key, Size keysize);

0 commit comments

Comments
 (0)