summaryrefslogtreecommitdiff
path: root/db/oplog.cpp
diff options
context:
space:
mode:
authordwight <dwight@10gen.com>2010-12-19 10:54:45 -0500
committerdwight <dwight@10gen.com>2010-12-19 10:54:45 -0500
commit1fb5ac5453ebeeb77edec5cf863e1fbcf231f97f (patch)
tree7110842f272d09cf82118dc4b71dddd81fcfe32b /db/oplog.cpp
parent1dc486db7d321e39bc353193b2c537dd0d65d535 (diff)
downloadmongo-1fb5ac5453ebeeb77edec5cf863e1fbcf231f97f.tar.gz
dur optimize writing to the oplog for durability
Diffstat (limited to 'db/oplog.cpp')
-rw-r--r--db/oplog.cpp45
1 files changed, 31 insertions, 14 deletions
diff --git a/db/oplog.cpp b/db/oplog.cpp
index 59dd8f01ade..b7dc8e5949d 100644
--- a/db/oplog.cpp
+++ b/db/oplog.cpp
@@ -217,9 +217,10 @@ namespace mongo {
b.appendBool("b", *bb);
if ( o2 )
b.append("o2", *o2);
- BSONObj partial = b.done();
- int posz = partial.objsize();
- int len = posz + obj.objsize() + 1 + 2 /*o:*/;
+ BSONObj partial = b.done(); // partial is everything except the o:... part.
+
+ int po_sz = partial.objsize();
+ int len = po_sz + obj.objsize() + 1 + 2 /*o:*/;
Record *r;
if( logNS == 0 ) {
@@ -236,21 +237,37 @@ namespace mongo {
} else {
Client::Context ctx( logNS, dbpath, 0, false );
assert( nsdetails( logNS ) );
+ // first we allocate the space, then we fill it below.
r = theDataFileMgr.fast_oplog_insert( nsdetails( logNS ), logNS, len);
}
{
- const int size2 = obj.objsize() + 1 + 2;
- char *p = (char *) getDur().writingPtr(r->data, size2+posz);
- memcpy(p, partial.objdata(), posz);
- *((unsigned *)p) += size2;
- p += posz - 1;
- *p++ = (char) Object;
- *p++ = 'o'; // { o : ... }
- *p++ = 0;
- memcpy(p, obj.objdata(), obj.objsize());
- p += obj.objsize();
- *p = EOO;
+ const int size1 = po_sz-1; // less the EOO char
+ const int objOfs = size1+3; // 3 = byte BSONOBJTYPE + byte 'o' + byte \0
+ char *objInsertPoint = r->data + objOfs;
+
+ // don't bother if obj is tiny as there is some header overhead for the additional journal entry
+ // and also some computational administrative overhead.
+ bool objAppendWorked = obj.objsize() >= 32 &&
+ getDur().objAppend(objInsertPoint, obj.objdata(), obj.objsize());
+
+ void *p = (char *) getDur().writingPtr(r->data, objAppendWorked ? size1 : objOfs+obj.objsize()+1);
+
+ memcpy(p, partial.objdata(), size1);
+
+ // adjust overall bson object size for the o: field
+ *(static_cast<unsigned*>(p)) += obj.objsize() + 1/*fieldtype byte*/ + 2/*"o" fieldname*/;
+
+ if( !objAppendWorked ) {
+ char *b = static_cast<char *>(p);
+ b += size1;
+ *b++ = (char) Object;
+ *b++ = 'o'; // { o : ... }
+ *b++ = 0; // null terminate "o" fieldname
+ memcpy(b, obj.objdata(), obj.objsize());
+ b += obj.objsize();
+ *b = EOO;
+ }
}
context.getClient()->setLastOp( ts.asDate() );