Skip to content

Commit

Permalink
CXX-650 Backport server r2.6.11..r2.6.12 changes
Browse files Browse the repository at this point in the history
Server SHAs picked into this commit:

52ae817
ce9d96d
c980c02
ec270ef
aa5a2f5
1290ac9
d73c92b
  • Loading branch information
acmorrow committed Mar 22, 2016
1 parent 6067bc9 commit 86bd3e6
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 20 deletions.
18 changes: 17 additions & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,17 @@ usePCH = has_option( "usePCH" )

justClientLib = (COMMAND_LINE_TARGETS == ['mongoclient'])

env = Environment( BUILD_DIR=variantDir,
# On some branches, we honor several scons Variables on the command
# line. Those don't exist on 2.6, but it is easy to get in the habit
# of using them. By default SCons silently ignores them, which can be
# very confusing if you say 'scons CC=clang' on the v2.6 branch, for
# instance. We create an empty Variables object here and feed it to
# the Environment constructor so that we can ask for any unknown
# variables (and all should be), below.
env_vars = Variables()

env = Environment( variables=env_vars,
BUILD_DIR=variantDir,
DIST_ARCHIVE_SUFFIX='.tgz',
EXTRAPATH=get_option("extrapath"),
MODULE_BANNERS=[],
Expand All @@ -466,6 +476,12 @@ env = Environment( BUILD_DIR=variantDir,
CONFIGURELOG = '#' + scons_data_dir + '/config.log'
)

# Report any unknown variables as an error.
unknown_vars = env_vars.UnknownVariables()
if unknown_vars:
print "Unknown variables specified: {0}".format(", ".join(unknown_vars.keys()))
Exit(1)

if has_option("cache"):
EnsureSConsVersion( 2, 3, 0 )
if has_option("release"):
Expand Down
1 change: 1 addition & 0 deletions src/mongo/base/error_codes.err
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ error_code("IndexOptionsConflict", 85 )
error_code("IndexKeySpecsConflict", 86 )
error_code("OutdatedClient", 101)
error_code("IncompatibleAuditMetadata", 102)
error_code("CappedPositionLost", 103)

# Non-sequential error codes (for compatibility only)
error_code("NetworkTimeout", 89)
Expand Down
26 changes: 15 additions & 11 deletions src/mongo/platform/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,49 +35,53 @@ namespace mongo {

// ---- PseudoRandom -----

int32_t PseudoRandom::nextInt32() {
int32_t t = _x ^ (_x << 11);
uint32_t PseudoRandom::nextUInt32() {
uint32_t t = _x ^ (_x << 11);
_x = _y;
_y = _z;
_z = _w;
return _w = _w ^ (_w >> 19) ^ (t ^ (t >> 8));
}

namespace {
const int32_t default_y = 362436069;
const int32_t default_z = 521288629;
const int32_t default_w = 88675123;
const uint32_t default_y = 362436069;
const uint32_t default_z = 521288629;
const uint32_t default_w = 88675123;
}

PseudoRandom::PseudoRandom( int32_t seed ) {
_x = seed;
_x = static_cast<uint32_t>(seed);
_y = default_y;
_z = default_z;
_w = default_w;
}


PseudoRandom::PseudoRandom( uint32_t seed ) {
_x = static_cast<int32_t>(seed);
_x = seed;
_y = default_y;
_z = default_z;
_w = default_w;
}


PseudoRandom::PseudoRandom( int64_t seed ) {
int32_t high = seed >> 32;
int32_t low = seed & 0xFFFFFFFF;
uint32_t high = seed >> 32;
uint32_t low = seed & 0xFFFFFFFF;

_x = high ^ low;
_y = default_y;
_z = default_z;
_w = default_w;
}

int32_t PseudoRandom::nextInt32() {
return nextUInt32();
}

int64_t PseudoRandom::nextInt64() {
int64_t a = nextInt32();
int64_t b = nextInt32();
uint64_t a = nextUInt32();
uint64_t b = nextUInt32();
return ( a << 32 ) | b;
}

Expand Down
20 changes: 13 additions & 7 deletions src/mongo/platform/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,21 @@ namespace mongo {
/**
* @return a number between 0 and max
*/
int32_t nextInt32( int32_t max ) { return nextInt32() % max; }
int32_t nextInt32( int32_t max ) {
return static_cast<uint32_t>(nextInt32()) % static_cast<uint32_t>(max);
}

/**
* @return a number between 0 and max
*/
int64_t nextInt64( int64_t max ) { return nextInt64() % max; }
int64_t nextInt64( int64_t max ) {
return static_cast<uint64_t>(nextInt64()) % static_cast<uint64_t>(max);
}

/**
* @return a number between 0 and max
*
* This makes PsuedoRandom instances passable as the third argument to std::random_shuffle
* This makes PseudoRandom instances passable as the third argument to std::random_shuffle
*/
intptr_t operator()(intptr_t max) {
if (sizeof(intptr_t) == 4)
Expand All @@ -58,10 +62,12 @@ namespace mongo {
}

private:
int32_t _x;
int32_t _y;
int32_t _z;
int32_t _w;
uint32_t nextUInt32();

uint32_t _x;
uint32_t _y;
uint32_t _z;
uint32_t _w;
};

/**
Expand Down
63 changes: 63 additions & 0 deletions src/mongo/platform/random_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#include <set>
#include <vector>

#include "mongo/platform/random.h"

Expand Down Expand Up @@ -86,6 +87,68 @@ namespace mongo {
ASSERT_EQUALS( 100U, s.size() );
}

TEST(RandomTest, NextInt32SanityCheck) {
// Generate 1000 int32s and assert that each bit is set between 40% and 60% of the time.
// This is a bare minimum sanity check, not an attempt to ensure quality random numbers.

PseudoRandom a(11);
std::vector<int32_t> nums;
for (int i = 0; i < 1000; i++) {
nums.push_back(a.nextInt32());
}

for (int bit = 0; bit < 32; bit++) {
int onesCount = 0;
for (size_t i=0; i < nums.size(); i++) {
bool isSet = (nums[i] >> bit) & 1;
if (isSet)
onesCount++;
}

ASSERT_FALSE(onesCount < 400 || onesCount > 600);
}
}

TEST(RandomTest, NextInt64SanityCheck) {
// Generate 1000 int64s and assert that each bit is set between 40% and 60% of the time.
// This is a bare minimum sanity check, not an attempt to ensure quality random numbers.

PseudoRandom a(11);
std::vector<int64_t> nums;
for (int i = 0; i < 1000; i++) {
nums.push_back(a.nextInt64());
}

for (int bit = 0; bit < 64; bit++) {
int onesCount = 0;
for (size_t i=0; i < nums.size(); i++) {
bool isSet = (nums[i] >> bit) & 1;
if (isSet)
onesCount++;
}

ASSERT_FALSE(onesCount < 400 || onesCount > 600);
}
}

TEST(RandomTest, NextInt32InRange) {
PseudoRandom a(11);
for (int i = 0; i < 1000; i++) {
int32_t res = a.nextInt32(10);
ASSERT_GREATER_THAN_OR_EQUALS(res, 0);
ASSERT_LESS_THAN(res, 10);
}
}

TEST(RandomTest, NextInt64InRange) {
PseudoRandom a(11);
for (int i = 0; i < 1000; i++) {
int64_t res = a.nextInt64(10);
ASSERT_GREATER_THAN_OR_EQUALS(res, 0);
ASSERT_LESS_THAN(res, 10);
}
}


TEST( RandomTest, Secure1 ) {
SecureRandom* a = SecureRandom::create();
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/util/version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace mongo {
* 1.2.3-rc4-pre-
* If you really need to do something else you'll need to fix _versionArray()
*/
const char versionString[] = "2.6.11";
const char versionString[] = "2.6.12";

// See unit test for example outputs
BSONArray toVersionArray(const char* version){
Expand Down

0 comments on commit 86bd3e6

Please sign in to comment.