Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3804539

Browse files
committed
Replace random(), pg_erand48(), etc with a better PRNG API and algorithm.
Standardize on xoroshiro128** as our basic PRNG algorithm, eliminatinga bunch of platform dependencies as well as fundamentally-obsolete PRNGcode. In addition, this API replacement will ease replacing thealgorithm again in future, should that become necessary.xoroshiro128** is a few percent slower than the drand48 family,but it can produce full-width 64-bit random values not only 48-bit,and it should be much more trustworthy. It's likely to be noticeablyfaster than the platform's random(), depending on which platform youare thinking about; and we can have non-global state vectors easily,unlike with random(). It is not cryptographically strong, but neitherare the functions it replaces.Fabien Coelho, reviewed by Dean Rasheed, Aleksander Alekseev, and myselfDiscussion:https://postgr.es/m/alpine.DEB.2.22.394.2105241211230.165418@pseudo
1 parentf44ceb4 commit3804539

File tree

50 files changed

+544
-481
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+544
-481
lines changed

‎configure

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16463,32 +16463,6 @@ esac
1646316463

1646416464
fi
1646516465

16466-
ac_fn_c_check_func "$LINENO" "random" "ac_cv_func_random"
16467-
if test "x$ac_cv_func_random" = xyes; then :
16468-
$as_echo "#define HAVE_RANDOM 1" >>confdefs.h
16469-
16470-
else
16471-
case " $LIBOBJS " in
16472-
*" random.$ac_objext "* ) ;;
16473-
*) LIBOBJS="$LIBOBJS random.$ac_objext"
16474-
;;
16475-
esac
16476-
16477-
fi
16478-
16479-
ac_fn_c_check_func "$LINENO" "srandom" "ac_cv_func_srandom"
16480-
if test "x$ac_cv_func_srandom" = xyes; then :
16481-
$as_echo "#define HAVE_SRANDOM 1" >>confdefs.h
16482-
16483-
else
16484-
case " $LIBOBJS " in
16485-
*" srandom.$ac_objext "* ) ;;
16486-
*) LIBOBJS="$LIBOBJS srandom.$ac_objext"
16487-
;;
16488-
esac
16489-
16490-
fi
16491-
1649216466
ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
1649316467
if test "x$ac_cv_func_strlcat" = xyes; then :
1649416468
$as_echo "#define HAVE_STRLCAT 1" >>confdefs.h

‎configure.ac

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,8 +1858,6 @@ AC_REPLACE_FUNCS(m4_normalize([
18581858
mkdtemp
18591859
pread
18601860
pwrite
1861-
random
1862-
srandom
18631861
strlcat
18641862
strlcpy
18651863
strnlen

‎contrib/amcheck/verify_nbtree.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include"catalog/index.h"
3333
#include"catalog/pg_am.h"
3434
#include"commands/tablecmds.h"
35+
#include"common/pg_prng.h"
3536
#include"lib/bloomfilter.h"
3637
#include"miscadmin.h"
3738
#include"storage/lmgr.h"
@@ -466,8 +467,8 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace,
466467
total_pages=RelationGetNumberOfBlocks(rel);
467468
total_elems=Max(total_pages* (MaxTIDsPerBTreePage /3),
468469
(int64)state->rel->rd_rel->reltuples);
469-
/*Random seed relies on backend srandom() call to avoid repetition */
470-
seed=random();
470+
/*Generate a random seed to avoid repetition */
471+
seed=pg_prng_uint64(&pg_global_prng_state);
471472
/* Create Bloom filter to fingerprint index */
472473
state->filter=bloom_create(total_elems,maintenance_work_mem,seed);
473474
state->heaptuplespresent=0;

‎contrib/auto_explain/auto_explain.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include"access/parallel.h"
1818
#include"commands/explain.h"
19+
#include"common/pg_prng.h"
1920
#include"executor/instrument.h"
2021
#include"jit/jit.h"
2122
#include"utils/guc.h"
@@ -275,8 +276,7 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
275276
if (nesting_level==0)
276277
{
277278
if (auto_explain_log_min_duration >=0&& !IsParallelWorker())
278-
current_query_sampled= (random()<auto_explain_sample_rate*
279-
((double)MAX_RANDOM_VALUE+1));
279+
current_query_sampled= (pg_prng_double(&pg_global_prng_state)<auto_explain_sample_rate);
280280
else
281281
current_query_sampled= false;
282282
}

‎contrib/file_fdw/file_fdw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ file_acquire_sample_rows(Relation onerel, int elevel,
11881188
* Found a suitable tuple, so save it, replacing one old tuple
11891189
* at random
11901190
*/
1191-
intk= (int) (targrows*sampler_random_fract(rstate.randstate));
1191+
intk= (int) (targrows*sampler_random_fract(&rstate.randstate));
11921192

11931193
Assert(k >=0&&k<targrows);
11941194
heap_freetuple(rows[k]);

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5158,7 +5158,7 @@ analyze_row_processor(PGresult *res, int row, PgFdwAnalyzeState *astate)
51585158
if (astate->rowstoskip <=0)
51595159
{
51605160
/* Choose a random reservoir element to replace. */
5161-
pos= (int) (targrows*sampler_random_fract(astate->rstate.randstate));
5161+
pos= (int) (targrows*sampler_random_fract(&astate->rstate.randstate));
51625162
Assert(pos >=0&&pos<targrows);
51635163
heap_freetuple(astate->rows[pos]);
51645164
}

‎contrib/tablefunc/tablefunc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#include"access/htup_details.h"
3838
#include"catalog/pg_type.h"
39+
#include"common/pg_prng.h"
3940
#include"executor/spi.h"
4041
#include"funcapi.h"
4142
#include"lib/stringinfo.h"
@@ -290,8 +291,8 @@ get_normal_pair(float8 *x1, float8 *x2)
290291

291292
do
292293
{
293-
u1=(float8)random() / (float8)MAX_RANDOM_VALUE;
294-
u2=(float8)random() / (float8)MAX_RANDOM_VALUE;
294+
u1=pg_prng_double(&pg_global_prng_state);
295+
u2=pg_prng_double(&pg_global_prng_state);
295296

296297
v1= (2.0*u1)-1.0;
297298
v2= (2.0*u2)-1.0;

‎contrib/tsm_system_rows/tsm_system_rows.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static BlockNumber system_rows_nextsampleblock(SampleScanState *node, BlockNumbe
6969
staticOffsetNumbersystem_rows_nextsampletuple(SampleScanState*node,
7070
BlockNumberblockno,
7171
OffsetNumbermaxoffset);
72-
staticuint32random_relative_prime(uint32n,SamplerRandomStaterandstate);
72+
staticuint32random_relative_prime(uint32n,pg_prng_state*randstate);
7373

7474

7575
/*
@@ -213,25 +213,25 @@ system_rows_nextsampleblock(SampleScanState *node, BlockNumber nblocks)
213213
if (sampler->step==0)
214214
{
215215
/* Initialize now that we have scan descriptor */
216-
SamplerRandomStaterandstate;
216+
pg_prng_staterandstate;
217217

218218
/* If relation is empty, there's nothing to scan */
219219
if (nblocks==0)
220220
returnInvalidBlockNumber;
221221

222222
/* We only need an RNG during this setup step */
223-
sampler_random_init_state(sampler->seed,randstate);
223+
sampler_random_init_state(sampler->seed,&randstate);
224224

225225
/* Compute nblocks/firstblock/step only once per query */
226226
sampler->nblocks=nblocks;
227227

228228
/* Choose random starting block within the relation */
229229
/* (Actually this is the predecessor of the first block visited) */
230-
sampler->firstblock=sampler_random_fract(randstate)*
230+
sampler->firstblock=sampler_random_fract(&randstate)*
231231
sampler->nblocks;
232232

233233
/* Find relative prime as step size for linear probing */
234-
sampler->step=random_relative_prime(sampler->nblocks,randstate);
234+
sampler->step=random_relative_prime(sampler->nblocks,&randstate);
235235
}
236236

237237
/* Reinitialize lb */
@@ -317,7 +317,7 @@ gcd(uint32 a, uint32 b)
317317
* (else return 1).
318318
*/
319319
staticuint32
320-
random_relative_prime(uint32n,SamplerRandomStaterandstate)
320+
random_relative_prime(uint32n,pg_prng_state*randstate)
321321
{
322322
uint32r;
323323

‎contrib/tsm_system_time/tsm_system_time.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static BlockNumber system_time_nextsampleblock(SampleScanState *node, BlockNumbe
6969
staticOffsetNumbersystem_time_nextsampletuple(SampleScanState*node,
7070
BlockNumberblockno,
7171
OffsetNumbermaxoffset);
72-
staticuint32random_relative_prime(uint32n,SamplerRandomStaterandstate);
72+
staticuint32random_relative_prime(uint32n,pg_prng_state*randstate);
7373

7474

7575
/*
@@ -224,25 +224,25 @@ system_time_nextsampleblock(SampleScanState *node, BlockNumber nblocks)
224224
if (sampler->step==0)
225225
{
226226
/* Initialize now that we have scan descriptor */
227-
SamplerRandomStaterandstate;
227+
pg_prng_staterandstate;
228228

229229
/* If relation is empty, there's nothing to scan */
230230
if (nblocks==0)
231231
returnInvalidBlockNumber;
232232

233233
/* We only need an RNG during this setup step */
234-
sampler_random_init_state(sampler->seed,randstate);
234+
sampler_random_init_state(sampler->seed,&randstate);
235235

236236
/* Compute nblocks/firstblock/step only once per query */
237237
sampler->nblocks=nblocks;
238238

239239
/* Choose random starting block within the relation */
240240
/* (Actually this is the predecessor of the first block visited) */
241-
sampler->firstblock=sampler_random_fract(randstate)*
241+
sampler->firstblock=sampler_random_fract(&randstate)*
242242
sampler->nblocks;
243243

244244
/* Find relative prime as step size for linear probing */
245-
sampler->step=random_relative_prime(sampler->nblocks,randstate);
245+
sampler->step=random_relative_prime(sampler->nblocks,&randstate);
246246
}
247247

248248
/* Reinitialize lb and start_time */
@@ -330,7 +330,7 @@ gcd(uint32 a, uint32 b)
330330
* (else return 1).
331331
*/
332332
staticuint32
333-
random_relative_prime(uint32n,SamplerRandomStaterandstate)
333+
random_relative_prime(uint32n,pg_prng_state*randstate)
334334
{
335335
uint32r;
336336

‎src/backend/access/gin/ginget.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include"access/gin_private.h"
1818
#include"access/relscan.h"
19+
#include"common/pg_prng.h"
1920
#include"miscadmin.h"
2021
#include"storage/predicate.h"
2122
#include"utils/datum.h"
@@ -787,7 +788,7 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry,
787788
}
788789
}
789790

790-
#definegin_rand()(((double) random()) / ((double) MAX_RANDOM_VALUE))
791+
#definegin_rand()pg_prng_double(&pg_global_prng_state)
791792
#definedropItem(e) ( gin_rand() > ((double)GinFuzzySearchLimit)/((double)((e)->predictNumberResult)) )
792793

793794
/*

‎src/backend/access/gist/gistutil.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include"access/htup_details.h"
2020
#include"access/reloptions.h"
2121
#include"catalog/pg_opclass.h"
22+
#include"common/pg_prng.h"
2223
#include"storage/indexfsm.h"
2324
#include"storage/lmgr.h"
2425
#include"utils/float.h"
@@ -507,7 +508,7 @@ gistchoose(Relation r, Page p, IndexTuple it,/* it has compressed entry */
507508
if (keep_current_best==-1)
508509
{
509510
/* we didn't make the random choice yet for this old best */
510-
keep_current_best=(random() <= (MAX_RANDOM_VALUE /2)) ?1 :0;
511+
keep_current_best=pg_prng_bool(&pg_global_prng_state) ?1 :0;
511512
}
512513
if (keep_current_best==0)
513514
{
@@ -529,7 +530,7 @@ gistchoose(Relation r, Page p, IndexTuple it,/* it has compressed entry */
529530
if (keep_current_best==-1)
530531
{
531532
/* we didn't make the random choice yet for this old best */
532-
keep_current_best=(random() <= (MAX_RANDOM_VALUE /2)) ?1 :0;
533+
keep_current_best=pg_prng_bool(&pg_global_prng_state) ?1 :0;
533534
}
534535
if (keep_current_best==1)
535536
break;

‎src/backend/access/nbtree/nbtinsert.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include"access/nbtxlog.h"
2020
#include"access/transam.h"
2121
#include"access/xloginsert.h"
22+
#include"common/pg_prng.h"
2223
#include"lib/qunique.h"
2324
#include"miscadmin.h"
2425
#include"storage/lmgr.h"
@@ -965,7 +966,7 @@ _bt_findinsertloc(Relation rel,
965966

966967
if (P_RIGHTMOST(opaque)||
967968
_bt_compare(rel,itup_key,page,P_HIKEY)!=0||
968-
random() <= (MAX_RANDOM_VALUE /100))
969+
pg_prng_uint32(&pg_global_prng_state) <= (PG_UINT32_MAX /100))
969970
break;
970971

971972
_bt_stepright(rel,insertstate,stack);

‎src/backend/access/spgist/spgdoinsert.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include"access/spgist_private.h"
2020
#include"access/spgxlog.h"
2121
#include"access/xloginsert.h"
22+
#include"common/pg_prng.h"
2223
#include"miscadmin.h"
2324
#include"storage/bufmgr.h"
2425
#include"utils/rel.h"
@@ -2210,7 +2211,9 @@ spgdoinsert(Relation index, SpGistState *state,
22102211
if (out.resultType==spgAddNode)
22112212
elog(ERROR,"cannot add a node to an allTheSame inner tuple");
22122213
elseif (out.resultType==spgMatchNode)
2213-
out.result.matchNode.nodeN=random() %innerTuple->nNodes;
2214+
out.result.matchNode.nodeN=
2215+
pg_prng_uint64_range(&pg_global_prng_state,
2216+
0,innerTuple->nNodes-1);
22142217
}
22152218

22162219
switch (out.resultType)

‎src/backend/access/transam/xact.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include"commands/async.h"
3838
#include"commands/tablecmds.h"
3939
#include"commands/trigger.h"
40+
#include"common/pg_prng.h"
4041
#include"executor/spi.h"
4142
#include"libpq/be-fsstubs.h"
4243
#include"libpq/pqsignal.h"
@@ -1990,7 +1991,7 @@ StartTransaction(void)
19901991
/* Determine if statements are logged in this transaction */
19911992
xact_is_sampled=log_xact_sample_rate!=0&&
19921993
(log_xact_sample_rate==1||
1993-
random() <=log_xact_sample_rate*MAX_RANDOM_VALUE);
1994+
pg_prng_double(&pg_global_prng_state) <=log_xact_sample_rate);
19941995

19951996
/*
19961997
* initialize current transaction state fields

‎src/backend/commands/analyze.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include"commands/progress.h"
3939
#include"commands/tablecmds.h"
4040
#include"commands/vacuum.h"
41+
#include"common/pg_prng.h"
4142
#include"executor/executor.h"
4243
#include"foreign/fdwapi.h"
4344
#include"miscadmin.h"
@@ -1140,7 +1141,7 @@ acquire_sample_rows(Relation onerel, int elevel,
11401141
doubleliverows=0;/* # live rows seen */
11411142
doubledeadrows=0;/* # dead rows seen */
11421143
doublerowstoskip=-1;/* -1 means not set yet */
1143-
longrandseed;/* Seed for block sampler(s) */
1144+
uint32randseed;/* Seed for block sampler(s) */
11441145
BlockNumbertotalblocks;
11451146
TransactionIdOldestXmin;
11461147
BlockSamplerDatabs;
@@ -1162,7 +1163,7 @@ acquire_sample_rows(Relation onerel, int elevel,
11621163
OldestXmin=GetOldestNonRemovableTransactionId(onerel);
11631164

11641165
/* Prepare for sampling block numbers */
1165-
randseed=random();
1166+
randseed=pg_prng_uint32(&pg_global_prng_state);
11661167
nblocks=BlockSampler_Init(&bs,totalblocks,targrows,randseed);
11671168

11681169
#ifdefUSE_PREFETCH
@@ -1279,7 +1280,7 @@ acquire_sample_rows(Relation onerel, int elevel,
12791280
* Found a suitable tuple, so save it, replacing one old
12801281
* tuple at random
12811282
*/
1282-
intk= (int) (targrows*sampler_random_fract(rstate.randstate));
1283+
intk= (int) (targrows*sampler_random_fract(&rstate.randstate));
12831284

12841285
Assert(k >=0&&k<targrows);
12851286
heap_freetuple(rows[k]);

‎src/backend/executor/nodeSamplescan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include"access/relscan.h"
1818
#include"access/tableam.h"
1919
#include"access/tsmapi.h"
20+
#include"common/pg_prng.h"
2021
#include"executor/executor.h"
2122
#include"executor/nodeSamplescan.h"
2223
#include"miscadmin.h"
@@ -154,7 +155,7 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
154155
* do this just once, since the seed shouldn't change over rescans.
155156
*/
156157
if (tsc->repeatable==NULL)
157-
scanstate->seed=random();
158+
scanstate->seed=pg_prng_uint32(&pg_global_prng_state);
158159

159160
/*
160161
* Finally, initialize the TABLESAMPLE method handler.

‎src/backend/lib/bloomfilter.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ static inline uint32 mod_m(uint32 a, uint64 m);
8181
* distinct seed value on every call makes it unlikely that the same false
8282
* positives will reoccur when the same set is fingerprinted a second time.
8383
* Callers that don't care about this pass a constant as their seed, typically
84-
* 0. Callers can use a pseudo-random seed in the range of 0 - INT_MAX by
85-
* calling random().
84+
* 0. Callers can also use a pseudo-random seed, eg from pg_prng_uint64().
8685
*/
8786
bloom_filter*
8887
bloom_create(int64total_elems,intbloom_work_mem,uint64seed)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp