/* Web Polygraph http://www.web-polygraph.org/ * (C) 2003-2006 The Measurement Factory * Licensed under the Apache License, Version 2.0 */ #ifndef POLYGRAPH__BASE_RNDPERMUT_H #define POLYGRAPH__BASE_RNDPERMUT_H #include #include "xstd/LibInit.h" // We often need to convert a number to some uncorrellated uniformly // distributed random number. Using seed-and-trial approach with a r.n.g. // does not work well if input stream of numbers is sequential and long. // The permutator is also useful for seeding a r.n.g. // Current permutation allows for a given [small] number of high quality // random values. The size of the output set is a parameter. class RndPermutator { public: RndPermutator(int setSize = 0); ~RndPermutator(); // changes the permutation set; expensive; // can be called multiple times, any time // using prime numbers for set size is recommended void configure(int setSize, int seed = 1); // set size remains unchanged, but contents changes void reseed(int seed); // use 2nd param if you need to map two numbers into one uniform var int permut(int n, int m = 0) const; protected: inline void swap(int x, int y); inline int item(int idx) const; protected: int *theTable; // good random numbers int theTableCap; }; // constant "offsets" to use as a second parameter to RndPermut // when the first parameter is the same for a set of calls enum { rndNone = 0, rndContentSel, rndUnused1, rndContentPfx, rndContentExt, rndBodyIter, rndInjTbdPos, rndInjOff, rndInjProb, rndHotSetPos, rndRepOlc, rndRepSize, rndRepCach, rndRepCheckNeed, rndCdbStart, rndSharedContent, rndUniqueContent, rndEmbedContType, rndTwoWayPermutator, rndMembershipRangeBeg, rndArraySymSelector, rndPglSemxAssignment, rndPglSemxSelectItems, rndPglSemxIsDistr, rndRobotSymReqInterArrival, rndSslSeed, rndSslSessionCache, rndCookieSend, rndCookieCount, rndCookieSize, rndReqBody }; // generate one seeded r.n.g. per group class RndGen; class String; extern RndGen *GlbRndGen(const String &group); extern RndGen *LclRndGen(const String &group); extern RndPermutator &LclPermut(); // each process gets its own rnd numbers extern RndPermutator &GlbPermut(); // all processes share this set of numbers inline int LclPermut(int n, int m = 0) { return LclPermut().permut(n, m); } inline int GlbPermut(int n, int m = 0) { return GlbPermut().permut(n, m); } /* inlined methods */ inline void RndPermutator::swap(int x, int y) { const int h = theTable[x]; theTable[x] = theTable[y]; theTable[y] = h; } inline int RndPermutator::item(int idx) const { return idx >= 0 ? theTable[idx % theTableCap] : theTable[(idx + INT_MAX) % theTableCap]; } LIB_INITIALIZER(RndPermutfInit) #endif