diff options
author | Eliot Horowitz <eliot@10gen.com> | 2013-03-04 14:19:24 -0500 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2013-03-04 14:20:06 -0500 |
commit | 00c93cd20c7aed10c5f26d42272182d79b4a8972 (patch) | |
tree | 23c6c24ca05d5437165c992f8b1dce028c89e243 | |
parent | acfb8d8abda2587c6015b354684614a5a1adbbd1 (diff) | |
download | mongo-00c93cd20c7aed10c5f26d42272182d79b4a8972.tar.gz |
SERVER-8431: make large index updates much less impactful
-rw-r--r-- | src/mongo/db/dur_commitjob.cpp | 56 | ||||
-rw-r--r-- | src/mongo/db/dur_commitjob.h | 9 |
2 files changed, 50 insertions, 15 deletions
diff --git a/src/mongo/db/dur_commitjob.cpp b/src/mongo/db/dur_commitjob.cpp index d8c1d7d0555..96eb203e1bc 100644 --- a/src/mongo/db/dur_commitjob.cpp +++ b/src/mongo/db/dur_commitjob.cpp @@ -31,29 +31,63 @@ namespace mongo { #endif namespace dur { - void ThreadLocalIntents::push(const WriteIntent& x) { + + ThreadLocalIntents::~ThreadLocalIntents() { + fassert( 16731, intents.size() == 0 ); + } + + void ThreadLocalIntents::push(const WriteIntent& x) { if( !commitJob._hasWritten ) commitJob._hasWritten = true; - if( n == 21 ) - unspool(); - i[n++] = x; + + if( intents.size() == N ) { + if ( !condense() ) { + unspool(); + } + } + + intents.push_back( x ); #if( CHECK_SPOOLING ) nSpooled++; #endif } void ThreadLocalIntents::_unspool() { - if( n ) { - for( int j = 0; j < n; j++ ) - commitJob.note(i[j].start(), i[j].length()); + if ( intents.size() == 0 ) + return; + + for( unsigned j = 0; j < intents.size(); j++ ) { + commitJob.note(intents[j].start(), intents[j].length()); + } + #if( CHECK_SPOOLING ) - nSpooled.signedAdd(-n); + nSpooled.signedAdd( -1 * static_cast<int>(intents.size()) ); #endif - n = 0; - dassert( cmdLine.dur ); + + intents.clear(); + } + + bool ThreadLocalIntents::condense() { + std::sort( intents.begin(), intents.end() ); + + bool didAnything = false; + + for ( unsigned x = 0; x < intents.size() - 1 ; x++ ) { + if ( intents[x].overlaps( intents[x+1] ) ) { + intents[x].absorb( intents[x+1] ); + intents.erase( intents.begin() + x + 1 ); + x--; + didAnything = true; +#if( CHECK_SPOOLING ) + nSpooled.signedAdd(-1); +#endif + } } + + return didAnything; } + void ThreadLocalIntents::unspool() { - if( n ) { + if ( intents.size() ) { SimpleMutex::scoped_lock lk(commitJob.groupCommitMutex); _unspool(); } diff --git a/src/mongo/db/dur_commitjob.h b/src/mongo/db/dur_commitjob.h index e3aafbe06e6..ed7fd9a46ff 100644 --- a/src/mongo/db/dur_commitjob.h +++ b/src/mongo/db/dur_commitjob.h @@ -108,14 +108,15 @@ namespace mongo { /** so we don't have to lock the groupCommitMutex too often */ class ThreadLocalIntents { enum { N = 21 }; - dur::WriteIntent i[N]; - int n; + std::vector<dur::WriteIntent> intents; + bool condense(); public: - ThreadLocalIntents() : n(0) { } + ThreadLocalIntents() : intents(N) { intents.clear(); } + ~ThreadLocalIntents(); void _unspool(); void unspool(); void push(const WriteIntent& i); - int n_informational() const { return n; } + int n_informational() const { return intents.size(); } static AtomicUInt nSpooled; }; |