summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2013-03-04 14:19:24 -0500
committerEliot Horowitz <eliot@10gen.com>2013-03-04 14:20:06 -0500
commit00c93cd20c7aed10c5f26d42272182d79b4a8972 (patch)
tree23c6c24ca05d5437165c992f8b1dce028c89e243
parentacfb8d8abda2587c6015b354684614a5a1adbbd1 (diff)
downloadmongo-00c93cd20c7aed10c5f26d42272182d79b4a8972.tar.gz
SERVER-8431: make large index updates much less impactful
-rw-r--r--src/mongo/db/dur_commitjob.cpp56
-rw-r--r--src/mongo/db/dur_commitjob.h9
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;
};