Use a faster hash function in resource owners.

This buys back some of the performance loss that we otherwise saw from the
previous commit.

Reviewed-by: Aleksander Alekseev, Michael Paquier, Julien Rouhaud
Reviewed-by: Kyotaro Horiguchi, Hayato Kuroda, Álvaro Herrera, Zhihong Yu
Reviewed-by: Peter Eisentraut, Andres Freund
Discussion: https://www.postgresql.org/message-id/d746cead-a1ef-7efe-fb47-933311e876a3%40iki.fi
pull/146/head
Heikki Linnakangas 2 years ago
parent b8bff07daa
commit 954e43564d
  1. 24
      src/backend/utils/resowner/resowner.c
  2. 15
      src/include/common/hashfn.h

@ -206,15 +206,27 @@ static void ReleaseAuxProcessResourcesCallback(int code, Datum arg);
* INTERNAL ROUTINES * * INTERNAL ROUTINES *
*****************************************************************************/ *****************************************************************************/
/*
* Hash function for value+kind combination.
*/
static inline uint32 static inline uint32
hash_resource_elem(Datum value, const ResourceOwnerDesc *kind) hash_resource_elem(Datum value, const ResourceOwnerDesc *kind)
{ {
Datum data[2]; /*
* Most resource kinds store a pointer in 'value', and pointers are unique
data[0] = value; * all on their own. But some resources store plain integers (Files and
data[1] = PointerGetDatum(kind); * Buffers as of this writing), so we want to incorporate the 'kind' in
* the hash too, otherwise those resources will collide a lot. But
return hash_bytes((unsigned char *) &data, 2 * SIZEOF_DATUM); * because there are only a few resource kinds like that - and only a few
* resource kinds to begin with - we don't need to work too hard to mix
* 'kind' into the hash. Just add it with hash_combine(), it perturbs the
* result enough for our purposes.
*/
#if SIZEOF_DATUM == 8
return hash_combine64(murmurhash64((uint64) value), (uint64) kind);
#else
return hash_combine(murmurhash32((uint32) value), (uint32) kind);
#endif
} }
/* /*

@ -101,4 +101,19 @@ murmurhash32(uint32 data)
return h; return h;
} }
/* 64-bit variant */
static inline uint64
murmurhash64(uint64 data)
{
uint64 h = data;
h ^= h >> 33;
h *= 0xff51afd7ed558ccd;
h ^= h >> 33;
h *= 0xc4ceb9fe1a85ec53;
h ^= h >> 33;
return h;
}
#endif /* HASHFN_H */ #endif /* HASHFN_H */

Loading…
Cancel
Save