summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Morrow <acm@10gen.com>2013-07-17 20:50:55 -0400
committerAndrew Morrow <acm@10gen.com>2013-07-18 13:16:43 -0400
commit46a7a951f43dd20aa20937bbeed0584c9dd19485 (patch)
tree32361015c4352d2d7326d3776571f2a7381fa1ee /src
parenta64cbc9c0f2c98ea48a0efdaa431075e1912fe51 (diff)
downloadmongo-46a7a951f43dd20aa20937bbeed0584c9dd19485.tar.gz
SERVER-10214 When doing an object replacement, update any 0 timestamps in first two fields
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/ops/modifier_object_replace.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/mongo/db/ops/modifier_object_replace.cpp b/src/mongo/db/ops/modifier_object_replace.cpp
index 99d94c0dbe7..a8d6a128a85 100644
--- a/src/mongo/db/ops/modifier_object_replace.cpp
+++ b/src/mongo/db/ops/modifier_object_replace.cpp
@@ -21,6 +21,30 @@
namespace mongo {
+ namespace {
+ // TODO: Egregiously stolen from jsobjmanipulator.h and instance.cpp to break a link
+ // dependency cycle. We should sort this out, but we don't need to do it right now.
+ void fixupTimestamps( const BSONObj& obj ) {
+ BSONObjIterator i(obj);
+ for(int j = 0; i.moreWithEOO() && j < 2; ++j) {
+ BSONElement e = i.next();
+ if (e.eoo())
+ break;
+ if (e.type() == Timestamp) {
+ // performance note, this locks a mutex:
+ unsigned long long &timestamp =
+ *(reinterpret_cast<unsigned long long*>(
+ const_cast<char *>(e.value())));
+ if (timestamp == 0) {
+ mutex::scoped_lock lk(OpTime::m);
+ timestamp = OpTime::now(lk).asDate();
+ }
+ break;
+ }
+ }
+ }
+ }
+
struct ModifierObjectReplace::PreparedState {
PreparedState(mutablebson::Document* targetDoc)
@@ -59,11 +83,10 @@ namespace mongo {
}
}
- // TODO: update timestamps?
-
// We make a copy of the object here because the update driver does not guarantees, in
// the case of object replacement, that the modExpr is going to outlive this mod.
_val = modExpr.embeddedObject().getOwned();
+ fixupTimestamps(_val);
return Status::OK();
}