Skip to content

Commit a304fdd

Browse files
committed
merge from legacy branch
2 parents db0b8fa + e19a93e commit a304fdd

File tree

5 files changed

+105
-35
lines changed

5 files changed

+105
-35
lines changed

.mci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ cxx_driver_variables:
133133
## msvc2010
134134
msvc2010: &with_msvc2010
135135
toolchain_flags: --msvc-version=10.0
136-
libpath: --libpath="c:\local\boost_1_55_0\lib64-msvc-10.0"
137-
cpppath: --cpppath="c:\local\boost_1_55_0"
136+
libpath: --libpath="c:\local\boost_1_57_0\lib64-msvc-10.0"
137+
cpppath: --cpppath="c:\local\boost_1_57_0"
138138
dllpath: --runtime-library-search-path="c:\local\boost_1_55_0\lib64-msvc-10.0,c:\openssl\bin,c:\sasl\bin,c:\curl\dlls"
139139
extrapath: --extrapath="c:\openssl,c:\sasl,c:\curl"
140140
## msvc2013, 32-bit boost headers
@@ -635,7 +635,7 @@ buildvariants:
635635
<<: *with_msvc2010_32bit
636636
compile_target: driver build-unit
637637
run_on:
638-
- windows-64-compile
638+
- windows-64-vs2010-compile
639639
tasks:
640640
- name: "compile"
641641
- name: "unit-test"
@@ -652,7 +652,7 @@ buildvariants:
652652
<<: *mongo_url_windows64
653653
<<: *with_msvc2010
654654
run_on:
655-
- windows-64-compile
655+
- windows-64-vs2010-compile
656656
tasks: *latest_tests
657657

658658
## Windows 64-bit DEBUG DYNAMIC (msvc2010)
@@ -668,7 +668,7 @@ buildvariants:
668668
<<: *mongo_url_windows64
669669
<<: *with_msvc2010
670670
run_on:
671-
- windows-64-compile
671+
- windows-64-vs2010-compile
672672
tasks: *latest_tests
673673

674674
## Windows 64-bit DYNAMIC (msvc2013)

SConstruct

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,8 @@ if has_option('runtime-library-search-path'):
562562
for lib in libs:
563563
env.AppendENVPath(envVar, env.Dir(lib), delete_existing=0)
564564

565-
if has_option('build-fast-and-loose'):
565+
# Ignore fast-and-loose option if the scons cache is enabled (see SERVER-19088)
566+
if has_option('build-fast-and-loose') and not has_option('cache'):
566567
# See http://www.scons.org/wiki/GoFastButton for details
567568
env.Decider('MD5-timestamp')
568569
env.SetOption('max_drift', 1)

src/mongo/platform/random.cpp

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,49 +35,46 @@ namespace mongo {
3535

3636
// ---- PseudoRandom -----
3737

38-
int32_t PseudoRandom::nextInt32() {
39-
int32_t t = _x ^ (_x << 11);
38+
uint32_t PseudoRandom::nextUInt32() {
39+
uint32_t t = _x ^ (_x << 11);
4040
_x = _y;
4141
_y = _z;
4242
_z = _w;
4343
return _w = _w ^ (_w >> 19) ^ (t ^ (t >> 8));
4444
}
4545

4646
namespace {
47-
const int32_t default_y = 362436069;
48-
const int32_t default_z = 521288629;
49-
const int32_t default_w = 88675123;
50-
}
47+
const uint32_t default_y = 362436069;
48+
const uint32_t default_z = 521288629;
49+
const uint32_t default_w = 88675123;
50+
} // namespace
5151

52-
PseudoRandom::PseudoRandom(int32_t seed) {
52+
void PseudoRandom::_init(uint32_t seed) {
5353
_x = seed;
5454
_y = default_y;
5555
_z = default_z;
5656
_w = default_w;
5757
}
5858

59-
6059
PseudoRandom::PseudoRandom(uint32_t seed) {
61-
_x = static_cast<int32_t>(seed);
62-
_y = default_y;
63-
_z = default_z;
64-
_w = default_w;
60+
_init(seed);
6561
}
6662

63+
PseudoRandom::PseudoRandom(int32_t seed) {
64+
_init(static_cast<uint32_t>(seed));
65+
}
6766

6867
PseudoRandom::PseudoRandom(int64_t seed) {
69-
int32_t high = seed >> 32;
70-
int32_t low = seed & 0xFFFFFFFF;
68+
_init(static_cast<uint32_t>(seed >> 32) ^ static_cast<uint32_t>(seed));
69+
}
7170

72-
_x = high ^ low;
73-
_y = default_y;
74-
_z = default_z;
75-
_w = default_w;
71+
int32_t PseudoRandom::nextInt32() {
72+
return nextUInt32();
7673
}
7774

7875
int64_t PseudoRandom::nextInt64() {
79-
int64_t a = nextInt32();
80-
int64_t b = nextInt32();
76+
uint64_t a = nextUInt32();
77+
uint64_t b = nextUInt32();
8178
return (a << 32) | b;
8279
}
8380

@@ -157,4 +154,4 @@ SecureRandom* SecureRandom::create() {
157154
#error Must implement SecureRandom for platform
158155

159156
#endif
160-
}
157+
} // namespace mongo

src/mongo/platform/random.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,20 @@ class PseudoRandom {
4040
* @return a number between 0 and max
4141
*/
4242
int32_t nextInt32(int32_t max) {
43-
return nextInt32() % max;
43+
return static_cast<uint32_t>(nextInt32()) % static_cast<uint32_t>(max);
4444
}
4545

4646
/**
4747
* @return a number between 0 and max
4848
*/
4949
int64_t nextInt64(int64_t max) {
50-
return nextInt64() % max;
50+
return static_cast<uint64_t>(nextInt64()) % static_cast<uint64_t>(max);
5151
}
5252

5353
/**
5454
* @return a number between 0 and max
5555
*
56-
* This makes PsuedoRandom instances passable as the third argument to std::random_shuffle
56+
* This makes PseudoRandom instances passable as the third argument to std::random_shuffle
5757
*/
5858
intptr_t operator()(intptr_t max) {
5959
if (sizeof(intptr_t) == 4)
@@ -62,10 +62,14 @@ class PseudoRandom {
6262
}
6363

6464
private:
65-
int32_t _x;
66-
int32_t _y;
67-
int32_t _z;
68-
int32_t _w;
65+
void _init(uint32_t seed);
66+
67+
uint32_t nextUInt32();
68+
69+
uint32_t _x;
70+
uint32_t _y;
71+
uint32_t _z;
72+
uint32_t _w;
6973
};
7074

7175
/**
@@ -81,4 +85,4 @@ class SecureRandom {
8185

8286
static SecureRandom* create();
8387
};
84-
}
88+
} // namespace mongo

src/mongo/platform/random_test.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include <set>
20+
#include <vector>
2021

2122
#include "mongo/platform/random.h"
2223

@@ -87,6 +88,73 @@ TEST(RandomTest, R2) {
8788
}
8889

8990

91+
TEST(RandomTest, NextInt32SanityCheck) {
92+
// Generate 1000 int32s and assert that each bit is set between 40% and 60% of the time. This is
93+
// a bare minimum sanity check, not an attempt to ensure quality random numbers.
94+
95+
PseudoRandom a(11);
96+
std::vector<int32_t> nums;
97+
for (int i = 0; i < 1000; i++) {
98+
nums.push_back(a.nextInt32());
99+
}
100+
101+
for (int bit = 0; bit < 32; bit++) {
102+
int onesCount = 0;
103+
for (size_t i = 0; i != nums.size(); ++i) {
104+
int32_t num = nums[i];
105+
bool isSet = (num >> bit) & 1;
106+
if (isSet)
107+
onesCount++;
108+
}
109+
110+
if (onesCount < 400 || onesCount > 600)
111+
FAIL() << "bit " << bit << " was set " << (onesCount / 10.) << "% of the time.";
112+
}
113+
}
114+
115+
TEST(RandomTest, NextInt64SanityCheck) {
116+
// Generate 1000 int64s and assert that each bit is set between 40% and 60% of the time. This is
117+
// a bare minimum sanity check, not an attempt to ensure quality random numbers.
118+
119+
PseudoRandom a(11);
120+
std::vector<int64_t> nums;
121+
for (int i = 0; i < 1000; i++) {
122+
nums.push_back(a.nextInt64());
123+
}
124+
125+
for (int bit = 0; bit < 64; bit++) {
126+
int onesCount = 0;
127+
for (size_t i = 0; i != nums.size(); ++i) {
128+
int32_t num = nums[i];
129+
130+
bool isSet = (num >> bit) & 1;
131+
if (isSet)
132+
onesCount++;
133+
}
134+
135+
if (onesCount < 400 || onesCount > 600)
136+
FAIL() << "bit " << bit << " was set " << (onesCount / 10.) << "% of the time.";
137+
}
138+
}
139+
140+
TEST(RandomTest, NextInt32InRange) {
141+
PseudoRandom a(11);
142+
for (int i = 0; i < 1000; i++) {
143+
int32_t res = a.nextInt32(10);
144+
ASSERT_GE(res, 0);
145+
ASSERT_LT(res, 10);
146+
}
147+
}
148+
149+
TEST(RandomTest, NextInt64InRange) {
150+
PseudoRandom a(11);
151+
for (int i = 0; i < 1000; i++) {
152+
int32_t res = a.nextInt64(10);
153+
ASSERT_GE(res, 0);
154+
ASSERT_LT(res, 10);
155+
}
156+
}
157+
90158
TEST(RandomTest, Secure1) {
91159
SecureRandom* a = SecureRandom::create();
92160
SecureRandom* b = SecureRandom::create();

0 commit comments

Comments
 (0)