diff --git a/src/bin/pgbench/exprparse.y b/src/bin/pgbench/exprparse.y index 25d5ad4..edd74ee 100644 --- a/src/bin/pgbench/exprparse.y +++ b/src/bin/pgbench/exprparse.y @@ -194,6 +194,9 @@ static const struct { "random_zipfian", 3, PGBENCH_RANDOM_ZIPFIAN }, + { + "hash", 1, PGBENCH_HASH + }, /* keep as last array element */ { NULL, 0, 0 diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 7ce6f60..75897cc 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -61,6 +61,12 @@ #define ERRCODE_UNDEFINED_TABLE "42P01" /* + * FNV hashing constants + */ +#define FNV_PRIME 1099511628211 +#define FNV_OFFSET_BASIS 0xcbf29ce484222325 + +/* * Multi-platform pthread implementations */ @@ -1850,6 +1856,33 @@ evalFunc(TState *thread, CState *st, return true; } + /* hashing */ + case PGBENCH_HASH: + { + int i; + int64 val; + int64 result; + + if (!coerceToInt(&vargs[0], &val)) + return false; + + /* + * Fowler–Noll–Vo hash + */ + result = FNV_OFFSET_BASIS; + for (i = 0; i < 8; ++i) + { + int32 octet = val & 0xff; + + val = val >> 8; + result = result ^ octet; + result = result * FNV_PRIME; + } + + setIntValue(retval, result); + return true; + } + default: /* cannot get here */ Assert(0); diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h index 83fee1a..a91e4e2 100644 --- a/src/bin/pgbench/pgbench.h +++ b/src/bin/pgbench/pgbench.h @@ -76,7 +76,8 @@ typedef enum PgBenchFunction PGBENCH_RANDOM, PGBENCH_RANDOM_GAUSSIAN, PGBENCH_RANDOM_EXPONENTIAL, - PGBENCH_RANDOM_ZIPFIAN + PGBENCH_RANDOM_ZIPFIAN, + PGBENCH_HASH } PgBenchFunction; typedef struct PgBenchExpr PgBenchExpr;