Commit a91e2fa9 authored by Robert Haas's avatar Robert Haas

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
parent 9341c783
...@@ -16,15 +16,14 @@ ...@@ -16,15 +16,14 @@
* It is expected that every bit of a hash function's 32-bit result is * It is expected that every bit of a hash function's 32-bit result is
* as random as every other; failure to ensure this is likely to lead * as random as every other; failure to ensure this is likely to lead
* to poor performance of hash tables. In most cases a hash * to poor performance of hash tables. In most cases a hash
* function should use hash_any() or its variant hash_uint32(). * function should use hash_bytes() or its variant hash_bytes_uint32(),
* or the wrappers hash_any() and hash_uint32 defined in hashfn.h.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "fmgr.h"
#include "utils/hashutils.h" #include "utils/hashutils.h"
#include "utils/hsearch.h"
/* /*
...@@ -126,7 +125,7 @@ ...@@ -126,7 +125,7 @@
} }
/* /*
* hash_any() -- hash a variable-length key into a 32-bit value * hash_bytes() -- hash a variable-length key into a 32-bit value
* k : the key (the unaligned variable-length array of bytes) * k : the key (the unaligned variable-length array of bytes)
* len : the length of the key, counting by bytes * len : the length of the key, counting by bytes
* *
...@@ -143,8 +142,8 @@ ...@@ -143,8 +142,8 @@
* by using the final values of both b and c. b is perhaps a little less * by using the final values of both b and c. b is perhaps a little less
* well mixed than c, however. * well mixed than c, however.
*/ */
Datum uint32
hash_any(const unsigned char *k, int keylen) hash_bytes(const unsigned char *k, int keylen)
{ {
uint32 a, uint32 a,
b, b,
...@@ -358,20 +357,19 @@ hash_any(const unsigned char *k, int keylen) ...@@ -358,20 +357,19 @@ hash_any(const unsigned char *k, int keylen)
final(a, b, c); final(a, b, c);
/* report the result */ /* report the result */
return UInt32GetDatum(c); return c;
} }
/* /*
* hash_any_extended() -- hash into a 64-bit value, using an optional seed * hash_bytes_extended() -- hash into a 64-bit value, using an optional seed
* k : the key (the unaligned variable-length array of bytes) * k : the key (the unaligned variable-length array of bytes)
* len : the length of the key, counting by bytes * len : the length of the key, counting by bytes
* seed : a 64-bit seed (0 means no seed) * seed : a 64-bit seed (0 means no seed)
* *
* Returns a uint64 value. Otherwise similar to hash_any. * Returns a uint64 value. Otherwise similar to hash_bytes.
*/ */
Datum uint64
hash_any_extended(const unsigned char *k, int keylen, hash_bytes_extended(const unsigned char *k, int keylen, uint64 seed)
uint64 seed)
{ {
uint32 a, uint32 a,
b, b,
...@@ -598,18 +596,18 @@ hash_any_extended(const unsigned char *k, int keylen, ...@@ -598,18 +596,18 @@ hash_any_extended(const unsigned char *k, int keylen,
final(a, b, c); final(a, b, c);
/* report the result */ /* report the result */
PG_RETURN_UINT64(((uint64) b << 32) | c); return ((uint64) b << 32) | c;
} }
/* /*
* hash_uint32() -- hash a 32-bit value to a 32-bit value * hash_bytes_uint32() -- hash a 32-bit value to a 32-bit value
* *
* This has the same result as * This has the same result as
* hash_any(&k, sizeof(uint32)) * hash_bytes(&k, sizeof(uint32))
* but is faster and doesn't force the caller to store k into memory. * but is faster and doesn't force the caller to store k into memory.
*/ */
Datum uint32
hash_uint32(uint32 k) hash_bytes_uint32(uint32 k)
{ {
uint32 a, uint32 a,
b, b,
...@@ -621,16 +619,16 @@ hash_uint32(uint32 k) ...@@ -621,16 +619,16 @@ hash_uint32(uint32 k)
final(a, b, c); final(a, b, c);
/* report the result */ /* report the result */
return UInt32GetDatum(c); return c;
} }
/* /*
* hash_uint32_extended() -- hash a 32-bit value to a 64-bit value, with a seed * hash_bytes_uint32_extended() -- hash 32-bit value to 64-bit value, with seed
* *
* Like hash_uint32, this is a convenience function. * Like hash_bytes_uint32, this is a convenience function.
*/ */
Datum uint64
hash_uint32_extended(uint32 k, uint64 seed) hash_bytes_uint32_extended(uint32 k, uint64 seed)
{ {
uint32 a, uint32 a,
b, b,
...@@ -650,7 +648,7 @@ hash_uint32_extended(uint32 k, uint64 seed) ...@@ -650,7 +648,7 @@ hash_uint32_extended(uint32 k, uint64 seed)
final(a, b, c); final(a, b, c);
/* report the result */ /* report the result */
PG_RETURN_UINT64(((uint64) b << 32) | c); return ((uint64) b << 32) | c;
} }
/* /*
...@@ -669,8 +667,7 @@ string_hash(const void *key, Size keysize) ...@@ -669,8 +667,7 @@ string_hash(const void *key, Size keysize)
Size s_len = strlen((const char *) key); Size s_len = strlen((const char *) key);
s_len = Min(s_len, keysize - 1); s_len = Min(s_len, keysize - 1);
return DatumGetUInt32(hash_any((const unsigned char *) key, return hash_bytes((const unsigned char *) key, (int) s_len);
(int) s_len));
} }
/* /*
...@@ -679,8 +676,7 @@ string_hash(const void *key, Size keysize) ...@@ -679,8 +676,7 @@ string_hash(const void *key, Size keysize)
uint32 uint32
tag_hash(const void *key, Size keysize) tag_hash(const void *key, Size keysize)
{ {
return DatumGetUInt32(hash_any((const unsigned char *) key, return hash_bytes((const unsigned char *) key, (int) keysize);
(int) keysize));
} }
/* /*
...@@ -692,5 +688,5 @@ uint32 ...@@ -692,5 +688,5 @@ uint32
uint32_hash(const void *key, Size keysize) uint32_hash(const void *key, Size keysize)
{ {
Assert(keysize == sizeof(uint32)); Assert(keysize == sizeof(uint32));
return DatumGetUInt32(hash_uint32(*((const uint32 *) key))); return hash_bytes_uint32(*((const uint32 *) key));
} }
...@@ -20,11 +20,37 @@ ...@@ -20,11 +20,37 @@
(((v) >> 31) & UINT64CONST(0x100000001))) (((v) >> 31) & UINT64CONST(0x100000001)))
extern Datum hash_any(const unsigned char *k, int keylen); extern uint32 hash_bytes(const unsigned char *k, int keylen);
extern Datum hash_any_extended(const unsigned char *k, extern uint64 hash_bytes_extended(const unsigned char *k,
int keylen, uint64 seed); int keylen, uint64 seed);
extern Datum hash_uint32(uint32 k); extern uint32 hash_bytes_uint32(uint32 k);
extern Datum hash_uint32_extended(uint32 k, uint64 seed); extern uint64 hash_bytes_uint32_extended(uint32 k, uint64 seed);
#ifndef FRONTEND
static inline Datum
hash_any(const unsigned char *k, int keylen)
{
return UInt32GetDatum(hash_bytes(k, keylen));
}
static inline Datum
hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
{
return UInt64GetDatum(hash_bytes_extended(k, keylen, seed));
}
static inline Datum
hash_uint32(uint32 k)
{
return UInt32GetDatum(hash_bytes_uint32(k));
}
static inline Datum
hash_uint32_extended(uint32 k, uint64 seed)
{
return UInt64GetDatum(hash_bytes_uint32_extended(k, seed));
}
#endif
extern uint32 string_hash(const void *key, Size keysize); extern uint32 string_hash(const void *key, Size keysize);
extern uint32 tag_hash(const void *key, Size keysize); extern uint32 tag_hash(const void *key, Size keysize);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment