summaryrefslogtreecommitdiff
path: root/src/include/common/pg_prng.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/common/pg_prng.h')
-rw-r--r--src/include/common/pg_prng.h60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/include/common/pg_prng.h b/src/include/common/pg_prng.h
new file mode 100644
index 0000000000..623c65ae73
--- /dev/null
+++ b/src/include/common/pg_prng.h
@@ -0,0 +1,60 @@
+/*-------------------------------------------------------------------------
+ *
+ * Pseudo-Random Number Generator
+ *
+ * Copyright (c) 2021, PostgreSQL Global Development Group
+ *
+ * src/include/common/pg_prng.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_PRNG_H
+#define PG_PRNG_H
+
+/*
+ * State vector for PRNG generation. Callers should treat this as an
+ * opaque typedef, but we expose its definition to allow it to be
+ * embedded in other structs.
+ */
+typedef struct pg_prng_state
+{
+ uint64 s0,
+ s1;
+} pg_prng_state;
+
+/*
+ * Callers not needing local PRNG series may use this global state vector,
+ * after initializing it with one of the pg_prng_...seed functions.
+ */
+extern PGDLLIMPORT pg_prng_state pg_global_prng_state;
+
+extern void pg_prng_seed(pg_prng_state *state, uint64 seed);
+extern void pg_prng_fseed(pg_prng_state *state, double fseed);
+extern bool pg_prng_seed_check(pg_prng_state *state);
+
+/*
+ * Initialize the PRNG state from the pg_strong_random source,
+ * taking care that we don't produce all-zeroes. If this returns false,
+ * caller should initialize the PRNG state from some other random seed,
+ * using pg_prng_[f]seed.
+ *
+ * We implement this as a macro, so that the pg_strong_random() call is
+ * in the caller. If it were in pg_prng.c, programs using pg_prng.c
+ * but not needing strong seeding would nonetheless be forced to pull in
+ * pg_strong_random.c and thence OpenSSL.
+ */
+#define pg_prng_strong_seed(state) \
+ (pg_strong_random((void *) (state), sizeof(pg_prng_state)) ? \
+ pg_prng_seed_check(state) : false)
+
+extern uint64 pg_prng_uint64(pg_prng_state *state);
+extern uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax);
+extern int64 pg_prng_int64(pg_prng_state *state);
+extern int64 pg_prng_int64p(pg_prng_state *state);
+extern uint32 pg_prng_uint32(pg_prng_state *state);
+extern int32 pg_prng_int32(pg_prng_state *state);
+extern int32 pg_prng_int32p(pg_prng_state *state);
+extern double pg_prng_double(pg_prng_state *state);
+extern bool pg_prng_bool(pg_prng_state *state);
+
+#endif /* PG_PRNG_H */