BSONArray versionArray(){ static BSONArray out; if (out.isEmpty()) { BSONArray tmp = _versionArray(versionString); out = tmp; return tmp; } return out; }
break; } else if (curPart == "pre"){ finalPart = -100; break; } } curPart = ""; } while (*c++); b.append(finalPart); return b.arr(); } const BSONArray versionArray = _versionArray(versionString); string mongodVersion() { stringstream ss; ss << "db version v" << versionString << ", pdfile version " << VERSION << "." << VERSION_MINOR; return ss.str(); } #ifndef _SCONS // only works in scons const char * gitVersion() { return "not-scons"; } #endif void printGitVersion() { log() << "git version: " << gitVersion() << endl; } #ifndef _SCONS
void run() { assert( _versionArray("1.2.3") == BSON_ARRAY(1 << 2 << 3 << 0) ); assert( _versionArray("1.2.0") == BSON_ARRAY(1 << 2 << 0 << 0) ); assert( _versionArray("2.0.0") == BSON_ARRAY(2 << 0 << 0 << 0) ); assert( _versionArray("1.2.3-pre-") == BSON_ARRAY(1 << 2 << 3 << -100) ); assert( _versionArray("1.2.0-pre-") == BSON_ARRAY(1 << 2 << 0 << -100) ); assert( _versionArray("2.0.0-pre-") == BSON_ARRAY(2 << 0 << 0 << -100) ); assert( _versionArray("1.2.3-rc0") == BSON_ARRAY(1 << 2 << 3 << -10) ); assert( _versionArray("1.2.0-rc1") == BSON_ARRAY(1 << 2 << 0 << -9) ); assert( _versionArray("2.0.0-rc2") == BSON_ARRAY(2 << 0 << 0 << -8) ); // Note that the pre of an rc is the same as the rc itself assert( _versionArray("1.2.3-rc3-pre-") == BSON_ARRAY(1 << 2 << 3 << -7) ); assert( _versionArray("1.2.0-rc4-pre-") == BSON_ARRAY(1 << 2 << 0 << -6) ); assert( _versionArray("2.0.0-rc5-pre-") == BSON_ARRAY(2 << 0 << 0 << -5) ); versionArray(); // make sure we work on current versionString log(1) << "versionArrayTest passed" << endl; }
namespace mongo { /* Approved formats for versionString: * 1.2.3 * 1.2.3-pre- * 1.2.3-rc4 (up to rc9) * 1.2.3-rc4-pre- * If you really need to do something else you'll need to fix _versionArray() */ const char versionString[] = "1.9.1-pre-"; // See unit test for example outputs static BSONArray _versionArray(const char* version){ // this is inefficient, but cached so it doesn't matter BSONArrayBuilder b; string curPart; const char* c = version; int finalPart = 0; // 0 = final release, -100 = pre, -10 to -1 = -10 + X for rcX do { //walks versionString including NUL byte if (!(*c == '.' || *c == '-' || *c == '\0')){ curPart += *c; continue; } try { unsigned num = stringToNum(curPart.c_str()); b.append((int) num); } catch (...){ // not a number if (curPart.empty()){ assert(*c == '\0'); break; } else if (startsWith(curPart, "rc")){ finalPart = -10 + stringToNum(curPart.c_str()+2); break; } else if (curPart == "pre"){ finalPart = -100; break; } } curPart = ""; } while (*c++); b.append(finalPart); return b.arr(); } const BSONArray versionArray = _versionArray(versionString); string mongodVersion() { stringstream ss; ss << "db version v" << versionString << ", pdfile version " << VERSION << "." << VERSION_MINOR; return ss.str(); } #ifndef _SCONS // only works in scons const char * gitVersion() { return "not-scons"; } #endif void printGitVersion() { log() << "git version: " << gitVersion() << endl; } #ifndef _SCONS #if defined(_WIN32) string sysInfo() { stringstream ss; ss << "not-scons win"; ss << " mscver:" << _MSC_FULL_VER << " built:" << __DATE__; ss << " boostver:" << BOOST_VERSION; #if( !defined(_MT) ) #error _MT is not defined #endif ss << (sizeof(char *) == 8) ? " 64bit" : " 32bit"; return ss.str(); } #else string sysInfo() { return ""; } #endif #endif void printSysInfo() { log() << "build info: " << sysInfo() << endl; } // // 32 bit systems warning // void show_warnings() { // each message adds a leading but not a trailing newline bool warned = false; { const char * foo = strchr( versionString , '.' ) + 1; int bar = atoi( foo ); if ( ( 2 * ( bar / 2 ) ) != bar ) { cout << "\n** NOTE: This is a development version (" << versionString << ") of MongoDB."; cout << "\n** Not recommended for production." << endl; warned = true; } } if ( sizeof(int*) == 4 ) { cout << endl; cout << "** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data" << endl; cout << "** see http://blog.mongodb.org/post/137788967/32-bit-limitations" << endl; cout << "** with --journal, the limit is lower" << endl; warned = true; } #ifdef __linux__ if (boost::filesystem::exists("/proc/vz") && !boost::filesystem::exists("/proc/bc")) { cout << endl; cout << "** WARNING: You are running in OpenVZ. This is known to be broken!!!" << endl; warned = true; } if (boost::filesystem::exists("/sys/devices/system/node/node1")){ // We are on a box with a NUMA enabled kernel and more than 1 numa node (they start at node0) // Now we look at the first line of /proc/self/numa_maps // // Bad example: // $ cat /proc/self/numa_maps // 00400000 default file=/bin/cat mapped=6 N4=6 // // Good example: // $ numactl --interleave=all cat /proc/self/numa_maps // 00400000 interleave:0-7 file=/bin/cat mapped=6 N4=6 File f; f.open("/proc/self/numa_maps", /*read_only*/true); char line[100]; //we only need the first line f.read(0, line, sizeof(line)); // just in case... line[98] = ' '; line[99] = '\0'; // skip over pointer const char* space = strchr(line, ' '); if (!startsWith(space+1, "interleave")){ cout << endl; cout << "** WARNING: You are running on a NUMA machine." << endl; cout << "** We suggest launching mongod like this to avoid performance problems:" << endl; cout << "** numactl --interleave=all mongod [other options]" << endl; warned = true; } } #endif if (warned) cout << endl; } int versionCmp(StringData rhs, StringData lhs) { if (strcmp(rhs.data(),lhs.data()) == 0) return 0; // handle "1.2.3-" and "1.2.3-pre" if (rhs.size() < lhs.size()) { if (strncmp(rhs.data(), lhs.data(), rhs.size()) == 0 && lhs.data()[rhs.size()] == '-') return +1; } else if (rhs.size() > lhs.size()) { if (strncmp(rhs.data(), lhs.data(), lhs.size()) == 0 && rhs.data()[lhs.size()] == '-') return -1; } return lexNumCmp(rhs.data(), lhs.data()); } class VersionCmpTest : public UnitTest { public: void run() { assert( versionCmp("1.2.3", "1.2.3") == 0 ); assert( versionCmp("1.2.3", "1.2.4") < 0 ); assert( versionCmp("1.2.3", "1.2.20") < 0 ); assert( versionCmp("1.2.3", "1.20.3") < 0 ); assert( versionCmp("2.2.3", "10.2.3") < 0 ); assert( versionCmp("1.2.3", "1.2.3-") > 0 ); assert( versionCmp("1.2.3", "1.2.3-pre") > 0 ); assert( versionCmp("1.2.3", "1.2.4-") < 0 ); assert( versionCmp("1.2.3-", "1.2.3") < 0 ); assert( versionCmp("1.2.3-pre", "1.2.3") < 0 ); log(1) << "versionCmpTest passed" << endl; } } versionCmpTest; class VersionArrayTest : public UnitTest { public: void run() { assert( _versionArray("1.2.3") == BSON_ARRAY(1 << 2 << 3 << 0) ); assert( _versionArray("1.2.0") == BSON_ARRAY(1 << 2 << 0 << 0) ); assert( _versionArray("2.0.0") == BSON_ARRAY(2 << 0 << 0 << 0) ); assert( _versionArray("1.2.3-pre-") == BSON_ARRAY(1 << 2 << 3 << -100) ); assert( _versionArray("1.2.0-pre-") == BSON_ARRAY(1 << 2 << 0 << -100) ); assert( _versionArray("2.0.0-pre-") == BSON_ARRAY(2 << 0 << 0 << -100) ); assert( _versionArray("1.2.3-rc0") == BSON_ARRAY(1 << 2 << 3 << -10) ); assert( _versionArray("1.2.0-rc1") == BSON_ARRAY(1 << 2 << 0 << -9) ); assert( _versionArray("2.0.0-rc2") == BSON_ARRAY(2 << 0 << 0 << -8) ); // Note that the pre of an rc is the same as the rc itself assert( _versionArray("1.2.3-rc3-pre-") == BSON_ARRAY(1 << 2 << 3 << -7) ); assert( _versionArray("1.2.0-rc4-pre-") == BSON_ARRAY(1 << 2 << 0 << -6) ); assert( _versionArray("2.0.0-rc5-pre-") == BSON_ARRAY(2 << 0 << 0 << -5) ); log(1) << "versionArrayTest passed" << endl; } } versionArrayTest; }