aboutsummaryrefslogtreecommitdiffstats
path: root/util/random
diff options
context:
space:
mode:
authorAnton Samokhvalov <pg83@yandex.ru>2022-02-10 16:45:17 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:17 +0300
commitd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch)
treedd4bd3ca0f36b817e96812825ffaf10d645803f2 /util/random
parent72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff)
downloadydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'util/random')
-rw-r--r--util/random/benchmark/prng/main.cpp204
-rw-r--r--util/random/common_ops.cpp2
-rw-r--r--util/random/common_ops.h198
-rw-r--r--util/random/common_ops_ut.cpp124
-rw-r--r--util/random/easy.cpp2
-rw-r--r--util/random/easy.h92
-rw-r--r--util/random/easy_ut.cpp64
-rw-r--r--util/random/entropy.cpp382
-rw-r--r--util/random/entropy.h30
-rw-r--r--util/random/entropy_ut.cpp20
-rw-r--r--util/random/fast.cpp90
-rw-r--r--util/random/fast.h168
-rw-r--r--util/random/fast_ut.cpp168
-rw-r--r--util/random/init_atfork.cpp54
-rw-r--r--util/random/init_atfork.h6
-rw-r--r--util/random/lcg_engine.cpp4
-rw-r--r--util/random/lcg_engine.h82
-rw-r--r--util/random/mersenne.h72
-rw-r--r--util/random/mersenne32.cpp186
-rw-r--r--util/random/mersenne32.h78
-rw-r--r--util/random/mersenne64.cpp190
-rw-r--r--util/random/mersenne64.h82
-rw-r--r--util/random/mersenne_ut.cpp144
-rw-r--r--util/random/normal.cpp54
-rw-r--r--util/random/normal.h76
-rw-r--r--util/random/normal_ut.cpp144
-rw-r--r--util/random/random.cpp194
-rw-r--r--util/random/random.h26
-rw-r--r--util/random/random_ut.cpp176
-rw-r--r--util/random/shuffle.cpp2
-rw-r--r--util/random/shuffle.h44
-rw-r--r--util/random/shuffle_ut.cpp98
-rw-r--r--util/random/ut/ya.make18
33 files changed, 1637 insertions, 1637 deletions
diff --git a/util/random/benchmark/prng/main.cpp b/util/random/benchmark/prng/main.cpp
index cc2b80d8a6..2c6279ff71 100644
--- a/util/random/benchmark/prng/main.cpp
+++ b/util/random/benchmark/prng/main.cpp
@@ -2,122 +2,122 @@
#include <util/random/entropy.h>
#include <util/random/fast.h>
-#include <util/random/normal.h>
+#include <util/random/normal.h>
#include <util/random/mersenne.h>
#include <util/system/compiler.h>
-#include <util/generic/xrange.h>
-
-#include <random>
-
-// double part
-Y_CPU_BENCHMARK(Mersenne32_Double, p) {
- TMersenne<ui32> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
+#include <util/generic/xrange.h>
+
+#include <random>
+
+// double part
+Y_CPU_BENCHMARK(Mersenne32_Double, p) {
+ TMersenne<ui32> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRandReal1());
}
}
-Y_CPU_BENCHMARK(Mersenne64_Double, p) {
- TMersenne<ui64> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
+Y_CPU_BENCHMARK(Mersenne64_Double, p) {
+ TMersenne<ui64> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRandReal1());
}
}
-Y_CPU_BENCHMARK(Fast32_Double, p) {
- TFastRng<ui32> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
+Y_CPU_BENCHMARK(Fast32_Double, p) {
+ TFastRng<ui32> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRandReal1());
}
}
-Y_CPU_BENCHMARK(Fast64_Double, p) {
- TFastRng<ui64> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
+Y_CPU_BENCHMARK(Fast64_Double, p) {
+ TFastRng<ui64> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRandReal1());
}
}
-
-// integer part
-Y_CPU_BENCHMARK(mt19937_32, p) {
- std::mt19937 mt;
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
-
- Y_DO_NOT_OPTIMIZE_AWAY(mt());
- }
-}
-
-Y_CPU_BENCHMARK(mt19937_64, p) {
- std::mt19937_64 mt;
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
-
- Y_DO_NOT_OPTIMIZE_AWAY(mt());
- }
-}
-
-Y_CPU_BENCHMARK(Mersenne32_GenRand, p) {
- TMersenne<ui32> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
- Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRand());
- }
-}
-
-Y_CPU_BENCHMARK(Mersenne64_GenRand, p) {
- TMersenne<ui64> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
- Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRand());
- }
-}
-
-Y_CPU_BENCHMARK(Fast32_GenRand, p) {
- TFastRng<ui32> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
- Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRand());
- }
-}
-
-Y_CPU_BENCHMARK(Fast64_GenRand, p) {
- TFastRng<ui64> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
- Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRand());
- }
-}
-
-Y_CPU_BENCHMARK(StlNormal, p) {
- TFastRng<ui64> rng(Seed());
- std::normal_distribution<double> d(1.0, 0.0);
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
- Y_DO_NOT_OPTIMIZE_AWAY(d(rng));
- }
-}
-
-Y_CPU_BENCHMARK(UtilNormal, p) {
- TFastRng<ui64> rng(Seed());
-
- for (auto i : xrange<size_t>(0, p.Iterations())) {
- (void)i;
- Y_DO_NOT_OPTIMIZE_AWAY(NormalDistribution<double>(rng, 1.0, 0.0));
- }
-}
+
+// integer part
+Y_CPU_BENCHMARK(mt19937_32, p) {
+ std::mt19937 mt;
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
+
+ Y_DO_NOT_OPTIMIZE_AWAY(mt());
+ }
+}
+
+Y_CPU_BENCHMARK(mt19937_64, p) {
+ std::mt19937_64 mt;
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
+
+ Y_DO_NOT_OPTIMIZE_AWAY(mt());
+ }
+}
+
+Y_CPU_BENCHMARK(Mersenne32_GenRand, p) {
+ TMersenne<ui32> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
+ Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRand());
+ }
+}
+
+Y_CPU_BENCHMARK(Mersenne64_GenRand, p) {
+ TMersenne<ui64> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
+ Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRand());
+ }
+}
+
+Y_CPU_BENCHMARK(Fast32_GenRand, p) {
+ TFastRng<ui32> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
+ Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRand());
+ }
+}
+
+Y_CPU_BENCHMARK(Fast64_GenRand, p) {
+ TFastRng<ui64> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
+ Y_DO_NOT_OPTIMIZE_AWAY(rng.GenRand());
+ }
+}
+
+Y_CPU_BENCHMARK(StlNormal, p) {
+ TFastRng<ui64> rng(Seed());
+ std::normal_distribution<double> d(1.0, 0.0);
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
+ Y_DO_NOT_OPTIMIZE_AWAY(d(rng));
+ }
+}
+
+Y_CPU_BENCHMARK(UtilNormal, p) {
+ TFastRng<ui64> rng(Seed());
+
+ for (auto i : xrange<size_t>(0, p.Iterations())) {
+ (void)i;
+ Y_DO_NOT_OPTIMIZE_AWAY(NormalDistribution<double>(rng, 1.0, 0.0));
+ }
+}
diff --git a/util/random/common_ops.cpp b/util/random/common_ops.cpp
index 2ec78cbc98..f856a76cbc 100644
--- a/util/random/common_ops.cpp
+++ b/util/random/common_ops.cpp
@@ -1 +1 @@
-#include "common_ops.h"
+#include "common_ops.h"
diff --git a/util/random/common_ops.h b/util/random/common_ops.h
index f9c50f12ac..602eede351 100644
--- a/util/random/common_ops.h
+++ b/util/random/common_ops.h
@@ -1,130 +1,130 @@
-#pragma once
-
-#include <util/system/defaults.h>
-#include <util/system/yassert.h>
-
-namespace NPrivate {
+#pragma once
+
+#include <util/system/defaults.h>
+#include <util/system/yassert.h>
+
+namespace NPrivate {
constexpr double ToRandReal1(const ui32 x) noexcept {
return x * (double)(1.0 / 4294967295.0);
- }
-
+ }
+
constexpr double ToRandReal2(const ui32 x) noexcept {
return x * (double)(1.0 / 4294967296.0);
- }
-
+ }
+
constexpr double ToRandReal3(const ui32 x) noexcept {
return ((double)x + 0.5) * (double)(1.0 / 4294967296.0);
- }
-
+ }
+
constexpr double ToRandReal1(const ui64 x) noexcept {
return (x >> 11) * (double)(1.0 / 9007199254740991.0);
- }
-
+ }
+
constexpr double ToRandReal2(const ui64 x) noexcept {
return (x >> 11) * (double)(1.0 / 9007199254740992.0);
- }
-
+ }
+
constexpr double ToRandReal3(const ui64 x) noexcept {
return ((x >> 12) + 0.5) * (double)(1.0 / 4503599627370496.0);
- }
-
+ }
+
constexpr double ToRandReal4(const ui64 x) noexcept {
return double(x * (double)(1.0 / 18446744073709551616.0L));
- }
-
- template <class T>
+ }
+
+ template <class T>
static inline ui64 ToRand64(T&& rng, ui32 x) noexcept {
- return ((ui64)x) | (((ui64)rng.GenRand()) << 32);
- }
-
- template <class T>
+ return ((ui64)x) | (((ui64)rng.GenRand()) << 32);
+ }
+
+ template <class T>
static constexpr ui64 ToRand64(T&&, ui64 x) noexcept {
- return x;
- }
-
- /*
- * return value in range [0, max) from any generator
- */
- template <class T, class TRandGen>
- static T GenUniform(T max, TRandGen&& gen) {
+ return x;
+ }
+
+ /*
+ * return value in range [0, max) from any generator
+ */
+ template <class T, class TRandGen>
+ static T GenUniform(T max, TRandGen&& gen) {
Y_VERIFY(max > 0, "Invalid random number range [0, 0)");
-
- const T randmax = gen.RandMax() - gen.RandMax() % max;
- T rand;
-
- while ((rand = gen.GenRand()) >= randmax) {
- /* no-op */
- }
-
- return rand % max;
- }
-}
-
-template <class TRandType, class T>
-struct TCommonRNG {
- using TResult = TRandType;
+
+ const T randmax = gen.RandMax() - gen.RandMax() % max;
+ T rand;
+
+ while ((rand = gen.GenRand()) >= randmax) {
+ /* no-op */
+ }
+
+ return rand % max;
+ }
+}
+
+template <class TRandType, class T>
+struct TCommonRNG {
+ using TResult = TRandType;
using result_type = TRandType;
-
+
inline T& Engine() noexcept {
- return static_cast<T&>(*this);
- }
-
- static constexpr TResult _Min = TResult(0);
- static constexpr TResult _Max = TResult(-1);
-
+ return static_cast<T&>(*this);
+ }
+
+ static constexpr TResult _Min = TResult(0);
+ static constexpr TResult _Max = TResult(-1);
+
static constexpr TResult RandMax() noexcept {
- return _Max;
- }
-
+ return _Max;
+ }
+
static constexpr TResult RandMin() noexcept {
- return _Min;
- }
-
- /* generates uniformly distributed random number on [0, t) interval */
+ return _Min;
+ }
+
+ /* generates uniformly distributed random number on [0, t) interval */
inline TResult Uniform(TResult t) noexcept {
- return ::NPrivate::GenUniform(t, Engine());
- }
-
- /* generates uniformly distributed random number on [f, t) interval */
+ return ::NPrivate::GenUniform(t, Engine());
+ }
+
+ /* generates uniformly distributed random number on [f, t) interval */
inline TResult Uniform(TResult f, TResult t) noexcept {
- return f + Uniform(t - f);
- }
-
- /* generates 64-bit random number for current(may be 32 bit) rng */
+ return f + Uniform(t - f);
+ }
+
+ /* generates 64-bit random number for current(may be 32 bit) rng */
inline ui64 GenRand64() noexcept {
- return ::NPrivate::ToRand64(Engine(), Engine().GenRand());
- }
-
- /* generates a random number on [0, 1]-real-interval */
+ return ::NPrivate::ToRand64(Engine(), Engine().GenRand());
+ }
+
+ /* generates a random number on [0, 1]-real-interval */
inline double GenRandReal1() noexcept {
- return ::NPrivate::ToRandReal1(Engine().GenRand());
- }
-
- /* generates a random number on [0, 1)-real-interval */
+ return ::NPrivate::ToRandReal1(Engine().GenRand());
+ }
+
+ /* generates a random number on [0, 1)-real-interval */
inline double GenRandReal2() noexcept {
- return ::NPrivate::ToRandReal2(Engine().GenRand());
- }
-
- /* generates a random number on (0, 1)-real-interval */
+ return ::NPrivate::ToRandReal2(Engine().GenRand());
+ }
+
+ /* generates a random number on (0, 1)-real-interval */
inline double GenRandReal3() noexcept {
- return ::NPrivate::ToRandReal3(Engine().GenRand());
- }
-
- /* generates a random number on [0, 1) with 53-bit resolution */
+ return ::NPrivate::ToRandReal3(Engine().GenRand());
+ }
+
+ /* generates a random number on [0, 1) with 53-bit resolution */
inline double GenRandReal4() noexcept {
- return ::NPrivate::ToRandReal4(Engine().GenRand64());
- }
-
- //compatibility stuff
+ return ::NPrivate::ToRandReal4(Engine().GenRand64());
+ }
+
+ //compatibility stuff
inline TResult operator()() noexcept {
- return Engine().GenRand();
- }
-
+ return Engine().GenRand();
+ }
+
static constexpr TResult max() noexcept {
- return T::RandMax();
- }
-
+ return T::RandMax();
+ }
+
static constexpr TResult min() noexcept {
- return T::RandMin();
- }
-};
+ return T::RandMin();
+ }
+};
diff --git a/util/random/common_ops_ut.cpp b/util/random/common_ops_ut.cpp
index 3610b5d2ff..905912bd1e 100644
--- a/util/random/common_ops_ut.cpp
+++ b/util/random/common_ops_ut.cpp
@@ -1,69 +1,69 @@
-#include "common_ops.h"
-#include "random.h"
-
+#include "common_ops.h"
+#include "random.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/digest/numeric.h>
-
-#include <random>
-
+
+#include <util/digest/numeric.h>
+
+#include <random>
+
Y_UNIT_TEST_SUITE(TestCommonRNG) {
- template <class T>
- struct TRng: public TCommonRNG<T, TRng<T>> {
+ template <class T>
+ struct TRng: public TCommonRNG<T, TRng<T>> {
inline T GenRand() noexcept {
- return IntHash(C_++);
- }
-
- T C_ = RandomNumber<T>();
- };
-
+ return IntHash(C_++);
+ }
+
+ T C_ = RandomNumber<T>();
+ };
+
Y_UNIT_TEST(TestUniform1) {
- TRng<ui32> r;
-
- for (size_t i = 0; i < 1000; ++i) {
- UNIT_ASSERT(r.Uniform(10) < 10);
- }
- }
-
+ TRng<ui32> r;
+
+ for (size_t i = 0; i < 1000; ++i) {
+ UNIT_ASSERT(r.Uniform(10) < 10);
+ }
+ }
+
Y_UNIT_TEST(TestUniform2) {
- TRng<ui32> r;
-
- for (size_t i = 0; i < 1000; ++i) {
- UNIT_ASSERT(r.Uniform(1) == 0);
- }
- }
-
+ TRng<ui32> r;
+
+ for (size_t i = 0; i < 1000; ++i) {
+ UNIT_ASSERT(r.Uniform(1) == 0);
+ }
+ }
+
Y_UNIT_TEST(TestUniform3) {
- TRng<ui32> r;
-
- for (size_t i = 0; i < 1000; ++i) {
- auto x = r.Uniform(100, 200);
-
- UNIT_ASSERT(x >= 100);
- UNIT_ASSERT(x < 200);
- }
- }
-
+ TRng<ui32> r;
+
+ for (size_t i = 0; i < 1000; ++i) {
+ auto x = r.Uniform(100, 200);
+
+ UNIT_ASSERT(x >= 100);
+ UNIT_ASSERT(x < 200);
+ }
+ }
+
Y_UNIT_TEST(TestStlCompatibility) {
- {
- TRng<ui32> r;
- r.C_ = 17;
- std::normal_distribution<float> nd(0, 1);
- UNIT_ASSERT_DOUBLES_EQUAL(nd(r), -0.877167, 0.01);
- }
-
- {
- TRng<ui64> r;
- r.C_ = 17;
- std::normal_distribution<double> nd(0, 1);
- UNIT_ASSERT_DOUBLES_EQUAL(nd(r), -0.5615566731, 0.01);
- }
-
- {
- TRng<ui16> r;
- r.C_ = 17;
- std::normal_distribution<long double> nd(0, 1);
- UNIT_ASSERT_DOUBLES_EQUAL(nd(r), -0.430375088, 0.01);
- }
- }
-}
+ {
+ TRng<ui32> r;
+ r.C_ = 17;
+ std::normal_distribution<float> nd(0, 1);
+ UNIT_ASSERT_DOUBLES_EQUAL(nd(r), -0.877167, 0.01);
+ }
+
+ {
+ TRng<ui64> r;
+ r.C_ = 17;
+ std::normal_distribution<double> nd(0, 1);
+ UNIT_ASSERT_DOUBLES_EQUAL(nd(r), -0.5615566731, 0.01);
+ }
+
+ {
+ TRng<ui16> r;
+ r.C_ = 17;
+ std::normal_distribution<long double> nd(0, 1);
+ UNIT_ASSERT_DOUBLES_EQUAL(nd(r), -0.430375088, 0.01);
+ }
+ }
+}
diff --git a/util/random/easy.cpp b/util/random/easy.cpp
index a82cbed95f..a92f4e9017 100644
--- a/util/random/easy.cpp
+++ b/util/random/easy.cpp
@@ -1 +1 @@
-#include "easy.h"
+#include "easy.h"
diff --git a/util/random/easy.h b/util/random/easy.h
index 80c5f7099a..fd5b826fbe 100644
--- a/util/random/easy.h
+++ b/util/random/easy.h
@@ -1,47 +1,47 @@
-#pragma once
-
-#include "random.h"
-
-namespace NPrivate {
- struct TRandom {
- inline operator unsigned char() {
- return RandomNumber<unsigned char>();
- }
-
- inline operator unsigned short() {
- return RandomNumber<unsigned short>();
- }
-
- inline operator unsigned int() {
- return RandomNumber<unsigned int>();
- }
-
- inline operator unsigned long() {
- return RandomNumber<unsigned long>();
- }
-
- inline operator unsigned long long() {
- return RandomNumber<unsigned long long>();
- }
-
- inline operator bool() {
- return RandomNumber<bool>();
- }
-
- inline operator float() {
- return RandomNumber<float>();
- }
-
- inline operator double() {
- return RandomNumber<double>();
- }
-
- inline operator long double() {
- return RandomNumber<long double>();
- }
- };
-}
-
+#pragma once
+
+#include "random.h"
+
+namespace NPrivate {
+ struct TRandom {
+ inline operator unsigned char() {
+ return RandomNumber<unsigned char>();
+ }
+
+ inline operator unsigned short() {
+ return RandomNumber<unsigned short>();
+ }
+
+ inline operator unsigned int() {
+ return RandomNumber<unsigned int>();
+ }
+
+ inline operator unsigned long() {
+ return RandomNumber<unsigned long>();
+ }
+
+ inline operator unsigned long long() {
+ return RandomNumber<unsigned long long>();
+ }
+
+ inline operator bool() {
+ return RandomNumber<bool>();
+ }
+
+ inline operator float() {
+ return RandomNumber<float>();
+ }
+
+ inline operator double() {
+ return RandomNumber<double>();
+ }
+
+ inline operator long double() {
+ return RandomNumber<long double>();
+ }
+ };
+}
+
static inline ::NPrivate::TRandom Random() noexcept {
- return {};
-}
+ return {};
+}
diff --git a/util/random/easy_ut.cpp b/util/random/easy_ut.cpp
index a0f6c21976..d1d024a91f 100644
--- a/util/random/easy_ut.cpp
+++ b/util/random/easy_ut.cpp
@@ -1,35 +1,35 @@
-#include "easy.h"
-
+#include "easy.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
+
Y_UNIT_TEST_SUITE(TEasyRndInterface) {
Y_UNIT_TEST(Test1) {
- {
- ui32 x = 0;
-
- x = Random();
-
- if (!x) {
- x = Random();
- }
-
- UNIT_ASSERT(x != 0);
- }
-
- {
- ui64 x = 0;
-
- x = Random();
-
- UNIT_ASSERT(x != 0);
- }
-
- {
- long double x = 0;
-
- x = Random();
-
- UNIT_ASSERT(x != 0);
- }
- }
-}
+ {
+ ui32 x = 0;
+
+ x = Random();
+
+ if (!x) {
+ x = Random();
+ }
+
+ UNIT_ASSERT(x != 0);
+ }
+
+ {
+ ui64 x = 0;
+
+ x = Random();
+
+ UNIT_ASSERT(x != 0);
+ }
+
+ {
+ long double x = 0;
+
+ x = Random();
+
+ UNIT_ASSERT(x != 0);
+ }
+ }
+}
diff --git a/util/random/entropy.cpp b/util/random/entropy.cpp
index 33213cbe15..3617edb83d 100644
--- a/util/random/entropy.cpp
+++ b/util/random/entropy.cpp
@@ -1,221 +1,221 @@
-#include "fast.h"
-#include "random.h"
-#include "entropy.h"
-#include "mersenne.h"
-#include "shuffle.h"
-#include "init_atfork.h"
-
+#include "fast.h"
+#include "random.h"
+#include "entropy.h"
+#include "mersenne.h"
+#include "shuffle.h"
+#include "init_atfork.h"
+
#include <util/stream/output.h>
#include <util/stream/mem.h>
-#include <util/stream/zlib.h>
+#include <util/stream/zlib.h>
#include <util/stream/buffer.h>
-
-#include <util/system/fs.h>
-#include <util/system/info.h>
-#include <util/system/spinlock.h>
-#include <util/system/thread.h>
+
+#include <util/system/fs.h>
+#include <util/system/info.h>
+#include <util/system/spinlock.h>
+#include <util/system/thread.h>
#include <util/system/execpath.h>
-#include <util/system/datetime.h>
-#include <util/system/hostname.h>
-#include <util/system/getpid.h>
-#include <util/system/mem_info.h>
-#include <util/system/rusage.h>
-#include <util/system/cpu_id.h>
-#include <util/system/unaligned_mem.h>
-
-#include <util/generic/buffer.h>
-#include <util/generic/singleton.h>
-
+#include <util/system/datetime.h>
+#include <util/system/hostname.h>
+#include <util/system/getpid.h>
+#include <util/system/mem_info.h>
+#include <util/system/rusage.h>
+#include <util/system/cpu_id.h>
+#include <util/system/unaligned_mem.h>
+
+#include <util/generic/buffer.h>
+#include <util/generic/singleton.h>
+
#include <util/digest/murmur.h>
-#include <util/digest/city.h>
-
-#include <util/ysaveload.h>
-
-namespace {
- inline void Permute(char* buf, size_t len, ui32 seed) noexcept {
- Shuffle(buf, buf + len, TReallyFastRng32(seed));
- }
-
- struct THostEntropy: public TBuffer {
- inline THostEntropy() {
- {
- TBufferOutput buf(*this);
- TZLibCompress out(&buf);
-
- Save(&out, GetPID());
- Save(&out, GetCycleCount());
- Save(&out, MicroSeconds());
- Save(&out, TThread::CurrentThreadId());
- Save(&out, NSystemInfo::CachedNumberOfCpus());
- Save(&out, NSystemInfo::TotalMemorySize());
- Save(&out, HostName());
-
- try {
- Save(&out, GetExecPath());
- } catch (...) {
- //workaround - sometimes fails on FreeBSD
- }
-
- Save(&out, (size_t)Data());
- Save(&out, (size_t)&buf);
-
- {
- double la[3];
-
- NSystemInfo::LoadAverage(la, Y_ARRAY_SIZE(la));
-
- out.Write(la, sizeof(la));
- }
-
- {
- auto mi = NMemInfo::GetMemInfo();
-
- out.Write(&mi, sizeof(mi));
- }
-
- {
- auto ru = TRusage::Get();
-
- out.Write(&ru, sizeof(ru));
- }
-
- {
- ui32 store[12];
-
- out << TStringBuf(CpuBrand(store));
- }
-
- out << NFs::CurrentWorkingDirectory();
-
- out.Finish();
- }
-
- {
- TMemoryOutput out(Data(), Size());
-
- //replace zlib header with hash
- Save(&out, CityHash64(Data(), Size()));
- }
-
- Permute(Data(), Size(), MurmurHash<ui32>(Data(), Size()));
- }
- };
-
- //not thread-safe
+#include <util/digest/city.h>
+
+#include <util/ysaveload.h>
+
+namespace {
+ inline void Permute(char* buf, size_t len, ui32 seed) noexcept {
+ Shuffle(buf, buf + len, TReallyFastRng32(seed));
+ }
+
+ struct THostEntropy: public TBuffer {
+ inline THostEntropy() {
+ {
+ TBufferOutput buf(*this);
+ TZLibCompress out(&buf);
+
+ Save(&out, GetPID());
+ Save(&out, GetCycleCount());
+ Save(&out, MicroSeconds());
+ Save(&out, TThread::CurrentThreadId());
+ Save(&out, NSystemInfo::CachedNumberOfCpus());
+ Save(&out, NSystemInfo::TotalMemorySize());
+ Save(&out, HostName());
+
+ try {
+ Save(&out, GetExecPath());
+ } catch (...) {
+ //workaround - sometimes fails on FreeBSD
+ }
+
+ Save(&out, (size_t)Data());
+ Save(&out, (size_t)&buf);
+
+ {
+ double la[3];
+
+ NSystemInfo::LoadAverage(la, Y_ARRAY_SIZE(la));
+
+ out.Write(la, sizeof(la));
+ }
+
+ {
+ auto mi = NMemInfo::GetMemInfo();
+
+ out.Write(&mi, sizeof(mi));
+ }
+
+ {
+ auto ru = TRusage::Get();
+
+ out.Write(&ru, sizeof(ru));
+ }
+
+ {
+ ui32 store[12];
+
+ out << TStringBuf(CpuBrand(store));
+ }
+
+ out << NFs::CurrentWorkingDirectory();
+
+ out.Finish();
+ }
+
+ {
+ TMemoryOutput out(Data(), Size());
+
+ //replace zlib header with hash
+ Save(&out, CityHash64(Data(), Size()));
+ }
+
+ Permute(Data(), Size(), MurmurHash<ui32>(Data(), Size()));
+ }
+ };
+
+ //not thread-safe
class TMersenneInput: public IInputStream {
using TKey = ui64;
using TRnd = TMersenne<TKey>;
-
- public:
+
+ public:
inline explicit TMersenneInput(const TBuffer& rnd)
- : Rnd_((const TKey*)rnd.Data(), rnd.Size() / sizeof(TKey))
- {
- }
-
+ : Rnd_((const TKey*)rnd.Data(), rnd.Size() / sizeof(TKey))
+ {
+ }
+
~TMersenneInput() override = default;
-
+
size_t DoRead(void* buf, size_t len) override {
- size_t toRead = len;
-
- while (toRead) {
- const TKey next = Rnd_.GenRand();
- const size_t toCopy = Min(toRead, sizeof(next));
-
- memcpy(buf, &next, toCopy);
-
- buf = (char*)buf + toCopy;
- toRead -= toCopy;
- }
-
- return len;
- }
-
- private:
- TRnd Rnd_;
- };
-
+ size_t toRead = len;
+
+ while (toRead) {
+ const TKey next = Rnd_.GenRand();
+ const size_t toCopy = Min(toRead, sizeof(next));
+
+ memcpy(buf, &next, toCopy);
+
+ buf = (char*)buf + toCopy;
+ toRead -= toCopy;
+ }
+
+ return len;
+ }
+
+ private:
+ TRnd Rnd_;
+ };
+
class TEntropyPoolStream: public IInputStream {
- public:
+ public:
inline explicit TEntropyPoolStream(const TBuffer& buffer)
- : Mi_(buffer)
- , Bi_(&Mi_, 8192)
- {
- }
-
+ : Mi_(buffer)
+ , Bi_(&Mi_, 8192)
+ {
+ }
+
size_t DoRead(void* buf, size_t len) override {
- auto guard = Guard(Mutex_);
-
- return Bi_.Read(buf, len);
- }
-
- private:
- TAdaptiveLock Mutex_;
- TMersenneInput Mi_;
- TBufferedInput Bi_;
- };
-
+ auto guard = Guard(Mutex_);
+
+ return Bi_.Read(buf, len);
+ }
+
+ private:
+ TAdaptiveLock Mutex_;
+ TMersenneInput Mi_;
+ TBufferedInput Bi_;
+ };
+
struct TSeedStream: public IInputStream {
size_t DoRead(void* inbuf, size_t len) override {
- char* buf = (char*)inbuf;
-
-#define DO_STEP(type) \
- while (len >= sizeof(type)) { \
+ char* buf = (char*)inbuf;
+
+#define DO_STEP(type) \
+ while (len >= sizeof(type)) { \
WriteUnaligned<type>(buf, RandomNumber<type>()); \
- buf += sizeof(type); \
- len -= sizeof(type); \
- }
-
- DO_STEP(ui64);
- DO_STEP(ui32);
- DO_STEP(ui16);
- DO_STEP(ui8);
-
-#undef DO_STEP
-
- return buf - (char*)inbuf;
- }
- };
-
- struct TDefaultTraits {
+ buf += sizeof(type); \
+ len -= sizeof(type); \
+ }
+
+ DO_STEP(ui64);
+ DO_STEP(ui32);
+ DO_STEP(ui16);
+ DO_STEP(ui8);
+
+#undef DO_STEP
+
+ return buf - (char*)inbuf;
+ }
+ };
+
+ struct TDefaultTraits {
THolder<TEntropyPoolStream> EP;
- TSeedStream SS;
-
- inline TDefaultTraits() {
+ TSeedStream SS;
+
+ inline TDefaultTraits() {
Reset();
- }
-
+ }
+
inline IInputStream& EntropyPool() noexcept {
return *EP;
- }
-
+ }
+
inline IInputStream& Seed() noexcept {
- return SS;
- }
-
+ return SS;
+ }
+
inline void Reset() noexcept {
EP.Reset(new TEntropyPoolStream(THostEntropy()));
}
- static inline TDefaultTraits& Instance() {
- auto res = SingletonWithPriority<TDefaultTraits, 0>();
-
- RNGInitAtForkHandlers();
-
- return *res;
- }
- };
-
- using TRandomTraits = TDefaultTraits;
-}
-
+ static inline TDefaultTraits& Instance() {
+ auto res = SingletonWithPriority<TDefaultTraits, 0>();
+
+ RNGInitAtForkHandlers();
+
+ return *res;
+ }
+ };
+
+ using TRandomTraits = TDefaultTraits;
+}
+
IInputStream& EntropyPool() {
- return TRandomTraits::Instance().EntropyPool();
-}
-
+ return TRandomTraits::Instance().EntropyPool();
+}
+
IInputStream& Seed() {
- return TRandomTraits::Instance().Seed();
-}
-
+ return TRandomTraits::Instance().Seed();
+}
+
void ResetEntropyPool() {
TRandomTraits::Instance().Reset();
-}
+}
diff --git a/util/random/entropy.h b/util/random/entropy.h
index fc3d015b7a..62029c1b63 100644
--- a/util/random/entropy.h
+++ b/util/random/entropy.h
@@ -1,21 +1,21 @@
#pragma once
-
-class TBuffer;
+
+class TBuffer;
class IInputStream;
-
-/*
- * fast entropy pool, based on good prng, can lock for some time
- * initialized with some bits from system entropy pool
- * think as /dev/urandom replacement
- */
+
+/*
+ * fast entropy pool, based on good prng, can lock for some time
+ * initialized with some bits from system entropy pool
+ * think as /dev/urandom replacement
+ */
IInputStream& EntropyPool();
-
-/*
- * fast(non-blocking) entropy pool, useful for seeding PRNGs
- */
+
+/*
+ * fast(non-blocking) entropy pool, useful for seeding PRNGs
+ */
IInputStream& Seed();
-
-/*
+
+/*
* Re-initialize entropy pool - useful after forking in multi-process programs.
- */
+ */
void ResetEntropyPool();
diff --git a/util/random/entropy_ut.cpp b/util/random/entropy_ut.cpp
index 9139e70203..1ff27203f0 100644
--- a/util/random/entropy_ut.cpp
+++ b/util/random/entropy_ut.cpp
@@ -1,13 +1,13 @@
-#include "entropy.h"
-
+#include "entropy.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
+
Y_UNIT_TEST_SUITE(TestEntropy) {
Y_UNIT_TEST(TestSeed) {
- char buf[100];
-
- for (size_t i = 0; i < sizeof(buf); ++i) {
- Seed().LoadOrFail(buf, i);
- }
- }
-}
+ char buf[100];
+
+ for (size_t i = 0; i < sizeof(buf); ++i) {
+ Seed().LoadOrFail(buf, i);
+ }
+ }
+}
diff --git a/util/random/fast.cpp b/util/random/fast.cpp
index c4b869318a..2f98dfc5d3 100644
--- a/util/random/fast.cpp
+++ b/util/random/fast.cpp
@@ -1,52 +1,52 @@
-#include "fast.h"
-
-#include <util/stream/input.h>
-
+#include "fast.h"
+
+#include <util/stream/input.h>
+
static inline ui32 FixSeq(ui32 seq1, ui32 seq2) noexcept {
- const ui32 mask = (~(ui32)(0)) >> 1;
-
- if ((seq1 & mask) == (seq2 & mask)) {
- return ~seq2;
- }
-
- return seq2;
-}
-
+ const ui32 mask = (~(ui32)(0)) >> 1;
+
+ if ((seq1 & mask) == (seq2 & mask)) {
+ return ~seq2;
+ }
+
+ return seq2;
+}
+
TFastRng64::TFastRng64(ui64 seed1, ui32 seq1, ui64 seed2, ui32 seq2) noexcept
- : R1_(seed1, seq1)
- , R2_(seed2, FixSeq(seq1, seq2))
-{
-}
-
+ : R1_(seed1, seq1)
+ , R2_(seed2, FixSeq(seq1, seq2))
+{
+}
+
TFastRng64::TArgs::TArgs(ui64 seed) noexcept {
- TReallyFastRng32 rng(seed);
-
- Seed1 = rng.GenRand64();
- Seq1 = rng.GenRand();
- Seed2 = rng.GenRand64();
- Seq2 = rng.GenRand();
-}
-
+ TReallyFastRng32 rng(seed);
+
+ Seed1 = rng.GenRand64();
+ Seq1 = rng.GenRand();
+ Seed2 = rng.GenRand64();
+ Seq2 = rng.GenRand();
+}
+
TFastRng64::TArgs::TArgs(IInputStream& entropy) {
- static_assert(sizeof(*this) == 3 * sizeof(ui64), "please, fix me");
- entropy.LoadOrFail(this, sizeof(*this));
-}
-
-template <class T>
+ static_assert(sizeof(*this) == 3 * sizeof(ui64), "please, fix me");
+ entropy.LoadOrFail(this, sizeof(*this));
+}
+
+template <class T>
static inline T Read(IInputStream& in) noexcept {
- T t = T();
-
- in.LoadOrFail(&t, sizeof(t));
-
- return t;
-}
-
+ T t = T();
+
+ in.LoadOrFail(&t, sizeof(t));
+
+ return t;
+}
+
TFastRng32::TFastRng32(IInputStream& entropy)
- : TFastRng32(Read<ui64>(entropy), Read<ui32>(entropy))
-{
-}
-
+ : TFastRng32(Read<ui64>(entropy), Read<ui32>(entropy))
+{
+}
+
TReallyFastRng32::TReallyFastRng32(IInputStream& entropy)
- : TReallyFastRng32(Read<ui64>(entropy))
-{
-}
+ : TReallyFastRng32(Read<ui64>(entropy))
+{
+}
diff --git a/util/random/fast.h b/util/random/fast.h
index 69b1772dd8..ddc5711641 100644
--- a/util/random/fast.h
+++ b/util/random/fast.h
@@ -1,101 +1,101 @@
-#pragma once
-
-#include "lcg_engine.h"
-#include "common_ops.h"
-
+#pragma once
+
+#include "lcg_engine.h"
+#include "common_ops.h"
+
#include <util/generic/bitops.h>
-#include <util/system/platform.h>
-
-// based on http://www.pcg-random.org/. See T*FastRng* family below.
-
-struct TPCGMixer {
+#include <util/system/platform.h>
+
+// based on http://www.pcg-random.org/. See T*FastRng* family below.
+
+struct TPCGMixer {
static inline ui32 Mix(ui64 x) noexcept {
- const ui32 xorshifted = ((x >> 18u) ^ x) >> 27u;
- const ui32 rot = x >> 59u;
-
+ const ui32 xorshifted = ((x >> 18u) ^ x) >> 27u;
+ const ui32 rot = x >> 59u;
+
return RotateBitsRight(xorshifted, rot);
- }
-};
-
-using TFastRng32Base = TLcgRngBase<TLcgIterator<ui64, ULL(6364136223846793005)>, TPCGMixer>;
-using TReallyFastRng32Base = TLcgRngBase<TFastLcgIterator<ui64, ULL(6364136223846793005), ULL(1)>, TPCGMixer>;
-
+ }
+};
+
+using TFastRng32Base = TLcgRngBase<TLcgIterator<ui64, ULL(6364136223846793005)>, TPCGMixer>;
+using TReallyFastRng32Base = TLcgRngBase<TFastLcgIterator<ui64, ULL(6364136223846793005), ULL(1)>, TPCGMixer>;
+
class IInputStream;
-
-struct TFastRng32: public TCommonRNG<ui32, TFastRng32>, public TFastRng32Base {
- inline TFastRng32(ui64 seed, ui32 seq)
- : TFastRng32Base(seed, seq)
- {
- }
-
+
+struct TFastRng32: public TCommonRNG<ui32, TFastRng32>, public TFastRng32Base {
+ inline TFastRng32(ui64 seed, ui32 seq)
+ : TFastRng32Base(seed, seq)
+ {
+ }
+
TFastRng32(IInputStream& entropy);
-};
-
-// faster than TFastRng32, but have only one possible stream sequence
-struct TReallyFastRng32: public TCommonRNG<ui32, TReallyFastRng32>, public TReallyFastRng32Base {
- inline TReallyFastRng32(ui64 seed)
- : TReallyFastRng32Base(seed)
- {
- }
-
+};
+
+// faster than TFastRng32, but have only one possible stream sequence
+struct TReallyFastRng32: public TCommonRNG<ui32, TReallyFastRng32>, public TReallyFastRng32Base {
+ inline TReallyFastRng32(ui64 seed)
+ : TReallyFastRng32Base(seed)
+ {
+ }
+
TReallyFastRng32(IInputStream& entropy);
-};
-
-class TFastRng64: public TCommonRNG<ui64, TFastRng64> {
-public:
- struct TArgs {
+};
+
+class TFastRng64: public TCommonRNG<ui64, TFastRng64> {
+public:
+ struct TArgs {
TArgs(ui64 seed) noexcept;
TArgs(IInputStream& entropy);
-
- ui64 Seed1;
- ui64 Seed2;
- ui32 Seq1;
- ui32 Seq2;
- };
-
+
+ ui64 Seed1;
+ ui64 Seed2;
+ ui32 Seq1;
+ ui32 Seq2;
+ };
+
TFastRng64(ui64 seed1, ui32 seq1, ui64 seed2, ui32 seq2) noexcept;
-
- /*
- * simplify constructions like
- * TFastRng64 rng(17);
+
+ /*
+ * simplify constructions like
+ * TFastRng64 rng(17);
* TFastRng64 rng(Seek()); //from any IInputStream
- */
+ */
inline TFastRng64(const TArgs& args) noexcept
- : TFastRng64(args.Seed1, args.Seq1, args.Seed2, args.Seq2)
- {
- }
-
+ : TFastRng64(args.Seed1, args.Seq1, args.Seed2, args.Seq2)
+ {
+ }
+
inline ui64 GenRand() noexcept {
- const ui64 x = R1_.GenRand();
- const ui64 y = R2_.GenRand();
-
- return (x << 32) | y;
- }
-
+ const ui64 x = R1_.GenRand();
+ const ui64 y = R2_.GenRand();
+
+ return (x << 32) | y;
+ }
+
inline void Advance(ui64 delta) noexcept {
R1_.Advance(delta);
R2_.Advance(delta);
}
-private:
- TFastRng32Base R1_;
- TFastRng32Base R2_;
-};
-
-namespace NPrivate {
- template <typename T>
- struct TFastRngTraits;
-
- template <>
- struct TFastRngTraits<ui32> {
- using TResult = TReallyFastRng32;
- };
-
- template <>
- struct TFastRngTraits<ui64> {
- using TResult = TFastRng64;
- };
-}
-
-template <typename T>
-using TFastRng = typename ::NPrivate::TFastRngTraits<T>::TResult;
+private:
+ TFastRng32Base R1_;
+ TFastRng32Base R2_;
+};
+
+namespace NPrivate {
+ template <typename T>
+ struct TFastRngTraits;
+
+ template <>
+ struct TFastRngTraits<ui32> {
+ using TResult = TReallyFastRng32;
+ };
+
+ template <>
+ struct TFastRngTraits<ui64> {
+ using TResult = TFastRng64;
+ };
+}
+
+template <typename T>
+using TFastRng = typename ::NPrivate::TFastRngTraits<T>::TResult;
diff --git a/util/random/fast_ut.cpp b/util/random/fast_ut.cpp
index 032fd65b84..60994a98b0 100644
--- a/util/random/fast_ut.cpp
+++ b/util/random/fast_ut.cpp
@@ -1,62 +1,62 @@
-#include "fast.h"
-
+#include "fast.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
+
Y_UNIT_TEST_SUITE(TTestFastRng) {
Y_UNIT_TEST(Test1) {
- TFastRng32 rng1(17, 0);
- TReallyFastRng32 rng2(17);
-
- for (size_t i = 0; i < 1000; ++i) {
- UNIT_ASSERT_VALUES_EQUAL(rng1.GenRand(), rng2.GenRand());
- }
- }
-
- static ui64 R1[] = {
- 37,
- 43,
- 76,
- 17,
- 12,
- 87,
- 60,
- 4,
- 83,
- 47,
- 57,
- 81,
- 28,
- 45,
- 66,
- 74,
- 18,
- 17,
- 18,
- 75,
- };
-
+ TFastRng32 rng1(17, 0);
+ TReallyFastRng32 rng2(17);
+
+ for (size_t i = 0; i < 1000; ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(rng1.GenRand(), rng2.GenRand());
+ }
+ }
+
+ static ui64 R1[] = {
+ 37,
+ 43,
+ 76,
+ 17,
+ 12,
+ 87,
+ 60,
+ 4,
+ 83,
+ 47,
+ 57,
+ 81,
+ 28,
+ 45,
+ 66,
+ 74,
+ 18,
+ 17,
+ 18,
+ 75,
+ };
+
Y_UNIT_TEST(Test2) {
- TFastRng64 rng(0, 1, 2, 3);
-
+ TFastRng64 rng(0, 1, 2, 3);
+
for (auto& i : R1) {
UNIT_ASSERT_VALUES_EQUAL(rng.Uniform(100u), i);
- }
- }
+ }
+ }
Y_UNIT_TEST(TestAdvance) {
TReallyFastRng32 rng1(17);
TReallyFastRng32 rng2(17);
- for (size_t i = 0; i < 100; i++) {
+ for (size_t i = 0; i < 100; i++) {
rng1.GenRand();
- }
+ }
rng2.Advance(100);
UNIT_ASSERT_VALUES_EQUAL(rng1.GenRand(), rng2.GenRand());
TFastRng64 rng3(0, 1, 2, 3);
TFastRng64 rng4(0, 1, 2, 3);
- for (size_t i = 0; i < 100; i++) {
+ for (size_t i = 0; i < 100; i++) {
rng3.GenRand();
- }
+ }
rng4.Advance(100);
UNIT_ASSERT_VALUES_EQUAL(rng3.GenRand(), rng4.GenRand());
}
@@ -70,50 +70,50 @@ Y_UNIT_TEST_SUITE(TTestFastRng) {
UNIT_ASSERT_VALUES_EQUAL(rng1.GenRand(), rng2.GenRand());
UNIT_ASSERT_VALUES_EQUAL(rng1.GenRand(), rng3.GenRand());
}
-
+
Y_UNIT_TEST(TestCopy) {
- TReallyFastRng32 r1(1);
- TReallyFastRng32 r2(2);
-
- UNIT_ASSERT_VALUES_UNEQUAL(r1.GenRand(), r2.GenRand());
-
- r2 = r1;
-
- UNIT_ASSERT_VALUES_EQUAL(r1.GenRand(), r2.GenRand());
- }
-
+ TReallyFastRng32 r1(1);
+ TReallyFastRng32 r2(2);
+
+ UNIT_ASSERT_VALUES_UNEQUAL(r1.GenRand(), r2.GenRand());
+
+ r2 = r1;
+
+ UNIT_ASSERT_VALUES_EQUAL(r1.GenRand(), r2.GenRand());
+ }
+
Y_UNIT_TEST(Test3) {
- TFastRng64 rng(17);
-
- UNIT_ASSERT_VALUES_EQUAL(rng.GenRand(), ULL(14895365814383052362));
- }
-
+ TFastRng64 rng(17);
+
+ UNIT_ASSERT_VALUES_EQUAL(rng.GenRand(), ULL(14895365814383052362));
+ }
+
Y_UNIT_TEST(TestCompile) {
- TFastRng<ui32> rng1(1);
- TFastRng<ui64> rng2(2);
- TFastRng<size_t> rng3(3);
-
- rng1.GenRand();
- rng2.GenRand();
- rng3.GenRand();
- }
-
- const char* RNG_DATA = "At the top of the department store I,"
- "I bought a fur coat with fur I"
- "But apparently I made a blunder here -"
- "Doha does not warm ... Absolutely.";
-
+ TFastRng<ui32> rng1(1);
+ TFastRng<ui64> rng2(2);
+ TFastRng<size_t> rng3(3);
+
+ rng1.GenRand();
+ rng2.GenRand();
+ rng3.GenRand();
+ }
+
+ const char* RNG_DATA = "At the top of the department store I,"
+ "I bought a fur coat with fur I"
+ "But apparently I made a blunder here -"
+ "Doha does not warm ... Absolutely.";
+
Y_UNIT_TEST(TestStreamCtor1) {
- TMemoryInput mi(RNG_DATA, strlen(RNG_DATA));
- TFastRng<ui32> rng(mi);
-
- UNIT_ASSERT_VALUES_EQUAL(rng.GenRand(), 1449109131u);
- }
-
+ TMemoryInput mi(RNG_DATA, strlen(RNG_DATA));
+ TFastRng<ui32> rng(mi);
+
+ UNIT_ASSERT_VALUES_EQUAL(rng.GenRand(), 1449109131u);
+ }
+
Y_UNIT_TEST(TestStreamCtor2) {
- TMemoryInput mi(RNG_DATA, strlen(RNG_DATA));
- TFastRng<ui64> rng(mi);
-
- UNIT_ASSERT_VALUES_EQUAL(rng.GenRand(), ULL(6223876579076085114));
- }
-}
+ TMemoryInput mi(RNG_DATA, strlen(RNG_DATA));
+ TFastRng<ui64> rng(mi);
+
+ UNIT_ASSERT_VALUES_EQUAL(rng.GenRand(), ULL(6223876579076085114));
+ }
+}
diff --git a/util/random/init_atfork.cpp b/util/random/init_atfork.cpp
index a7fb38de13..0faa3d119a 100644
--- a/util/random/init_atfork.cpp
+++ b/util/random/init_atfork.cpp
@@ -1,30 +1,30 @@
-#include "init_atfork.h"
-#include "random.h"
-#include "entropy.h"
-
-#include <util/generic/singleton.h>
+#include "init_atfork.h"
+#include "random.h"
+#include "entropy.h"
+
+#include <util/generic/singleton.h>
#include <util/system/yassert.h>
-
-#if defined(_unix_)
- #include <pthread.h>
-#endif
-
-namespace {
- struct TInit {
- inline TInit() noexcept {
+
+#if defined(_unix_)
+ #include <pthread.h>
+#endif
+
+namespace {
+ struct TInit {
+ inline TInit() noexcept {
(void)&AtFork;
-
-#if defined(_unix_)
+
+#if defined(_unix_)
Y_VERIFY(pthread_atfork(nullptr, AtFork, nullptr) == 0, "it happens");
-#endif
- }
-
- static void AtFork() noexcept {
- ResetRandomState();
- }
- };
-}
-
-void RNGInitAtForkHandlers() {
- SingletonWithPriority<TInit, 0>();
-}
+#endif
+ }
+
+ static void AtFork() noexcept {
+ ResetRandomState();
+ }
+ };
+}
+
+void RNGInitAtForkHandlers() {
+ SingletonWithPriority<TInit, 0>();
+}
diff --git a/util/random/init_atfork.h b/util/random/init_atfork.h
index 2dcb4239c6..be3506b4a0 100644
--- a/util/random/init_atfork.h
+++ b/util/random/init_atfork.h
@@ -1,3 +1,3 @@
-#pragma once
-
-void RNGInitAtForkHandlers();
+#pragma once
+
+void RNGInitAtForkHandlers();
diff --git a/util/random/lcg_engine.cpp b/util/random/lcg_engine.cpp
index 01e450c361..e1469104fa 100644
--- a/util/random/lcg_engine.cpp
+++ b/util/random/lcg_engine.cpp
@@ -1,4 +1,4 @@
-#include "lcg_engine.h"
+#include "lcg_engine.h"
namespace NPrivate {
template <typename T>
@@ -27,4 +27,4 @@ namespace NPrivate {
template ui32 LcgAdvance<ui32>(ui32, ui32, ui32, ui32) noexcept;
template ui64 LcgAdvance<ui64>(ui64, ui64, ui64, ui64) noexcept;
-}
+}
diff --git a/util/random/lcg_engine.h b/util/random/lcg_engine.h
index fcf8ab7166..08cc93c845 100644
--- a/util/random/lcg_engine.h
+++ b/util/random/lcg_engine.h
@@ -1,66 +1,66 @@
-#pragma once
-
+#pragma once
+
#include <utility>
-#include <util/generic/typetraits.h>
-
-// common engine for lcg-based RNG's
-// http://en.wikipedia.org/wiki/Linear_congruential_generator
-
+#include <util/generic/typetraits.h>
+
+// common engine for lcg-based RNG's
+// http://en.wikipedia.org/wiki/Linear_congruential_generator
+
namespace NPrivate {
template <typename T>
T LcgAdvance(T seed, T lcgBase, T lcgAddend, T delta) noexcept;
};
-template <typename T, T A, T C>
-struct TFastLcgIterator {
- static_assert(C % 2 == 1, "C must be odd");
-
+template <typename T, T A, T C>
+struct TFastLcgIterator {
+ static_assert(C % 2 == 1, "C must be odd");
+
static constexpr T Iterate(T x) noexcept {
- return x * A + C;
- }
+ return x * A + C;
+ }
static inline T IterateMultiple(T x, T delta) noexcept {
return ::NPrivate::LcgAdvance(x, A, C, delta);
}
-};
-
-template <typename T, T A>
-struct TLcgIterator {
+};
+
+template <typename T, T A>
+struct TLcgIterator {
inline TLcgIterator(T seq) noexcept
- : C((seq << 1u) | (T)1) // C must be odd
- {
- }
-
+ : C((seq << 1u) | (T)1) // C must be odd
+ {
+ }
+
inline T Iterate(T x) noexcept {
- return x * A + C;
- }
-
+ return x * A + C;
+ }
+
inline T IterateMultiple(T x, T delta) noexcept {
return ::NPrivate::LcgAdvance(x, A, C, delta);
}
- const T C;
-};
-
-template <class TIterator, class TMixer>
-struct TLcgRngBase: public TIterator, public TMixer {
+ const T C;
+};
+
+template <class TIterator, class TMixer>
+struct TLcgRngBase: public TIterator, public TMixer {
using TStateType = decltype(std::declval<TIterator>().Iterate(0));
using TResultType = decltype(std::declval<TMixer>().Mix(TStateType()));
-
- template <typename... Args>
- inline TLcgRngBase(TStateType seed, Args&&... args)
+
+ template <typename... Args>
+ inline TLcgRngBase(TStateType seed, Args&&... args)
: TIterator(std::forward<Args>(args)...)
- , X(seed)
- {
- }
-
+ , X(seed)
+ {
+ }
+
inline TResultType GenRand() noexcept {
- return this->Mix(X = this->Iterate(X));
- }
-
+ return this->Mix(X = this->Iterate(X));
+ }
+
inline void Advance(TStateType delta) noexcept {
X = this->IterateMultiple(X, delta);
}
- TStateType X;
-};
+ TStateType X;
+};
diff --git a/util/random/mersenne.h b/util/random/mersenne.h
index 464159c81d..b2044604ac 100644
--- a/util/random/mersenne.h
+++ b/util/random/mersenne.h
@@ -1,46 +1,46 @@
#pragma once
-
-#include "mersenne64.h"
-#include "mersenne32.h"
-#include "common_ops.h"
-
-namespace NPrivate {
- template <class T>
- struct TMersenneTraits;
-
- template <>
- struct TMersenneTraits<ui64> {
+
+#include "mersenne64.h"
+#include "mersenne32.h"
+#include "common_ops.h"
+
+namespace NPrivate {
+ template <class T>
+ struct TMersenneTraits;
+
+ template <>
+ struct TMersenneTraits<ui64> {
using TImpl = TMersenne64;
- };
-
- template <>
- struct TMersenneTraits<ui32> {
+ };
+
+ template <>
+ struct TMersenneTraits<ui32> {
using TImpl = TMersenne32;
- };
-}
-
+ };
+}
+
class IInputStream;
-
-template <class T>
+
+template <class T>
class TMersenne: public TCommonRNG<T, TMersenne<T>>, public ::NPrivate::TMersenneTraits<T>::TImpl {
-public:
+public:
using TBase = typename ::NPrivate::TMersenneTraits<T>::TImpl;
-
+
inline TMersenne() noexcept {
- }
-
+ }
+
inline TMersenne(T seed) noexcept
- : TBase(seed)
- {
- }
-
+ : TBase(seed)
+ {
+ }
+
inline TMersenne(IInputStream& pool)
- : TBase(pool)
- {
- }
-
+ : TBase(pool)
+ {
+ }
+
inline TMersenne(const T* keys, size_t len) noexcept
- : TBase(keys, len)
- {
- }
-};
+ : TBase(keys, len)
+ {
+ }
+};
diff --git a/util/random/mersenne32.cpp b/util/random/mersenne32.cpp
index a7a4d17b2c..cb8aad8b03 100644
--- a/util/random/mersenne32.cpp
+++ b/util/random/mersenne32.cpp
@@ -1,98 +1,98 @@
-#include "mersenne32.h"
-
-#include <util/generic/array_size.h>
-#include <util/stream/input.h>
-
-using namespace NPrivate;
-
-#define M 397
-#define MATRIX_A 0x9908b0dfUL
-#define UPPER_MASK 0x80000000UL
-#define LOWER_MASK 0x7fffffffUL
-
+#include "mersenne32.h"
+
+#include <util/generic/array_size.h>
+#include <util/stream/input.h>
+
+using namespace NPrivate;
+
+#define M 397
+#define MATRIX_A 0x9908b0dfUL
+#define UPPER_MASK 0x80000000UL
+#define LOWER_MASK 0x7fffffffUL
+
void TMersenne32::InitGenRand(ui32 s) noexcept {
- mt[0] = s;
-
- for (mti = 1; mti < N; ++mti) {
- mt[mti] = (1812433253UL * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti);
- }
-}
-
+ mt[0] = s;
+
+ for (mti = 1; mti < N; ++mti) {
+ mt[mti] = (1812433253UL * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti);
+ }
+}
+
void TMersenne32::InitByArray(const ui32 init_key[], size_t key_length) noexcept {
- InitGenRand(19650218UL);
-
- ui32 i = 1;
- ui32 j = 0;
- ui32 k = ui32(N > key_length ? N : key_length);
-
- for (; k; k--) {
- mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525UL)) + init_key[j] + j;
-
- ++i;
- ++j;
-
- if (i >= N) {
- mt[0] = mt[N - 1];
- i = 1;
- }
-
- if (j >= key_length) {
- j = 0;
- }
- }
-
- for (k = N - 1; k; k--) {
- mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941UL)) - i;
-
- ++i;
-
- if (i >= N) {
- mt[0] = mt[N - 1];
- i = 1;
- }
- }
-
- mt[0] = 0x80000000UL;
-}
-
+ InitGenRand(19650218UL);
+
+ ui32 i = 1;
+ ui32 j = 0;
+ ui32 k = ui32(N > key_length ? N : key_length);
+
+ for (; k; k--) {
+ mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525UL)) + init_key[j] + j;
+
+ ++i;
+ ++j;
+
+ if (i >= N) {
+ mt[0] = mt[N - 1];
+ i = 1;
+ }
+
+ if (j >= key_length) {
+ j = 0;
+ }
+ }
+
+ for (k = N - 1; k; k--) {
+ mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941UL)) - i;
+
+ ++i;
+
+ if (i >= N) {
+ mt[0] = mt[N - 1];
+ i = 1;
+ }
+ }
+
+ mt[0] = 0x80000000UL;
+}
+
void TMersenne32::InitNext() noexcept {
- int kk;
- ui32 y;
- ui32 mag01[2] = {
- 0x0UL,
- MATRIX_A,
- };
-
- if (mti == N + 1) {
- InitGenRand(5489UL);
- }
-
- for (kk = 0; kk < N - M; ++kk) {
- y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
- mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
-
- for (; kk < N - 1; ++kk) {
- y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
- mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
-
- y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
- mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1UL];
-
- mti = 0;
-}
-
+ int kk;
+ ui32 y;
+ ui32 mag01[2] = {
+ 0x0UL,
+ MATRIX_A,
+ };
+
+ if (mti == N + 1) {
+ InitGenRand(5489UL);
+ }
+
+ for (kk = 0; kk < N - M; ++kk) {
+ y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
+ mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+
+ for (; kk < N - 1; ++kk) {
+ y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
+ mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+
+ y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
+ mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+
+ mti = 0;
+}
+
TMersenne32::TMersenne32(IInputStream& input)
- : mti(N + 1)
-{
- ui32 buf[128];
-
- input.LoadOrFail(buf, sizeof(buf));
+ : mti(N + 1)
+{
+ ui32 buf[128];
+
+ input.LoadOrFail(buf, sizeof(buf));
InitByArray(buf, Y_ARRAY_SIZE(buf));
-}
-
-#undef M
-#undef MATRIX_A
-#undef UPPER_MASK
-#undef LOWER_MASK
+}
+
+#undef M
+#undef MATRIX_A
+#undef UPPER_MASK
+#undef LOWER_MASK
diff --git a/util/random/mersenne32.h b/util/random/mersenne32.h
index f0cc84832b..861f3a3d38 100644
--- a/util/random/mersenne32.h
+++ b/util/random/mersenne32.h
@@ -1,50 +1,50 @@
#pragma once
-
+
#include <util/system/defaults.h>
-
+
class IInputStream;
-
-namespace NPrivate {
- class TMersenne32 {
+
+namespace NPrivate {
+ class TMersenne32 {
static constexpr int N = 624;
-
- public:
+
+ public:
inline TMersenne32(ui32 s = 19650218UL) noexcept
- : mti(N + 1)
- {
- InitGenRand(s);
- }
-
+ : mti(N + 1)
+ {
+ InitGenRand(s);
+ }
+
inline TMersenne32(const ui32* init_key, size_t key_length) noexcept
- : mti(N + 1)
- {
- InitByArray(init_key, key_length);
- }
-
+ : mti(N + 1)
+ {
+ InitByArray(init_key, key_length);
+ }
+
TMersenne32(IInputStream& input);
-
+
inline ui32 GenRand() noexcept {
- if (mti >= N) {
- InitNext();
- }
-
- ui32 y = mt[mti++];
-
- y ^= (y >> 11);
- y ^= (y << 7) & 0x9d2c5680UL;
- y ^= (y << 15) & 0xefc60000UL;
- y ^= (y >> 18);
-
- return y;
- }
-
- private:
+ if (mti >= N) {
+ InitNext();
+ }
+
+ ui32 y = mt[mti++];
+
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680UL;
+ y ^= (y << 15) & 0xefc60000UL;
+ y ^= (y >> 18);
+
+ return y;
+ }
+
+ private:
void InitNext() noexcept;
void InitGenRand(ui32 s) noexcept;
void InitByArray(const ui32* init_key, size_t key_length) noexcept;
-
- private:
- ui32 mt[N];
- int mti;
- };
-}
+
+ private:
+ ui32 mt[N];
+ int mti;
+ };
+}
diff --git a/util/random/mersenne64.cpp b/util/random/mersenne64.cpp
index 9ebf24242f..4ede2c6dca 100644
--- a/util/random/mersenne64.cpp
+++ b/util/random/mersenne64.cpp
@@ -1,100 +1,100 @@
-#include "mersenne64.h"
-
-#include <util/generic/array_size.h>
-#include <util/stream/input.h>
-
-#define MM 156
-#define MATRIX_A ULL(0xB5026F5AA96619E9)
-#define UM ULL(0xFFFFFFFF80000000)
-#define LM ULL(0x7FFFFFFF)
-
-using namespace NPrivate;
-
+#include "mersenne64.h"
+
+#include <util/generic/array_size.h>
+#include <util/stream/input.h>
+
+#define MM 156
+#define MATRIX_A ULL(0xB5026F5AA96619E9)
+#define UM ULL(0xFFFFFFFF80000000)
+#define LM ULL(0x7FFFFFFF)
+
+using namespace NPrivate;
+
void TMersenne64::InitGenRand(ui64 seed) noexcept {
- mt[0] = seed;
-
- for (mti = 1; mti < NN; ++mti) {
- mt[mti] = (ULL(6364136223846793005) * (mt[mti - 1] ^ (mt[mti - 1] >> 62)) + mti);
- }
-}
-
+ mt[0] = seed;
+
+ for (mti = 1; mti < NN; ++mti) {
+ mt[mti] = (ULL(6364136223846793005) * (mt[mti - 1] ^ (mt[mti - 1] >> 62)) + mti);
+ }
+}
+
void TMersenne64::InitByArray(const ui64* init_key, size_t key_length) noexcept {
- ui64 i = 1;
- ui64 j = 0;
- ui64 k;
-
- InitGenRand(ULL(19650218));
-
- k = NN > key_length ? NN : key_length;
-
- for (; k; --k) {
- mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * ULL(3935559000370003845))) + init_key[j] + j;
-
- ++i;
- ++j;
-
- if (i >= NN) {
- mt[0] = mt[NN - 1];
- i = 1;
- }
-
- if (j >= key_length) {
- j = 0;
- }
- }
-
- for (k = NN - 1; k; --k) {
- mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * ULL(2862933555777941757))) - i;
-
- ++i;
-
- if (i >= NN) {
- mt[0] = mt[NN - 1];
- i = 1;
- }
- }
-
- mt[0] = ULL(1) << 63;
-}
-
+ ui64 i = 1;
+ ui64 j = 0;
+ ui64 k;
+
+ InitGenRand(ULL(19650218));
+
+ k = NN > key_length ? NN : key_length;
+
+ for (; k; --k) {
+ mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * ULL(3935559000370003845))) + init_key[j] + j;
+
+ ++i;
+ ++j;
+
+ if (i >= NN) {
+ mt[0] = mt[NN - 1];
+ i = 1;
+ }
+
+ if (j >= key_length) {
+ j = 0;
+ }
+ }
+
+ for (k = NN - 1; k; --k) {
+ mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * ULL(2862933555777941757))) - i;
+
+ ++i;
+
+ if (i >= NN) {
+ mt[0] = mt[NN - 1];
+ i = 1;
+ }
+ }
+
+ mt[0] = ULL(1) << 63;
+}
+
void TMersenne64::InitNext() noexcept {
- int i;
- ui64 x;
- ui64 mag01[2] = {
- ULL(0),
- MATRIX_A,
- };
-
- if (mti == NN + 1) {
- InitGenRand(ULL(5489));
- }
-
- for (i = 0; i < NN - MM; ++i) {
- x = (mt[i] & UM) | (mt[i + 1] & LM);
- mt[i] = mt[i + MM] ^ (x >> 1) ^ mag01[(int)(x & ULL(1))];
- }
-
- for (; i < NN - 1; ++i) {
- x = (mt[i] & UM) | (mt[i + 1] & LM);
- mt[i] = mt[i + (MM - NN)] ^ (x >> 1) ^ mag01[(int)(x & ULL(1))];
- }
-
- x = (mt[NN - 1] & UM) | (mt[0] & LM);
- mt[NN - 1] = mt[MM - 1] ^ (x >> 1) ^ mag01[(int)(x & ULL(1))];
-
- mti = 0;
-}
-
+ int i;
+ ui64 x;
+ ui64 mag01[2] = {
+ ULL(0),
+ MATRIX_A,
+ };
+
+ if (mti == NN + 1) {
+ InitGenRand(ULL(5489));
+ }
+
+ for (i = 0; i < NN - MM; ++i) {
+ x = (mt[i] & UM) | (mt[i + 1] & LM);
+ mt[i] = mt[i + MM] ^ (x >> 1) ^ mag01[(int)(x & ULL(1))];
+ }
+
+ for (; i < NN - 1; ++i) {
+ x = (mt[i] & UM) | (mt[i + 1] & LM);
+ mt[i] = mt[i + (MM - NN)] ^ (x >> 1) ^ mag01[(int)(x & ULL(1))];
+ }
+
+ x = (mt[NN - 1] & UM) | (mt[0] & LM);
+ mt[NN - 1] = mt[MM - 1] ^ (x >> 1) ^ mag01[(int)(x & ULL(1))];
+
+ mti = 0;
+}
+
TMersenne64::TMersenne64(IInputStream& input)
- : mti(NN + 1)
-{
- ui64 buf[128];
-
- input.LoadOrFail(buf, sizeof(buf));
+ : mti(NN + 1)
+{
+ ui64 buf[128];
+
+ input.LoadOrFail(buf, sizeof(buf));
InitByArray(buf, Y_ARRAY_SIZE(buf));
-}
-
-#undef MM
-#undef MATRIX_A
-#undef UM
-#undef LM
+}
+
+#undef MM
+#undef MATRIX_A
+#undef UM
+#undef LM
diff --git a/util/random/mersenne64.h b/util/random/mersenne64.h
index bb02b3c53b..12ca43b6af 100644
--- a/util/random/mersenne64.h
+++ b/util/random/mersenne64.h
@@ -1,50 +1,50 @@
#pragma once
-
-#include <util/system/defaults.h>
-
+
+#include <util/system/defaults.h>
+
class IInputStream;
-
-namespace NPrivate {
- class TMersenne64 {
+
+namespace NPrivate {
+ class TMersenne64 {
static constexpr int NN = 312;
-
- public:
- inline TMersenne64(ui64 s = ULL(19650218))
- : mti(NN + 1)
- {
- InitGenRand(s);
- }
-
+
+ public:
+ inline TMersenne64(ui64 s = ULL(19650218))
+ : mti(NN + 1)
+ {
+ InitGenRand(s);
+ }
+
inline TMersenne64(const ui64* keys, size_t len) noexcept
- : mti(NN + 1)
- {
- InitByArray(keys, len);
- }
-
+ : mti(NN + 1)
+ {
+ InitByArray(keys, len);
+ }
+
TMersenne64(IInputStream& input);
-
+
inline ui64 GenRand() noexcept {
- if (mti >= NN) {
- InitNext();
- }
-
- ui64 x = mt[mti++];
-
- x ^= (x >> 29) & ULL(0x5555555555555555);
- x ^= (x << 17) & ULL(0x71D67FFFEDA60000);
- x ^= (x << 37) & ULL(0xFFF7EEE000000000);
- x ^= (x >> 43);
-
- return x;
- }
-
- private:
+ if (mti >= NN) {
+ InitNext();
+ }
+
+ ui64 x = mt[mti++];
+
+ x ^= (x >> 29) & ULL(0x5555555555555555);
+ x ^= (x << 17) & ULL(0x71D67FFFEDA60000);
+ x ^= (x << 37) & ULL(0xFFF7EEE000000000);
+ x ^= (x >> 43);
+
+ return x;
+ }
+
+ private:
void InitNext() noexcept;
void InitGenRand(ui64 seed) noexcept;
void InitByArray(const ui64* init_key, size_t key_length) noexcept;
-
- private:
- ui64 mt[NN];
- int mti;
- };
-}
+
+ private:
+ ui64 mt[NN];
+ int mti;
+ };
+}
diff --git a/util/random/mersenne_ut.cpp b/util/random/mersenne_ut.cpp
index 3f48d18831..a4b84efa3d 100644
--- a/util/random/mersenne_ut.cpp
+++ b/util/random/mersenne_ut.cpp
@@ -1,82 +1,82 @@
-#include "mersenne.h"
-
+#include "mersenne.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <util/stream/output.h>
-
-#define UI32(x) x##ul
-
+
+#define UI32(x) x##ul
+
Y_UNIT_TEST_SUITE(TMersenneRndTest) {
- template <class T>
- inline void Test(const T* res, size_t len) {
- TMersenne<T> m;
-
- for (size_t i = 0; i < len; ++i) {
- UNIT_ASSERT_EQUAL(m.GenRand(), res[i]);
- }
- }
-
+ template <class T>
+ inline void Test(const T* res, size_t len) {
+ TMersenne<T> m;
+
+ for (size_t i = 0; i < len; ++i) {
+ UNIT_ASSERT_EQUAL(m.GenRand(), res[i]);
+ }
+ }
+
Y_UNIT_TEST(Test32) {
- const ui32 res[] = {
- UI32(2325592414),
- UI32(482149846),
- UI32(4177211283),
- UI32(3872387439),
- UI32(1663027210),
- UI32(2005191859),
- UI32(666881213),
- UI32(3289399202),
- UI32(2514534568),
- UI32(3882134983),
- };
-
+ const ui32 res[] = {
+ UI32(2325592414),
+ UI32(482149846),
+ UI32(4177211283),
+ UI32(3872387439),
+ UI32(1663027210),
+ UI32(2005191859),
+ UI32(666881213),
+ UI32(3289399202),
+ UI32(2514534568),
+ UI32(3882134983),
+ };
+
Test<ui32>(res, Y_ARRAY_SIZE(res));
- }
-
+ }
+
Y_UNIT_TEST(Test64) {
- const ui64 res[] = {
- ULL(13735441942630277712),
- ULL(10468394322237346228),
- ULL(5051557175812687784),
- ULL(8252857936377966838),
- ULL(4330799099585512958),
- ULL(327094098846779408),
- ULL(6143667654738189122),
- ULL(6387112078486713335),
- ULL(3862502196831460488),
- ULL(11231499428520958715),
- };
-
+ const ui64 res[] = {
+ ULL(13735441942630277712),
+ ULL(10468394322237346228),
+ ULL(5051557175812687784),
+ ULL(8252857936377966838),
+ ULL(4330799099585512958),
+ ULL(327094098846779408),
+ ULL(6143667654738189122),
+ ULL(6387112078486713335),
+ ULL(3862502196831460488),
+ ULL(11231499428520958715),
+ };
+
Test<ui64>(res, Y_ARRAY_SIZE(res));
- }
-
+ }
+
Y_UNIT_TEST(TestGenRand64) {
- TMersenne<ui32> rng;
-
- for (size_t i = 0; i < 100; ++i) {
- UNIT_ASSERT(rng.GenRand64() > ULL(12345678912));
- }
- }
-
+ TMersenne<ui32> rng;
+
+ for (size_t i = 0; i < 100; ++i) {
+ UNIT_ASSERT(rng.GenRand64() > ULL(12345678912));
+ }
+ }
+
Y_UNIT_TEST(TestCopy32) {
- TMersenne<ui32> r1(1);
- TMersenne<ui32> r2(2);
-
- UNIT_ASSERT_VALUES_UNEQUAL(r1.GenRand(), r2.GenRand());
-
- r2 = r1;
-
- UNIT_ASSERT_VALUES_EQUAL(r1.GenRand(), r2.GenRand());
- }
-
+ TMersenne<ui32> r1(1);
+ TMersenne<ui32> r2(2);
+
+ UNIT_ASSERT_VALUES_UNEQUAL(r1.GenRand(), r2.GenRand());
+
+ r2 = r1;
+
+ UNIT_ASSERT_VALUES_EQUAL(r1.GenRand(), r2.GenRand());
+ }
+
Y_UNIT_TEST(TestCopy64) {
- TMersenne<ui64> r1(1);
- TMersenne<ui64> r2(2);
-
- UNIT_ASSERT_VALUES_UNEQUAL(r1.GenRand(), r2.GenRand());
-
- r2 = r1;
-
- UNIT_ASSERT_VALUES_EQUAL(r1.GenRand(), r2.GenRand());
- }
-}
+ TMersenne<ui64> r1(1);
+ TMersenne<ui64> r2(2);
+
+ UNIT_ASSERT_VALUES_UNEQUAL(r1.GenRand(), r2.GenRand());
+
+ r2 = r1;
+
+ UNIT_ASSERT_VALUES_EQUAL(r1.GenRand(), r2.GenRand());
+ }
+}
diff --git a/util/random/normal.cpp b/util/random/normal.cpp
index 8ef56c6a34..478b38fd25 100644
--- a/util/random/normal.cpp
+++ b/util/random/normal.cpp
@@ -1,27 +1,27 @@
-#include "normal.h"
-#include "common_ops.h"
-#include "random.h"
-
-namespace {
- template <class T>
- struct TSysRNG: public TCommonRNG<T, TSysRNG<T>> {
- inline T GenRand() noexcept {
- return RandomNumber<T>();
- }
- };
-}
-
-template <>
-float StdNormalRandom<float>() noexcept {
- return StdNormalDistribution<float>(TSysRNG<ui64>());
-}
-
-template <>
-double StdNormalRandom<double>() noexcept {
- return StdNormalDistribution<double>(TSysRNG<ui64>());
-}
-
-template <>
-long double StdNormalRandom<long double>() noexcept {
- return StdNormalDistribution<long double>(TSysRNG<ui64>());
-}
+#include "normal.h"
+#include "common_ops.h"
+#include "random.h"
+
+namespace {
+ template <class T>
+ struct TSysRNG: public TCommonRNG<T, TSysRNG<T>> {
+ inline T GenRand() noexcept {
+ return RandomNumber<T>();
+ }
+ };
+}
+
+template <>
+float StdNormalRandom<float>() noexcept {
+ return StdNormalDistribution<float>(TSysRNG<ui64>());
+}
+
+template <>
+double StdNormalRandom<double>() noexcept {
+ return StdNormalDistribution<double>(TSysRNG<ui64>());
+}
+
+template <>
+long double StdNormalRandom<long double>() noexcept {
+ return StdNormalDistribution<long double>(TSysRNG<ui64>());
+}
diff --git a/util/random/normal.h b/util/random/normal.h
index 4b6d0e3b8e..1ed132b532 100644
--- a/util/random/normal.h
+++ b/util/random/normal.h
@@ -1,38 +1,38 @@
-#pragma once
-
-#include <cmath>
-
-// sometimes we need stateless normal distribution...
-
-/*
- * normal distribution with Box-Muller transform
- * http://www.design.caltech.edu/erik/Misc/Gaussian.html
- */
-template <typename T, typename TRng>
-static inline T StdNormalDistribution(TRng&& rng) noexcept {
- T x;
- T y;
- T r;
-
- do {
- x = (T)rng.GenRandReal1() * T(2) - T(1);
- y = (T)rng.GenRandReal1() * T(2) - T(1);
- r = x * x + y * y;
- } while (r > T(1) || r <= T(0));
-
- return x * std::sqrt(-T(2) * std::log(r) / r);
-}
-
-template <typename T, typename TRng>
-static inline T NormalDistribution(TRng&& rng, T m, T d) noexcept {
- return StdNormalDistribution<T>(rng) * d + m;
-}
-
-// specialized for float, double, long double
-template <class T>
-T StdNormalRandom() noexcept;
-
-template <class T>
-static inline T NormalRandom(T m, T d) noexcept {
- return StdNormalRandom<T>() * d + m;
-}
+#pragma once
+
+#include <cmath>
+
+// sometimes we need stateless normal distribution...
+
+/*
+ * normal distribution with Box-Muller transform
+ * http://www.design.caltech.edu/erik/Misc/Gaussian.html
+ */
+template <typename T, typename TRng>
+static inline T StdNormalDistribution(TRng&& rng) noexcept {
+ T x;
+ T y;
+ T r;
+
+ do {
+ x = (T)rng.GenRandReal1() * T(2) - T(1);
+ y = (T)rng.GenRandReal1() * T(2) - T(1);
+ r = x * x + y * y;
+ } while (r > T(1) || r <= T(0));
+
+ return x * std::sqrt(-T(2) * std::log(r) / r);
+}
+
+template <typename T, typename TRng>
+static inline T NormalDistribution(TRng&& rng, T m, T d) noexcept {
+ return StdNormalDistribution<T>(rng) * d + m;
+}
+
+// specialized for float, double, long double
+template <class T>
+T StdNormalRandom() noexcept;
+
+template <class T>
+static inline T NormalRandom(T m, T d) noexcept {
+ return StdNormalRandom<T>() * d + m;
+}
diff --git a/util/random/normal_ut.cpp b/util/random/normal_ut.cpp
index c65f59d038..42b6cc4ba2 100644
--- a/util/random/normal_ut.cpp
+++ b/util/random/normal_ut.cpp
@@ -1,81 +1,81 @@
-#include "normal.h"
-#include "fast.h"
-
+#include "normal.h"
+#include "fast.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/generic/vector.h>
-
-#include <functional>
-
+
+#include <util/generic/vector.h>
+
+#include <functional>
+
Y_UNIT_TEST_SUITE(TestNormalDistribution) {
Y_UNIT_TEST(TestDefined) {
- volatile auto x = NormalRandom<float>(0, 1) + NormalRandom<double>(0, 1) + NormalRandom<long double>(0, 1);
-
- (void)x;
- }
-
- template <class T>
- static void TestMD(std::function<T()> f, T m, T d) {
+ volatile auto x = NormalRandom<float>(0, 1) + NormalRandom<double>(0, 1) + NormalRandom<long double>(0, 1);
+
+ (void)x;
+ }
+
+ template <class T>
+ static void TestMD(std::function<T()> f, T m, T d) {
TVector<T> v;
-
- v.reserve(20000);
-
- for (size_t i = 0; i < 20000; ++i) {
- v.push_back(f());
- }
-
- long double mm = 0;
- long double vv = 0;
-
- for (auto x : v) {
- mm += x;
- }
-
+
+ v.reserve(20000);
+
+ for (size_t i = 0; i < 20000; ++i) {
+ v.push_back(f());
+ }
+
+ long double mm = 0;
+ long double vv = 0;
+
+ for (auto x : v) {
+ mm += x;
+ }
+
mm /= v.size();
-
- for (auto x : v) {
- vv += (mm - x) * (mm - x);
- }
-
+
+ for (auto x : v) {
+ vv += (mm - x) * (mm - x);
+ }
+
vv /= v.size();
-
- long double dd = std::sqrt(vv);
-
- UNIT_ASSERT_DOUBLES_EQUAL(m, mm, (m + 1) * 0.05);
- UNIT_ASSERT_DOUBLES_EQUAL(d, dd, (d + 1) * 0.05);
- }
-
+
+ long double dd = std::sqrt(vv);
+
+ UNIT_ASSERT_DOUBLES_EQUAL(m, mm, (m + 1) * 0.05);
+ UNIT_ASSERT_DOUBLES_EQUAL(d, dd, (d + 1) * 0.05);
+ }
+
Y_UNIT_TEST(Test1) {
- TestMD<float>(&StdNormalRandom<float>, 0, 1);
- TestMD<double>(&StdNormalRandom<double>, 0, 1);
- TestMD<long double>(&StdNormalRandom<long double>, 0, 1);
- }
-
- template <class T>
- std::function<T()> GenFunc1(T m, T d) {
- return [m, d]() {
- return NormalRandom<T>(m, d);
- };
- }
-
- template <class T>
- std::function<T()> GenFunc2(T m, T d) {
- TFastRng<ui64> rng(17);
-
- return [rng, m, d]() mutable {
- return NormalDistribution<T>(rng, m, d);
- };
- }
-
+ TestMD<float>(&StdNormalRandom<float>, 0, 1);
+ TestMD<double>(&StdNormalRandom<double>, 0, 1);
+ TestMD<long double>(&StdNormalRandom<long double>, 0, 1);
+ }
+
+ template <class T>
+ std::function<T()> GenFunc1(T m, T d) {
+ return [m, d]() {
+ return NormalRandom<T>(m, d);
+ };
+ }
+
+ template <class T>
+ std::function<T()> GenFunc2(T m, T d) {
+ TFastRng<ui64> rng(17);
+
+ return [rng, m, d]() mutable {
+ return NormalDistribution<T>(rng, m, d);
+ };
+ }
+
Y_UNIT_TEST(Test2) {
- TestMD<float>(GenFunc1<float>(2, 3), 2, 3);
- TestMD<double>(GenFunc1<double>(3, 4), 3, 4);
- TestMD<long double>(GenFunc1<long double>(4, 5), 4, 5);
- }
-
+ TestMD<float>(GenFunc1<float>(2, 3), 2, 3);
+ TestMD<double>(GenFunc1<double>(3, 4), 3, 4);
+ TestMD<long double>(GenFunc1<long double>(4, 5), 4, 5);
+ }
+
Y_UNIT_TEST(Test3) {
- TestMD<float>(GenFunc2<float>(20, 30), 20, 30);
- TestMD<double>(GenFunc2<double>(30, 40), 30, 40);
- TestMD<long double>(GenFunc2<long double>(40, 50), 40, 50);
- }
-}
+ TestMD<float>(GenFunc2<float>(20, 30), 20, 30);
+ TestMD<double>(GenFunc2<double>(30, 40), 30, 40);
+ TestMD<long double>(GenFunc2<long double>(40, 50), 40, 50);
+ }
+}
diff --git a/util/random/random.cpp b/util/random/random.cpp
index 561f8aa412..71f9323856 100644
--- a/util/random/random.cpp
+++ b/util/random/random.cpp
@@ -1,118 +1,118 @@
-#include "random.h"
-#include "entropy.h"
-#include "mersenne.h"
-
-#include <util/system/getpid.h>
-#include <util/thread/singleton.h>
-#include <util/stream/multi.h>
-#include <util/stream/mem.h>
-#include <util/digest/numeric.h>
-
-namespace {
- struct TProcStream {
- ui32 Extra;
- TMemoryInput MI;
- TMultiInput TI;
-
- static inline ui32 ExtraData() noexcept {
- ui32 data;
-
- EntropyPool().LoadOrFail(&data, sizeof(data));
-
- return IntHash(data ^ GetPID());
- }
-
- inline TProcStream() noexcept
- : Extra(ExtraData())
- , MI(&Extra, sizeof(Extra))
- , TI(&MI, &EntropyPool())
- {
- }
-
- inline IInputStream& S() noexcept {
- return TI;
- }
- };
-
- template <class T>
- struct TRndGen: public TMersenne<T> {
- inline TRndGen()
- : TMersenne<T>(TProcStream().S())
- {
- }
+#include "random.h"
+#include "entropy.h"
+#include "mersenne.h"
+
+#include <util/system/getpid.h>
+#include <util/thread/singleton.h>
+#include <util/stream/multi.h>
+#include <util/stream/mem.h>
+#include <util/digest/numeric.h>
+
+namespace {
+ struct TProcStream {
+ ui32 Extra;
+ TMemoryInput MI;
+ TMultiInput TI;
+
+ static inline ui32 ExtraData() noexcept {
+ ui32 data;
+
+ EntropyPool().LoadOrFail(&data, sizeof(data));
+
+ return IntHash(data ^ GetPID());
+ }
+
+ inline TProcStream() noexcept
+ : Extra(ExtraData())
+ , MI(&Extra, sizeof(Extra))
+ , TI(&MI, &EntropyPool())
+ {
+ }
+
+ inline IInputStream& S() noexcept {
+ return TI;
+ }
+ };
+
+ template <class T>
+ struct TRndGen: public TMersenne<T> {
+ inline TRndGen()
+ : TMersenne<T>(TProcStream().S())
+ {
+ }
inline TRndGen(T seed)
: TMersenne<T>(seed)
{
}
- };
-
- template <class T>
- static inline TRndGen<T>* GetRndGen() {
+ };
+
+ template <class T>
+ static inline TRndGen<T>* GetRndGen() {
return FastTlsSingletonWithPriority<TRndGen<T>, 2>();
- }
-
- template <unsigned N>
- struct TToRealTypeBySize {
+ }
+
+ template <unsigned N>
+ struct TToRealTypeBySize {
using TResult = ui32;
- };
-
- template <>
- struct TToRealTypeBySize<8> {
+ };
+
+ template <>
+ struct TToRealTypeBySize<8> {
using TResult = ui64;
- };
-
- template <class T>
- struct TToRealType {
+ };
+
+ template <class T>
+ struct TToRealType {
using TResult = typename TToRealTypeBySize<sizeof(T)>::TResult;
- };
-}
-
-#define DEF_RND(TY) \
- template <> \
- TY RandomNumber<TY>() { \
- return GetRndGen<TToRealType<TY>::TResult>()->GenRand(); \
- } \
- \
- template <> \
- TY RandomNumber<TY>(TY n) { \
- return GetRndGen<TToRealType<TY>::TResult>()->Uniform(n); \
- }
-
+ };
+}
+
+#define DEF_RND(TY) \
+ template <> \
+ TY RandomNumber<TY>() { \
+ return GetRndGen<TToRealType<TY>::TResult>()->GenRand(); \
+ } \
+ \
+ template <> \
+ TY RandomNumber<TY>(TY n) { \
+ return GetRndGen<TToRealType<TY>::TResult>()->Uniform(n); \
+ }
+
DEF_RND(char)
-DEF_RND(unsigned char)
-DEF_RND(unsigned int)
-DEF_RND(unsigned long)
-DEF_RND(unsigned short)
-DEF_RND(unsigned long long)
-
+DEF_RND(unsigned char)
+DEF_RND(unsigned int)
+DEF_RND(unsigned long)
+DEF_RND(unsigned short)
+DEF_RND(unsigned long long)
+
#undef DEF_RND
-template <>
+template <>
bool RandomNumber<bool>() {
return RandomNumber<ui8>() % 2 == 0;
}
template <>
-float RandomNumber<float>() {
- float ret;
-
- do {
- ret = (float)GetRndGen<ui64>()->GenRandReal2();
+float RandomNumber<float>() {
+ float ret;
+
+ do {
+ ret = (float)GetRndGen<ui64>()->GenRandReal2();
} while (ret >= 1);
-
- return ret;
-}
-
-template <>
-double RandomNumber<double>() {
- return GetRndGen<ui64>()->GenRandReal4();
-}
-
-template <>
-long double RandomNumber<long double>() {
- return RandomNumber<double>();
-}
+
+ return ret;
+}
+
+template <>
+double RandomNumber<double>() {
+ return GetRndGen<ui64>()->GenRandReal4();
+}
+
+template <>
+long double RandomNumber<long double>() {
+ return RandomNumber<double>();
+}
void ResetRandomState() {
*GetRndGen<ui32>() = TRndGen<ui32>();
diff --git a/util/random/random.h b/util/random/random.h
index d5c99de95b..16b52d3995 100644
--- a/util/random/random.h
+++ b/util/random/random.h
@@ -1,18 +1,18 @@
#pragma once
-
-/*
- * thread-safe random number generator.
- *
- * specialized for:
- * all unsigned types (return value in range [0, MAX_VALUE_FOR_TYPE])
+
+/*
+ * thread-safe random number generator.
+ *
+ * specialized for:
+ * all unsigned types (return value in range [0, MAX_VALUE_FOR_TYPE])
* bool
- * long double (return value in range [0, 1))
- * double (return value in range [0, 1))
- * float (return value in range [0, 1))
- */
-template <class T>
-T RandomNumber();
-
+ * long double (return value in range [0, 1))
+ * double (return value in range [0, 1))
+ * float (return value in range [0, 1))
+ */
+template <class T>
+T RandomNumber();
+
/*
* returns value in range [0, max)
*/
diff --git a/util/random/random_ut.cpp b/util/random/random_ut.cpp
index 20db587463..30427676f3 100644
--- a/util/random/random_ut.cpp
+++ b/util/random/random_ut.cpp
@@ -1,15 +1,15 @@
-#include "random.h"
-
+#include "random.h"
+
#include <library/cpp/testing/unittest/registar.h>
#include <util/generic/ylimits.h>
-template <class T>
-static inline void AssertRange(T v, T r1, T r2) {
- UNIT_ASSERT(v >= r1);
- UNIT_ASSERT(v < r2);
-}
-
+template <class T>
+static inline void AssertRange(T v, T r1, T r2) {
+ UNIT_ASSERT(v >= r1);
+ UNIT_ASSERT(v < r2);
+}
+
Y_UNIT_TEST_SUITE(TRandomNumberTest) {
template <typename T>
void TestAll(T n) {
@@ -55,24 +55,24 @@ Y_UNIT_TEST_SUITE(TRandomNumberTest) {
TestType<unsigned long>();
TestType<unsigned long long>();
}
-
+
Y_UNIT_TEST(TestRandomNumberFloat) {
- for (size_t i = 0; i < 1000; ++i) {
- AssertRange<float>(RandomNumber<float>(), 0.0, 1.0);
- }
- }
-
+ for (size_t i = 0; i < 1000; ++i) {
+ AssertRange<float>(RandomNumber<float>(), 0.0, 1.0);
+ }
+ }
+
Y_UNIT_TEST(TestRandomNumberDouble) {
- for (size_t i = 0; i < 1000; ++i) {
- AssertRange<double>(RandomNumber<double>(), 0.0, 1.0);
- }
- }
-
+ for (size_t i = 0; i < 1000; ++i) {
+ AssertRange<double>(RandomNumber<double>(), 0.0, 1.0);
+ }
+ }
+
Y_UNIT_TEST(TestRandomNumberLongDouble) {
- for (size_t i = 0; i < 1000; ++i) {
- AssertRange<long double>(RandomNumber<long double>(), 0.0, 1.0);
- }
- }
+ for (size_t i = 0; i < 1000; ++i) {
+ AssertRange<long double>(RandomNumber<long double>(), 0.0, 1.0);
+ }
+ }
Y_UNIT_TEST(TestBoolean) {
while (RandomNumber<bool>()) {
@@ -84,71 +84,71 @@ Y_UNIT_TEST_SUITE(TRandomNumberTest) {
Y_UNIT_TEST(TestResetSeed) {
SetRandomSeed(42);
for (const ui32 el : {
- 102,
- 179,
- 92,
- 14,
- 106,
- 71,
- 188,
- 20,
- 102,
- 121,
- 210,
- 214,
- 74,
- 202,
- 87,
- 116,
- 99,
- 103,
- 151,
- 130,
- 149,
- 52,
- 1,
- 87,
- 235,
- 157,
- 37,
- 129,
- 191,
- 187,
- 20,
- 160,
- 203,
- 57,
- 21,
- 252,
- 235,
- 88,
- 48,
- 218,
- 58,
- 254,
- 169,
- 255,
- 219,
- 187,
- 207,
- 14,
- 189,
- 189,
- 174,
- 189,
- 50,
- 107,
- 54,
- 243,
- 63,
- 248,
- 130,
- 228,
- 50,
- 134,
- 20,
- 72,
- }) {
+ 102,
+ 179,
+ 92,
+ 14,
+ 106,
+ 71,
+ 188,
+ 20,
+ 102,
+ 121,
+ 210,
+ 214,
+ 74,
+ 202,
+ 87,
+ 116,
+ 99,
+ 103,
+ 151,
+ 130,
+ 149,
+ 52,
+ 1,
+ 87,
+ 235,
+ 157,
+ 37,
+ 129,
+ 191,
+ 187,
+ 20,
+ 160,
+ 203,
+ 57,
+ 21,
+ 252,
+ 235,
+ 88,
+ 48,
+ 218,
+ 58,
+ 254,
+ 169,
+ 255,
+ 219,
+ 187,
+ 207,
+ 14,
+ 189,
+ 189,
+ 174,
+ 189,
+ 50,
+ 107,
+ 54,
+ 243,
+ 63,
+ 248,
+ 130,
+ 228,
+ 50,
+ 134,
+ 20,
+ 72,
+ }) {
UNIT_ASSERT_EQUAL(RandomNumber<ui32>(1 << 8), el);
}
}
diff --git a/util/random/shuffle.cpp b/util/random/shuffle.cpp
index 1c2ef02f45..fa35320973 100644
--- a/util/random/shuffle.cpp
+++ b/util/random/shuffle.cpp
@@ -1 +1 @@
-#include "shuffle.h"
+#include "shuffle.h"
diff --git a/util/random/shuffle.h b/util/random/shuffle.h
index 579f3073ee..274ac147c9 100644
--- a/util/random/shuffle.h
+++ b/util/random/shuffle.h
@@ -1,43 +1,43 @@
#pragma once
-#include "fast.h"
-#include "entropy.h"
-
+#include "fast.h"
+#include "entropy.h"
+
#include <util/generic/utility.h>
-
-// some kind of https://en.wikipedia.org/wiki/Fisher–Yates_shuffle#The_modern_algorithm
-
-template <typename TRandIter, typename TRandIterEnd>
+
+// some kind of https://en.wikipedia.org/wiki/Fisher–Yates_shuffle#The_modern_algorithm
+
+template <typename TRandIter, typename TRandIterEnd>
inline void Shuffle(TRandIter begin, TRandIterEnd end) {
- static_assert(sizeof(end - begin) <= sizeof(size_t), "fixme");
- static_assert(sizeof(TReallyFastRng32::RandMax()) <= sizeof(size_t), "fixme");
-
- if ((size_t)(end - begin) < (size_t)TReallyFastRng32::RandMax()) {
- Shuffle(begin, end, TReallyFastRng32(Seed()));
- } else {
- Shuffle(begin, end, TFastRng64(Seed()));
+ static_assert(sizeof(end - begin) <= sizeof(size_t), "fixme");
+ static_assert(sizeof(TReallyFastRng32::RandMax()) <= sizeof(size_t), "fixme");
+
+ if ((size_t)(end - begin) < (size_t)TReallyFastRng32::RandMax()) {
+ Shuffle(begin, end, TReallyFastRng32(Seed()));
+ } else {
+ Shuffle(begin, end, TFastRng64(Seed()));
}
}
template <typename TRandIter, typename TRandIterEnd, typename TRandGen>
-inline void Shuffle(TRandIter begin, TRandIterEnd end, TRandGen&& gen) {
+inline void Shuffle(TRandIter begin, TRandIterEnd end, TRandGen&& gen) {
const size_t sz = end - begin;
for (size_t i = 1; i < sz; ++i) {
- DoSwap(*(begin + i), *(begin + gen.Uniform(i + 1)));
+ DoSwap(*(begin + i), *(begin + gen.Uniform(i + 1)));
}
}
template <typename TRange>
inline void ShuffleRange(TRange& range) {
- auto b = range.begin();
-
- Shuffle(b, range.end());
+ auto b = range.begin();
+
+ Shuffle(b, range.end());
}
template <typename TRange, typename TRandGen>
inline void ShuffleRange(TRange& range, TRandGen&& gen) {
- auto b = range.begin();
-
- Shuffle(b, range.end(), gen);
+ auto b = range.begin();
+
+ Shuffle(b, range.end(), gen);
}
diff --git a/util/random/shuffle_ut.cpp b/util/random/shuffle_ut.cpp
index 9b3ba18859..87cbae94c0 100644
--- a/util/random/shuffle_ut.cpp
+++ b/util/random/shuffle_ut.cpp
@@ -1,75 +1,75 @@
-#include "fast.h"
-#include "shuffle.h"
+#include "fast.h"
+#include "shuffle.h"
#include "mersenne.h"
-
+
#include <library/cpp/testing/unittest/registar.h>
#include <util/generic/ylimits.h>
Y_UNIT_TEST_SUITE(TRandUtilsTest) {
- template <typename... A>
- static void TestRange(A&&... args) {
+ template <typename... A>
+ static void TestRange(A&&... args) {
TString s0, s1;
- ShuffleRange(s1, args...);
+ ShuffleRange(s1, args...);
s1 = "0";
- ShuffleRange(s1, args...);
+ ShuffleRange(s1, args...);
s1 = "01";
- ShuffleRange(s1, args...);
+ ShuffleRange(s1, args...);
s1 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
s0 = s1.copy();
- ShuffleRange(s1, args...);
+ ShuffleRange(s1, args...);
UNIT_ASSERT(s0 != s1); // if shuffle does work, chances it will fail are 1 to 64!.
}
-
- template <typename... A>
- static void TestIter(A&&... args) {
+
+ template <typename... A>
+ static void TestIter(A&&... args) {
TString s0, s1;
-
- auto f = [&]() {
- auto b = s1.begin();
- auto e = s1.end();
-
- Shuffle(b, e, args...);
- };
-
+
+ auto f = [&]() {
+ auto b = s1.begin();
+ auto e = s1.end();
+
+ Shuffle(b, e, args...);
+ };
+
s1 = "0";
- f();
-
+ f();
+
s1 = "01";
- f();
-
+ f();
+
s1 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
s0 = s1.copy();
- f();
-
+ f();
+
UNIT_ASSERT(s0 != s1); // if shuffle does work, chances it will fail are 1 to 64!.
}
-
- Y_UNIT_TEST(TestShuffle) {
- TestRange();
- }
-
- Y_UNIT_TEST(TestShuffleMersenne64) {
- TMersenne<ui64> prng(42);
-
- TestRange(prng);
- }
-
+
+ Y_UNIT_TEST(TestShuffle) {
+ TestRange();
+ }
+
+ Y_UNIT_TEST(TestShuffleMersenne64) {
+ TMersenne<ui64> prng(42);
+
+ TestRange(prng);
+ }
+
Y_UNIT_TEST(TestShuffleMersenne32) {
TMersenne<ui32> prng(24);
-
- TestIter(prng);
+
+ TestIter(prng);
}
-
+
Y_UNIT_TEST(TestShuffleFast32) {
- TFastRng32 prng(24, 0);
-
- TestIter(prng);
- }
-
+ TFastRng32 prng(24, 0);
+
+ TestIter(prng);
+ }
+
Y_UNIT_TEST(TestShuffleFast64) {
- TFastRng64 prng(24, 0, 25, 1);
-
- TestIter(prng);
- }
+ TFastRng64 prng(24, 0, 25, 1);
+
+ TestIter(prng);
+ }
}
diff --git a/util/random/ut/ya.make b/util/random/ut/ya.make
index d18236d6c4..5080b339de 100644
--- a/util/random/ut/ya.make
+++ b/util/random/ut/ya.make
@@ -1,17 +1,17 @@
-UNITTEST_FOR(util)
+UNITTEST_FOR(util)
OWNER(g:util)
SUBSCRIBER(g:util-subscribers)
SRCS(
- random/common_ops_ut.cpp
- random/easy_ut.cpp
- random/entropy_ut.cpp
- random/fast_ut.cpp
- random/normal_ut.cpp
- random/mersenne_ut.cpp
- random/random_ut.cpp
- random/shuffle_ut.cpp
+ random/common_ops_ut.cpp
+ random/easy_ut.cpp
+ random/entropy_ut.cpp
+ random/fast_ut.cpp
+ random/normal_ut.cpp
+ random/mersenne_ut.cpp
+ random/random_ut.cpp
+ random/shuffle_ut.cpp
)
INCLUDE(${ARCADIA_ROOT}/util/tests/ya_util_tests.inc)