diff --git a/src/util/u_printf.c b/src/util/u_printf.c index b432e8925e6..a9c3903e967 100644 --- a/src/util/u_printf.c +++ b/src/util/u_printf.c @@ -35,6 +35,9 @@ #include "u_math.h" #include "u_printf.h" +#define XXH_INLINE_ALL +#include "util/xxhash.h" + /* Some versions of MinGW are missing _vscprintf's declaration, although they * still provide the symbol in the import library. */ #ifdef __MINGW32__ @@ -332,3 +335,28 @@ u_printf_deserialize_info(void *mem_ctx, return printf_info; } + +/* + * Hash the format string, allowing the driver to pool format strings. + * + * Post-condition: hash is nonzero. This is convenient. + */ +uint32_t +u_printf_hash(const u_printf_info *info) +{ + struct blob blob; + blob_init(&blob); + u_printf_serialize_info(&blob, info, 1); + uint32_t hash = XXH32(blob.data, blob.size, 0); + blob_finish(&blob); + + /* Force things away from zero. This weakens the hash only slightly, as + * there's only a 2^-31 probability of hashing to either hash=0 or hash=1. + */ + if (hash == 0) { + hash = 1; + } + + assert(hash != 0); + return hash; +} diff --git a/src/util/u_printf.h b/src/util/u_printf.h index a89a5041105..427301ed7ba 100644 --- a/src/util/u_printf.h +++ b/src/util/u_printf.h @@ -49,6 +49,8 @@ u_printf_info *u_printf_deserialize_info(void *mem_ctx, struct blob_reader *blob, unsigned *printf_info_count); +uint32_t u_printf_hash(const u_printf_info *info); + struct u_printf_ctx { simple_mtx_t lock; void *bo;