summaryrefslogtreecommitdiff
path: root/src/mongo/client/examples/mongoperf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/client/examples/mongoperf.cpp')
-rw-r--r--src/mongo/client/examples/mongoperf.cpp189
1 files changed, 97 insertions, 92 deletions
diff --git a/src/mongo/client/examples/mongoperf.cpp b/src/mongo/client/examples/mongoperf.cpp
index 88d3d03e422..1681e8a9113 100644
--- a/src/mongo/client/examples/mongoperf.cpp
+++ b/src/mongo/client/examples/mongoperf.cpp
@@ -61,11 +61,11 @@ using namespace mongoutils::str;
int dummy;
unsigned recSizeKB;
-LogFile *lf = 0;
-MemoryMappedFile *mmfFile;
-char *mmf = 0;
+LogFile* lf = 0;
+MemoryMappedFile* mmfFile;
+char* mmf = 0;
bo options;
-unsigned long long len; // file len
+unsigned long long len; // file len
const unsigned PG = 4096;
unsigned nThreadsRunning = 0;
@@ -77,22 +77,23 @@ SimpleMutex m;
int syncDelaySecs = 0;
void syncThread() {
- while( 1 ) {
+ while (1) {
mongo::Timer t;
mmfFile->flush(true);
- cout << " mmf sync took " << t.millis() << "ms" << endl;
+ cout << " mmf sync took " << t.millis()
+ << "ms" << endl;
sleepsecs(syncDelaySecs);
}
}
-void stripTrailing(std::string& s, const char *chars) {
+void stripTrailing(std::string& s, const char* chars) {
std::string::iterator to = s.begin();
- for ( std::string::iterator i = s.begin(); i != s.end(); i++ ) {
+ for (std::string::iterator i = s.begin(); i != s.end(); i++) {
// During each iteration if i finds a non-"chars" character it writes it to the
// position of t. So the part of the string left from the "to" iterator is already
// "cleared" string.
- if ( !contains(chars, *i) ) {
- if ( i != to )
+ if (!contains(chars, *i)) {
+ if (i != to)
s.replace(to, to + 1, 1, *i);
to++;
}
@@ -101,14 +102,16 @@ void stripTrailing(std::string& s, const char *chars) {
}
char* round(char* x) {
- size_t f = (size_t) x;
- char *p = (char *) ((f+PG-1)/PG*PG);
+ size_t f = (size_t)x;
+ char* p = (char*)((f + PG - 1) / PG * PG);
return p;
}
struct Aligned {
char x[8192];
- char* addr() { return round(x); }
+ char* addr() {
+ return round(x);
+ }
};
unsigned long long rrand() {
@@ -122,118 +125,118 @@ void workerThread() {
cout << "read:" << r << " write:" << w << endl;
long long su = options["sleepMicros"].numberLong();
Aligned a;
- while( 1 ) {
+ while (1) {
unsigned long long rofs = (rrand() * PG) % len;
unsigned long long wofs = (rrand() * PG) % len;
- const unsigned P = PG/1024;
- if( mmf ) {
- if( r ) {
- for( unsigned p = P; p <= recSizeKB; p += P ) {
- if( rofs < len )
+ const unsigned P = PG / 1024;
+ if (mmf) {
+ if (r) {
+ for (unsigned p = P; p <= recSizeKB; p += P) {
+ if (rofs < len)
dummy += mmf[rofs];
rofs += PG;
}
iops.fetchAndAdd(1);
}
- if( w ) {
- for( unsigned p = P; p <= recSizeKB; p += P ) {
- if( wofs < len )
+ if (w) {
+ for (unsigned p = P; p <= recSizeKB; p += P) {
+ if (wofs < len)
mmf[wofs] = 3;
wofs += PG;
}
iops.fetchAndAdd(1);
}
- }
- else {
- if( r ) {
+ } else {
+ if (r) {
lf->readAt(rofs, a.addr(), recSizeKB * 1024);
iops.fetchAndAdd(1);
}
- if( w ) {
+ if (w) {
lf->writeAt(wofs, a.addr(), recSizeKB * 1024);
iops.fetchAndAdd(1);
}
}
long long micros = su / nThreadsRunning;
- if( micros ) {
+ if (micros) {
sleepmicros(micros);
}
}
}
void go() {
- verify( options["r"].trueValue() || options["w"].trueValue() );
+ verify(options["r"].trueValue() || options["w"].trueValue());
recSizeKB = options["recSizeKB"].numberInt();
- if( recSizeKB == 0 )
+ if (recSizeKB == 0)
recSizeKB = 4;
- verify( recSizeKB <= 64000 && recSizeKB > 0 );
+ verify(recSizeKB <= 64000 && recSizeKB > 0);
MemoryMappedFile f;
cout << "creating test file size:";
len = options["fileSizeMB"].numberLong();
- if( len == 0 ) len = 1;
+ if (len == 0)
+ len = 1;
cout << len << "MB ..." << endl;
- if( 0 && len > 2000 && !options["mmf"].trueValue() ) {
+ if (0 && len > 2000 && !options["mmf"].trueValue()) {
// todo make tests use 64 bit offsets in their i/o -- i.e. adjust LogFile::writeAt and such
cout << "\nsizes > 2GB not yet supported with mmf:false" << endl;
return;
}
len *= 1024 * 1024;
- const char *fname = "./mongoperf__testfile__tmp";
+ const char* fname = "./mongoperf__testfile__tmp";
try {
boost::filesystem::remove(fname);
- }
- catch(...) {
+ } catch (...) {
cout << "error deleting file " << fname << endl;
return;
}
- lf = new LogFile(fname,true);
- const unsigned sz = 1024 * 1024 * 32; // needs to be big as we are using synchronousAppend. if we used a regular MongoFile it wouldn't have to be
- char *buf = (char*) mongoMalloc(sz+4096);
- const char *p = round(buf);
- for( unsigned long long i = 0; i < len; i += sz ) {
+ lf = new LogFile(fname, true);
+ const unsigned sz = 1024 * 1024 *
+ 32; // needs to be big as we are using synchronousAppend. if we used a regular MongoFile it wouldn't have to be
+ char* buf = (char*)mongoMalloc(sz + 4096);
+ const char* p = round(buf);
+ for (unsigned long long i = 0; i < len; i += sz) {
lf->synchronousAppend(p, sz);
- if( i % (1024ULL*1024*1024) == 0 && i ) {
- cout << i / (1024ULL*1024*1024) << "GB..." << endl;
+ if (i % (1024ULL * 1024 * 1024) == 0 && i) {
+ cout << i / (1024ULL * 1024 * 1024) << "GB..." << endl;
}
}
BSONObj& o = options;
- if( o["mmf"].trueValue() ) {
+ if (o["mmf"].trueValue()) {
delete lf;
lf = 0;
mmfFile = new MemoryMappedFile();
- mmf = (char *) mmfFile->map(fname);
- verify( mmf );
+ mmf = (char*)mmfFile->map(fname);
+ verify(mmf);
syncDelaySecs = options["syncDelay"].numberInt();
- if( syncDelaySecs ) {
+ if (syncDelaySecs) {
stdx::thread t(syncThread);
}
}
- cout << "testing..."<< endl;
+ cout << "testing..." << endl;
cout << "options:" << o.toString() << endl;
unsigned wthr = 1;
- if( !o["nThreads"].eoo() ) {
- wthr = (unsigned) o["nThreads"].Int();
+ if (!o["nThreads"].eoo()) {
+ wthr = (unsigned)o["nThreads"].Int();
}
cout << "wthr " << wthr << endl;
- if( wthr < 1 ) {
+ if (wthr < 1) {
cout << "bad threads field value" << endl;
return;
}
unsigned i = 0;
unsigned d = 1;
- unsigned &nthr = nThreadsRunning;
- while( 1 ) {
- if( i++ % 8 == 0 ) {
- if( nthr < wthr ) {
- while( nthr < wthr && nthr < d ) {
+ unsigned& nthr = nThreadsRunning;
+ while (1) {
+ if (i++ % 8 == 0) {
+ if (nthr < wthr) {
+ while (nthr < wthr && nthr < d) {
nthr++;
stdx::thread w(workerThread);
}
@@ -244,48 +247,52 @@ void go() {
sleepsecs(1);
unsigned long long w = iops.loadRelaxed();
iops.store(0);
- w /= 1; // 1 secs
+ w /= 1; // 1 secs
cout << w << " ops/sec ";
- if( mmf == 0 )
+ if (mmf == 0)
// only writing 4 bytes with mmf so we don't say this
cout << (w * PG / 1024 / 1024) << " MB/sec";
cout << endl;
}
}
-int main(int argc, char *argv[]) {
-
+int main(int argc, char* argv[]) {
try {
cout << "mongoperf" << endl;
- if( argc > 1 ) {
-cout <<
-
-"\n"
-"usage:\n"
-"\n"
-" mongoperf < myjsonconfigfile\n"
-"\n"
-" {\n"
-" nThreads:<n>, // number of threads (default 1)\n"
-" fileSizeMB:<n>, // test file size (default 1MB)\n"
-" sleepMicros:<n>, // pause for sleepMicros/nThreads between each operation (default 0)\n"
-" mmf:<bool>, // if true do i/o's via memory mapped files (default false)\n"
-" r:<bool>, // do reads (default false)\n"
-" w:<bool>, // do writes (default false)\n"
-" recSizeKB:<n>, // size of each write (default 4KB)\n"
-" syncDelay:<n> // secs between fsyncs, like --syncdelay in mongod. (default 0/never)\n"
-" }\n"
-"\n"
-"mongoperf is a performance testing tool. the initial tests are of disk subsystem performance; \n"
-" tests of mongos and mongod will be added later.\n"
-"most fields are optional.\n"
-"non-mmf io is direct io (no caching). use a large file size to test making the heads\n"
-" move significantly and to avoid i/o coalescing\n"
-"mmf io uses caching (the file system cache).\n"
-"\n"
-
-<< endl;
+ if (argc > 1) {
+ cout <<
+
+ "\n"
+ "usage:\n"
+ "\n"
+ " mongoperf < myjsonconfigfile\n"
+ "\n"
+ " {\n"
+ " nThreads:<n>, // number of threads (default 1)\n"
+ " fileSizeMB:<n>, // test file size (default 1MB)\n"
+ " sleepMicros:<n>, // pause for sleepMicros/nThreads between each operation "
+ "(default 0)\n"
+ " mmf:<bool>, // if true do i/o's via memory mapped files (default "
+ "false)\n"
+ " r:<bool>, // do reads (default false)\n"
+ " w:<bool>, // do writes (default false)\n"
+ " recSizeKB:<n>, // size of each write (default 4KB)\n"
+ " syncDelay:<n> // secs between fsyncs, like --syncdelay in mongod. "
+ "(default 0/never)\n"
+ " }\n"
+ "\n"
+ "mongoperf is a performance testing tool. the initial tests are of disk subsystem "
+ "performance; \n"
+ " tests of mongos and mongod will be added later.\n"
+ "most fields are optional.\n"
+ "non-mmf io is direct io (no caching). use a large file size to test making the "
+ "heads\n"
+ " move significantly and to avoid i/o coalescing\n"
+ "mmf io uses caching (the file system cache).\n"
+ "\n"
+
+ << endl;
return EXIT_SUCCESS;
}
@@ -294,7 +301,7 @@ cout <<
char input[1024];
memset(input, 0, sizeof(input));
cin.read(input, 1000);
- if( *input == 0 ) {
+ if (*input == 0) {
cout << "error no options found on stdin for mongoperf" << endl;
return EXIT_FAILURE;
}
@@ -303,8 +310,7 @@ cout <<
stripTrailing(s, " \n\r\0x1a");
try {
options = fromjson(s);
- }
- catch(...) {
+ } catch (...) {
cout << "couldn't parse json options. input was:\n|" << s << "|" << endl;
return EXIT_FAILURE;
}
@@ -312,8 +318,7 @@ cout <<
ProcessInfo::initializeSystemInfo();
go();
- }
- catch(DBException& e) {
+ } catch (DBException& e) {
cout << "caught DBException " << e.toString() << endl;
return EXIT_FAILURE;
}