From 532dfe1180c2da552bebed70af1e7fba34cf355c Mon Sep 17 00:00:00 2001 From: Andy Schwerin Date: Thu, 7 May 2015 16:45:29 -0400 Subject: SERVER-13874 Make mongo::Milliseconds et al. aliases for equivalent stdx::chrono types. Also introduces operators for adding stdx::chrono::duration to Date_t, subtracting two Date_ts to get Milliseconds, and remove the use of reinterpret_cast from the implementation of BSON Timestamp type. --- src/mongo/bson/bson_validate_test.cpp | 2 +- src/mongo/bson/bsonelement.cpp | 20 +- src/mongo/bson/bsonelement.h | 5 +- src/mongo/bson/bsonobjbuilder.cpp | 13 +- src/mongo/bson/json.cpp | 12 +- src/mongo/bson/mutable/mutable_bson_test.cpp | 14 +- src/mongo/bson/oid.cpp | 2 +- src/mongo/bson/oid.h | 2 +- src/mongo/bson/timestamp.h | 83 ++--- src/mongo/client/connection_pool.cpp | 28 +- src/mongo/client/connection_pool.h | 2 +- src/mongo/client/remote_command_executor.cpp | 5 +- src/mongo/client/remote_command_executor.h | 1 - src/mongo/client/remote_command_executor_impl.cpp | 34 +-- src/mongo/db/auth/user_cache_invalidator_job.cpp | 17 +- src/mongo/db/concurrency/lock_state.cpp | 2 +- src/mongo/db/db.cpp | 2 +- src/mongo/db/dbcommands.cpp | 4 +- src/mongo/db/dbhelpers.cpp | 6 +- src/mongo/db/field_parser_test.cpp | 6 +- src/mongo/db/hasher_test.cpp | 4 +- src/mongo/db/pipeline/document_value_test.cpp | 26 +- src/mongo/db/pipeline/expression.cpp | 4 +- src/mongo/db/pipeline/value.cpp | 7 +- src/mongo/db/pipeline/value.h | 6 +- src/mongo/db/query/index_bounds_builder_test.cpp | 2 +- src/mongo/db/range_deleter.cpp | 40 +-- src/mongo/db/repl/base_cloner_test_fixture.cpp | 4 +- .../repl/check_quorum_for_config_change_test.cpp | 62 ++-- src/mongo/db/repl/data_replicator.cpp | 4 +- src/mongo/db/repl/data_replicator_test.cpp | 2 +- src/mongo/db/repl/elect_cmd_runner_test.cpp | 6 +- src/mongo/db/repl/fetcher_test.cpp | 2 +- src/mongo/db/repl/freshness_checker.cpp | 2 +- src/mongo/db/repl/freshness_checker_test.cpp | 114 +++---- src/mongo/db/repl/heartbeat_response_action.cpp | 6 +- src/mongo/db/repl/is_master_response.cpp | 2 +- src/mongo/db/repl/master_slave.cpp | 4 +- src/mongo/db/repl/member_config.cpp | 4 +- src/mongo/db/repl/member_config_test.cpp | 14 +- src/mongo/db/repl/member_heartbeat_data.cpp | 9 +- src/mongo/db/repl/network_interface_impl.cpp | 10 +- src/mongo/db/repl/network_interface_mock.cpp | 7 +- src/mongo/db/repl/oplog.cpp | 2 +- src/mongo/db/repl/oplogreader.cpp | 10 +- src/mongo/db/repl/read_after_optime_args_test.cpp | 8 +- src/mongo/db/repl/read_after_optime_response.cpp | 11 +- src/mongo/db/repl/read_after_optime_response.h | 10 +- .../db/repl/read_after_optime_response_test.cpp | 4 +- src/mongo/db/repl/repl_set_heartbeat_response.cpp | 7 +- .../db/repl/repl_set_heartbeat_response_test.cpp | 28 +- src/mongo/db/repl/repl_set_html_summary.cpp | 7 +- src/mongo/db/repl/replica_set_config.cpp | 4 +- src/mongo/db/repl/replica_set_config.h | 2 +- src/mongo/db/repl/replica_set_config_test.cpp | 6 +- src/mongo/db/repl/replication_coordinator.h | 4 +- src/mongo/db/repl/replication_coordinator_impl.cpp | 41 ++- .../db/repl/replication_coordinator_impl_elect.cpp | 6 +- .../replication_coordinator_impl_elect_test.cpp | 5 +- ...replication_coordinator_impl_heartbeat_test.cpp | 12 +- .../replication_coordinator_impl_reconfig_test.cpp | 4 +- .../db/repl/replication_coordinator_impl_test.cpp | 32 +- .../repl/replication_coordinator_test_fixture.cpp | 4 +- src/mongo/db/repl/replication_executor.cpp | 7 +- src/mongo/db/repl/replication_executor.h | 2 - src/mongo/db/repl/replication_executor_test.cpp | 18 +- src/mongo/db/repl/replication_info.cpp | 5 +- src/mongo/db/repl/replset_commands.cpp | 4 +- src/mongo/db/repl/reporter_test.cpp | 2 +- src/mongo/db/repl/rs_initialsync.cpp | 2 +- src/mongo/db/repl/scatter_gather_test.cpp | 33 +- src/mongo/db/repl/sync_source_feedback.cpp | 6 +- src/mongo/db/repl/sync_tail.cpp | 6 +- src/mongo/db/repl/topology_coordinator_impl.cpp | 87 +++--- src/mongo/db/repl/topology_coordinator_impl.h | 3 +- .../db/repl/topology_coordinator_impl_test.cpp | 299 +++++++++--------- src/mongo/db/stats/range_deleter_server_status.cpp | 6 +- src/mongo/db/storage/key_string.cpp | 4 +- src/mongo/db/storage/key_string_test.cpp | 4 +- src/mongo/db/storage/mmap_v1/btree/key.cpp | 9 +- src/mongo/db/storage/mmap_v1/data_file_sync.cpp | 2 +- src/mongo/db/storage/mmap_v1/dur.cpp | 3 +- src/mongo/db/ttl.cpp | 7 +- src/mongo/db/write_concern.cpp | 4 +- src/mongo/dbtests/config_upgrade_tests.cpp | 2 +- src/mongo/dbtests/expressiontests.cpp | 6 +- src/mongo/dbtests/jsobjtests.cpp | 52 ++-- src/mongo/dbtests/jsontests.cpp | 37 +-- src/mongo/dbtests/jstests.cpp | 14 +- src/mongo/dbtests/merge_chunk_tests.cpp | 2 +- src/mongo/dbtests/mock/mock_replica_set.cpp | 4 +- src/mongo/dbtests/querytests.cpp | 8 +- src/mongo/dbtests/repltests.cpp | 4 +- src/mongo/logger/log_test.cpp | 10 +- src/mongo/logger/logstream_builder.cpp | 2 +- src/mongo/logger/logstream_builder.h | 7 + src/mongo/logger/message_event.h | 2 +- .../s/catalog/legacy/catalog_manager_legacy.cpp | 2 +- .../s/catalog/legacy/cluster_client_internal.cpp | 15 +- src/mongo/s/catalog/legacy/distlock.cpp | 13 +- src/mongo/s/catalog/legacy/distlock.h | 4 +- .../s/catalog/legacy/legacy_dist_lock_pinger.cpp | 10 +- .../s/catalog/legacy/legacy_dist_lock_pinger.h | 10 +- src/mongo/s/catalog/type_actionlog.cpp | 2 +- src/mongo/s/catalog/type_changelog.cpp | 2 +- src/mongo/s/catalog/type_changelog_test.cpp | 16 +- src/mongo/s/catalog/type_chunk_test.cpp | 12 +- src/mongo/s/catalog/type_collection.cpp | 4 +- src/mongo/s/catalog/type_collection_test.cpp | 32 +- src/mongo/s/chunk_version.h | 2 +- src/mongo/s/client/multi_host_query.cpp | 5 +- src/mongo/s/client/multi_host_query_test.cpp | 4 +- src/mongo/s/collection_metadata_test.cpp | 64 ++-- src/mongo/s/config.cpp | 6 +- src/mongo/s/metadata_loader_test.cpp | 18 +- src/mongo/s/type_lockpings.cpp | 2 +- src/mongo/s/type_lockpings_test.cpp | 6 +- src/mongo/s/type_mongos.cpp | 2 +- src/mongo/s/type_mongos_test.cpp | 14 +- src/mongo/s/version_manager.cpp | 2 +- .../s/write_ops/batched_command_response_test.cpp | 2 +- src/mongo/scripting/engine.cpp | 5 +- src/mongo/scripting/engine_v8-3.25.cpp | 2 +- src/mongo/scripting/engine_v8.cpp | 6 +- src/mongo/unittest/unittest_helpers.h | 2 +- src/mongo/util/net/ssl_expiration.cpp | 25 +- src/mongo/util/net/ssl_manager.cpp | 2 +- src/mongo/util/signal_handlers_synchronous.cpp | 2 +- src/mongo/util/time_support.cpp | 102 +++++-- src/mongo/util/time_support.h | 119 +++++++- src/mongo/util/time_support_test.cpp | 334 +++++++++++---------- 131 files changed, 1261 insertions(+), 1058 deletions(-) diff --git a/src/mongo/bson/bson_validate_test.cpp b/src/mongo/bson/bson_validate_test.cpp index 99b54f12254..77dfc11e15c 100644 --- a/src/mongo/bson/bson_validate_test.cpp +++ b/src/mongo/bson/bson_validate_test.cpp @@ -157,7 +157,7 @@ namespace { "eight" << BSONDBRef( "rrr", OID( "01234567890123456789aaaa" ) ) << "_id" << OID( "deadbeefdeadbeefdeadbeef" ) << "nine" << BSONBinData( "\x69\xb7", 2, BinDataGeneral ) << - "ten" << Date_t( 44 ) << + "ten" << Date_t::fromMillisSinceEpoch( 44 ) << "eleven" << BSONRegEx( "foooooo", "i" ) ); int32_t fuzzFrequencies[] = { 2, 10, 20, 100, 1000 }; diff --git a/src/mongo/bson/bsonelement.cpp b/src/mongo/bson/bsonelement.cpp index 49f45c44a12..86efd0f7e27 100644 --- a/src/mongo/bson/bsonelement.cpp +++ b/src/mongo/bson/bsonelement.cpp @@ -201,7 +201,7 @@ namespace mongo { s << "\"" << dateToISOStringLocal(date()) << "\""; } else { - s << "{ \"$numberLong\" : \"" << static_cast(d.millis) << "\" }"; + s << "{ \"$numberLong\" : \"" << d.toMillisSinceEpoch() << "\" }"; } s << " }"; } @@ -221,7 +221,7 @@ namespace mongo { else { // FIXME: This is not parseable by the shell, since it may not fit in a // float - s << d.millis; + s << d.toMillisSinceEpoch(); } } else { @@ -266,10 +266,14 @@ namespace mongo { case bsonTimestamp: if ( format == TenGen ) { - s << "Timestamp( " << ( timestampTime() / 1000 ) << ", " << timestampInc() << " )"; + s << "Timestamp( " + << durationCount(timestampTime().toDurationSinceEpoch()) + << ", " << timestampInc() << " )"; } else { - s << "{ \"$timestamp\" : { \"t\" : " << ( timestampTime() / 1000 ) << ", \"i\" : " << timestampInc() << " } }"; + s << "{ \"$timestamp\" : { \"t\" : " + << durationCount(timestampTime().toDurationSinceEpoch()) + << ", \"i\" : " << timestampInc() << " } }"; } break; @@ -616,7 +620,7 @@ namespace mongo { s << "EOO"; break; case mongo::Date: - s << "new Date(" << (long long) date() << ')'; + s << "new Date(" << date().toMillisSinceEpoch() << ')'; break; case RegEx: { s << "/" << regex() << '/'; @@ -701,7 +705,7 @@ namespace mongo { } break; case bsonTimestamp: - s << "Timestamp " << timestampTime() << "|" << timestampInc(); + s << "Timestamp " << timestampTime().toMillisSinceEpoch() << "|" << timestampInc(); break; default: s << "?type=" << type(); @@ -852,8 +856,8 @@ namespace mongo { case Date: // Signed comparisons for Dates. { - long long a = (long long) l.Date().millis; - long long b = (long long) r.Date().millis; + const Date_t a = l.Date(); + const Date_t b = r.Date(); if( a < b ) return -1; return a == b ? 0 : 1; diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h index c4fd19c77b4..25d9e895b49 100644 --- a/src/mongo/bson/bsonelement.h +++ b/src/mongo/bson/bsonelement.h @@ -211,7 +211,8 @@ namespace mongo { @see Bool(), trueValue() */ Date_t date() const { - return Date_t(ConstDataView(value()).read>()); + return Date_t::fromMillisSinceEpoch( + ConstDataView(value()).read>()); } /** Convert the value to boolean, regardless of its type, in a javascript-like fashion @@ -464,7 +465,7 @@ namespace mongo { Date_t timestampTime() const { unsigned long long t = ConstDataView(value() + 4).read>(); - return t * 1000; + return Date_t::fromMillisSinceEpoch(t * 1000); } unsigned int timestampInc() const { return ConstDataView(value()).read>(); diff --git a/src/mongo/bson/bsonobjbuilder.cpp b/src/mongo/bson/bsonobjbuilder.cpp index d0fd2665ff3..a9878b28adc 100644 --- a/src/mongo/bson/bsonobjbuilder.cpp +++ b/src/mongo/bson/bsonobjbuilder.cpp @@ -109,7 +109,9 @@ namespace mongo { case String: appendMinForType( fieldName, Object ); return; case Date: - appendDate( fieldName , std::numeric_limits::max() ); return; + appendDate(fieldName, + Date_t::fromMillisSinceEpoch(std::numeric_limits::max())); + return; case bsonTimestamp: append( fieldName , Timestamp::max() ); return; case Undefined: // shared with EOO @@ -196,16 +198,9 @@ namespace mongo { } BSONObjBuilder& BSONObjBuilder::appendDate(StringData fieldName, Date_t dt) { - /* easy to pass a time_t to this and get a bad result. thus this warning. */ - if ( kDebugBuild && dt > 0 && dt <= 0xffffffff ) { - static int n; - if( n++ == 0 ) - log() << "DEV WARNING appendDate() called with a tiny (but nonzero) date" << std::endl; - } - _b.appendNum((char) Date); _b.appendStr(fieldName); - _b.appendNum(dt); + _b.appendNum(dt.toMillisSinceEpoch()); return *this; } diff --git a/src/mongo/bson/json.cpp b/src/mongo/bson/json.cpp index 2b13e318e44..3bf5c531cd0 100644 --- a/src/mongo/bson/json.cpp +++ b/src/mongo/bson/json.cpp @@ -471,12 +471,12 @@ namespace mongo { if (!ret.isOK()) { return ret; } - date = numberLong; + date = Date_t::fromMillisSinceEpoch(numberLong); } else { // SERVER-11920: We should use parseNumberFromString here, but that function requires // that we know ahead of time where the number ends, which is not currently the case. - date = static_cast(strtoll(_input, &endptr, 10)); + date = Date_t::fromMillisSinceEpoch(strtoll(_input, &endptr, 10)); if (_input == endptr) { return parseError("Date expecting integer milliseconds"); } @@ -487,7 +487,8 @@ namespace mongo { // SERVER-11920: We should use parseNumberFromString here, but that function // requires that we know ahead of time where the number ends, which is not currently // the case. - date = strtoull(_input, &endptr, 10); + date = Date_t::fromMillisSinceEpoch( + static_cast(strtoull(_input, &endptr, 10))); if (errno == ERANGE) { return parseError("Date milliseconds overflow"); } @@ -753,7 +754,7 @@ namespace mongo { char* endptr; // SERVER-11920: We should use parseNumberFromString here, but that function requires that // we know ahead of time where the number ends, which is not currently the case. - Date_t date = static_cast(strtoll(_input, &endptr, 10)); + Date_t date = Date_t::fromMillisSinceEpoch(strtoll(_input, &endptr, 10)); if (_input == endptr) { return parseError("Date expecting integer milliseconds"); } @@ -763,7 +764,8 @@ namespace mongo { errno = 0; // SERVER-11920: We should use parseNumberFromString here, but that function requires // that we know ahead of time where the number ends, which is not currently the case. - date = strtoull(_input, &endptr, 10); + date = Date_t::fromMillisSinceEpoch( + static_cast(strtoull(_input, &endptr, 10))); if (errno == ERANGE) { return parseError("Date milliseconds overflow"); } diff --git a/src/mongo/bson/mutable/mutable_bson_test.cpp b/src/mongo/bson/mutable/mutable_bson_test.cpp index 47cca65fb30..a7998173631 100644 --- a/src/mongo/bson/mutable/mutable_bson_test.cpp +++ b/src/mongo/bson/mutable/mutable_bson_test.cpp @@ -556,7 +556,7 @@ namespace { t0.setValueTimestamp(mongo::Timestamp()); ASSERT_EQUALS(mongo::bsonTimestamp, t0.getType()); - t0.setValueDate(12345LL); + t0.setValueDate(mongo::Date_t::fromMillisSinceEpoch(12345LL)); ASSERT_EQUALS(mongo::Date, t0.getType()); t0.setValueDouble(123.45); @@ -2740,7 +2740,7 @@ namespace { } TEST(DocumentInPlace, DateLifecycle) { - mongo::BSONObj obj(BSON("x" << mongo::Date_t(1000))); + mongo::BSONObj obj(BSON("x" << mongo::Date_t::fromMillisSinceEpoch(1000))); mmb::Document doc(obj, mmb::Document::kInPlaceEnabled); mmb::Element x = doc.root().leftChild(); @@ -2748,13 +2748,13 @@ namespace { mmb::DamageVector damages; const char* source = NULL; - x.setValueDate(mongo::Date_t(20000)); + x.setValueDate(mongo::Date_t::fromMillisSinceEpoch(20000)); ASSERT_TRUE(doc.getInPlaceUpdates(&damages, &source)); ASSERT_EQUALS(1U, damages.size()); apply(&obj, damages, source); ASSERT_TRUE(x.hasValue()); ASSERT_TRUE(x.isType(mongo::Date)); - ASSERT_EQUALS(mongo::Date_t(20000), x.getValueDate()); + ASSERT_EQUALS(mongo::Date_t::fromMillisSinceEpoch(20000), x.getValueDate()); // TODO: When in-place updates for leaf elements is implemented, add tests here. } @@ -2788,7 +2788,7 @@ namespace { } TEST(DocumentInPlace, TimestampLifecycle) { - mongo::BSONObj obj(BSON("x" << mongo::Timestamp(mongo::Date_t(1000)))); + mongo::BSONObj obj(BSON("x" << mongo::Timestamp(mongo::Date_t::fromMillisSinceEpoch(1000)))); mmb::Document doc(obj, mmb::Document::kInPlaceEnabled); mmb::Element x = doc.root().leftChild(); @@ -2796,13 +2796,13 @@ namespace { mmb::DamageVector damages; const char* source = NULL; - x.setValueTimestamp(mongo::Timestamp(mongo::Date_t(20000))); + x.setValueTimestamp(mongo::Timestamp(mongo::Date_t::fromMillisSinceEpoch(20000))); ASSERT_TRUE(doc.getInPlaceUpdates(&damages, &source)); ASSERT_EQUALS(1U, damages.size()); apply(&obj, damages, source); ASSERT_TRUE(x.hasValue()); ASSERT_TRUE(x.isType(mongo::bsonTimestamp)); - ASSERT_TRUE(mongo::Timestamp(mongo::Date_t(20000)) == x.getValueTimestamp()); + ASSERT_TRUE(mongo::Timestamp(20000U) == x.getValueTimestamp()); // TODO: When in-place updates for leaf elements is implemented, add tests here. } diff --git a/src/mongo/bson/oid.cpp b/src/mongo/bson/oid.cpp index 853299d5bfe..e9c6b87eb3a 100644 --- a/src/mongo/bson/oid.cpp +++ b/src/mongo/bson/oid.cpp @@ -151,7 +151,7 @@ namespace { } void OID::init(Date_t date, bool max) { - setTimestamp(uint32_t(date / 1000)); + setTimestamp(uint32_t(date.toMillisSinceEpoch() / 1000)); uint64_t rest = max ? std::numeric_limits::max() : 0u; std::memcpy(_view().view(kInstanceUniqueOffset), &rest, kInstanceUniqueSize + kIncrementSize); diff --git a/src/mongo/bson/oid.h b/src/mongo/bson/oid.h index df29065bb5e..a4ae3269d5f 100644 --- a/src/mongo/bson/oid.h +++ b/src/mongo/bson/oid.h @@ -140,7 +140,7 @@ namespace mongo { void init( Date_t date, bool max=false ); time_t asTimeT() const; - Date_t asDateT() const { return asTimeT() * 1000LL; } + Date_t asDateT() const { return Date_t::fromMillisSinceEpoch(asTimeT() * 1000LL); } // True iff the OID is not empty bool isSet() const { diff --git a/src/mongo/bson/timestamp.h b/src/mongo/bson/timestamp.h index b223b5deb50..3a92110edcb 100644 --- a/src/mongo/bson/timestamp.h +++ b/src/mongo/bson/timestamp.h @@ -30,51 +30,56 @@ #include "mongo/base/data_view.h" #include "mongo/bson/util/builder.h" #include "mongo/util/assert_util.h" +#include "mongo/util/time_support.h" namespace mongo { - /* Timestamp: A combination of current second plus an ordinal value. + /** + * Timestamp: A combination of a count of seconds since the POSIX epoch plus an ordinal value. */ -#pragma pack(4) class Timestamp { - unsigned i; // ordinal comes first so we can do a single 64 bit compare on little endian - unsigned secs; public: + // Maximum Timestamp value. + static Timestamp max(); + + /** + * DEPRECATED Constructor that builds a Timestamp from a Date_t by using the + * high-order 4 bytes of "date" for the "secs" field and the low-order 4 bytes + * for the "i" field. + */ + explicit Timestamp(Date_t date) : Timestamp(date.toULL()) {} + + /** + * DEPRECATED Constructor that builds a Timestamp from a 64-bit unsigned integer by using + * the high-order 4 bytes of "v" for the "secs" field and the low-order 4 bytes for the "i" + * field. + */ + explicit Timestamp(unsigned long long v) : Timestamp(v >> 32, v) {} + + Timestamp(Seconds s, unsigned increment) : Timestamp(s.count(), increment) {} + + Timestamp(unsigned a, unsigned b) : i(b), secs(a) { + dassert(secs <= std::numeric_limits::max()); + } + + Timestamp() = default; + unsigned getSecs() const { return secs; } + unsigned getInc() const { return i; } - Timestamp(Date_t date) { - reinterpret_cast(*this) = date.millis; - dassert( (int)secs >= 0 ); - } - - Timestamp(unsigned a, unsigned b) { - secs = a; - i = b; - dassert( (int)secs >= 0 ); - } - Timestamp( const Timestamp& other ) { - secs = other.secs; - i = other.i; - dassert( (int)secs >= 0 ); - } - Timestamp() { - secs = 0; - i = 0; - } - - // Maximum Timestamp value. - static Timestamp max(); - unsigned long long asULL() const { - return reinterpret_cast(&i)[0]; + unsigned long long result = secs; + result <<= 32; + result |= i; + return result; } long long asLL() const { - return reinterpret_cast(&i)[0]; + return static_cast(asULL()); } bool isNull() const { return secs == 0; } @@ -86,31 +91,33 @@ namespace mongo { std::string toString() const; bool operator==(const Timestamp& r) const { - return i == r.i && secs == r.secs; + return tie() == r.tie(); } bool operator!=(const Timestamp& r) const { - return !(*this == r); + return tie() != r.tie(); } bool operator<(const Timestamp& r) const { - if ( secs != r.secs ) - return secs < r.secs; - return i < r.i; + return tie() < r.tie(); } bool operator<=(const Timestamp& r) const { - return *this < r || *this == r; + return tie() <= r.tie(); } bool operator>(const Timestamp& r) const { - return !(*this <= r); + return tie() > r.tie(); } bool operator>=(const Timestamp& r) const { - return !(*this < r); + return tie() >= r.tie(); } // Append the BSON representation of this Timestamp to the given BufBuilder with the given // name. This lives here because Timestamp manages its own serialization format. void append(BufBuilder& builder, const StringData& fieldName) const; + private: + std::tuple tie() const { return std::tie(secs, i); } + + unsigned i = 0; + unsigned secs = 0; }; -#pragma pack() } // namespace mongo diff --git a/src/mongo/client/connection_pool.cpp b/src/mongo/client/connection_pool.cpp index dda86a0675c..ed994b25c33 100644 --- a/src/mongo/client/connection_pool.cpp +++ b/src/mongo/client/connection_pool.cpp @@ -39,22 +39,17 @@ namespace mongo { namespace { - const unsigned long long kNeverTooStale = std::numeric_limits::max(); + const Date_t kNeverTooStale = Date_t::max(); - // 5 Minutes (Note: Must be larger than kMaxConnectionAge below) - const long long kCleanUpInterval = 5 * 60 * 1000; + const Minutes kCleanUpInterval(5); // Note: Must be larger than kMaxConnectionAge below) const Seconds kMaxConnectionAge(30); } // namespace - ConnectionPool::ConnectionPool(int messagingPortTags) - : _messagingPortTags(messagingPortTags), - _lastCleanUpTime(0ULL) { - - } + ConnectionPool::ConnectionPool(int messagingPortTags) : _messagingPortTags(messagingPortTags) {} ConnectionPool::~ConnectionPool() { - cleanUpOlderThan(Date_t(~0ULL)); + cleanUpOlderThan(Date_t::max()); invariant(_connections.empty()); invariant(_inUseConnections.empty()); @@ -91,8 +86,7 @@ namespace { } bool ConnectionPool::_shouldKeepConnection(Date_t now, const ConnectionInfo& connInfo) const { - const Date_t expirationDate = - connInfo.creationDate + kMaxConnectionAge.total_milliseconds(); + const Date_t expirationDate = connInfo.creationDate + kMaxConnectionAge; if (expirationDate <= now) { return false; } @@ -120,7 +114,7 @@ namespace { ConnectionList connList = _connections.find(itr->first)->second; _cleanUpOlderThan_inlock(now, &connList); invariant(connList.empty()); - itr->second = Date_t(kNeverTooStale); + itr->second = kNeverTooStale; } } @@ -144,7 +138,7 @@ namespace { _cleanUpOlderThan_inlock(now, &hostConns->second); if (hostConns->second.empty()) { // prevent host from causing unnecessary cleanups - _lastUsedHosts[hostConns->first] = Date_t(kNeverTooStale); + _lastUsedHosts[hostConns->first] = kNeverTooStale; break; } @@ -157,9 +151,9 @@ namespace { try { if (candidate->conn->isStillConnected()) { // setSoTimeout takes a double representing the number of seconds for send and - // receive timeouts. Thus, we must take total_milliseconds() and divide by + // receive timeouts. Thus, we must take count() and divide by // 1000.0 to get the number of seconds with a fractional part. - candidate->conn->setSoTimeout(timeout.total_milliseconds() / 1000.0); + candidate->conn->setSoTimeout(timeout.count() / 1000.0); return candidate; } } @@ -178,9 +172,9 @@ namespace { std::auto_ptr conn(new DBClientConnection); // setSoTimeout takes a double representing the number of seconds for send and receive - // timeouts. Thus, we must take total_milliseconds() and divide by 1000.0 to get the number + // timeouts. Thus, we must take count() and divide by 1000.0 to get the number // of seconds with a fractional part. - conn->setSoTimeout(timeout.total_milliseconds() / 1000.0); + conn->setSoTimeout(timeout.count() / 1000.0); std::string errmsg; uassert(28640, str::stream() << "Failed attempt to connect to " diff --git a/src/mongo/client/connection_pool.h b/src/mongo/client/connection_pool.h index 2d31affcc00..daf36d87337 100644 --- a/src/mongo/client/connection_pool.h +++ b/src/mongo/client/connection_pool.h @@ -52,7 +52,7 @@ namespace mongo { * Information about a connection in the pool. */ struct ConnectionInfo { - ConnectionInfo() : conn(NULL), creationDate(0ULL) {} + ConnectionInfo() : conn(NULL) {} ConnectionInfo(DBClientConnection* theConn, Date_t date) : conn(theConn), creationDate(date) {} diff --git a/src/mongo/client/remote_command_executor.cpp b/src/mongo/client/remote_command_executor.cpp index e424c557173..0e8c535e38c 100644 --- a/src/mongo/client/remote_command_executor.cpp +++ b/src/mongo/client/remote_command_executor.cpp @@ -34,9 +34,8 @@ namespace mongo { - const Milliseconds RemoteCommandRequest::kNoTimeout(-1); - const Date_t RemoteCommandRequest::kNoExpirationDate(-1); - + const Milliseconds RemoteCommandRequest::kNoTimeout{-1}; + const Date_t RemoteCommandRequest::kNoExpirationDate{Date_t::max()}; std::string RemoteCommandRequest::toString() const { str::stream out; diff --git a/src/mongo/client/remote_command_executor.h b/src/mongo/client/remote_command_executor.h index 8b326589a90..f11f4d8bc4a 100644 --- a/src/mongo/client/remote_command_executor.h +++ b/src/mongo/client/remote_command_executor.h @@ -39,7 +39,6 @@ namespace mongo { template class StatusWith; - /** * Type of object describing a command to execute against a remote MongoDB node. */ diff --git a/src/mongo/client/remote_command_executor_impl.cpp b/src/mongo/client/remote_command_executor_impl.cpp index c39c53bfe81..6555f830a7e 100644 --- a/src/mongo/client/remote_command_executor_impl.cpp +++ b/src/mongo/client/remote_command_executor_impl.cpp @@ -42,29 +42,22 @@ namespace mongo { namespace { /** - * Calculates the timeout for a network operation expiring at "expDate", given that it is now - * "nowDate". + * Calculates the timeout for a network operation expiring at "expDate", given + * that it is now "nowDate". * - * Returns 0 to indicate no expiration date, a number of milliseconds until "expDate", or + * Returns 0ms to indicate no expiration date, a number of milliseconds until "expDate", or * ErrorCodes::ExceededTimeLimit if "expDate" is not later than "nowDate". - * - * TODO: Change return type to StatusWith once Milliseconds supports default - * construction or StatusWith supports not constructing T when the result is a non-OK - * status. */ - StatusWith getTimeoutMillis(const Date_t expDate, const Date_t nowDate) { + StatusWith getTimeoutMillis(const Date_t expDate, const Date_t nowDate) { if (expDate == RemoteCommandRequest::kNoExpirationDate) { - return StatusWith(0); + return Milliseconds(0); } - if (expDate <= nowDate) { - return StatusWith( - ErrorCodes::ExceededTimeLimit, - str::stream() << "Went to run command, but it was too late. " - "Expiration was set to " << dateToISOStringUTC(expDate)); + return {ErrorCodes::ExceededTimeLimit, + str::stream() << "Went to run command, but it was too late. " + "Expiration was set to " << dateToISOStringUTC(expDate)}; } - - return StatusWith(expDate.asInt64() - nowDate.asInt64()); + return expDate - nowDate; } /** @@ -220,9 +213,8 @@ namespace { try { BSONObj output; - const Date_t requestStartDate = curTimeMillis64(); - StatusWith timeoutMillis = getTimeoutMillis(request.expirationDate, - requestStartDate); + const Date_t requestStartDate = Date_t::now(); + const auto timeoutMillis = getTimeoutMillis(request.expirationDate, requestStartDate); if (!timeoutMillis.isOK()) { return StatusWith(timeoutMillis.getStatus()); } @@ -230,7 +222,7 @@ namespace { ConnectionPool::ConnectionPtr conn(&_connPool, request.target, requestStartDate, - Milliseconds(timeoutMillis.getValue())); + timeoutMillis.getValue()); bool ok = conn.get()->runCommand(request.dbname, request.cmdObj, output); @@ -260,7 +252,7 @@ namespace { } } - const Date_t requestFinishDate = curTimeMillis64(); + const Date_t requestFinishDate = Date_t::now(); conn.done(requestFinishDate); return StatusWith( diff --git a/src/mongo/db/auth/user_cache_invalidator_job.cpp b/src/mongo/db/auth/user_cache_invalidator_job.cpp index 7669d0201bc..7c4494adc2b 100644 --- a/src/mongo/db/auth/user_cache_invalidator_job.cpp +++ b/src/mongo/db/auth/user_cache_invalidator_job.cpp @@ -134,19 +134,16 @@ namespace { void UserCacheInvalidator::run() { Client::initThread("UserCacheInvalidator"); - lastInvalidationTime = Date_t(curTimeMillis64()); + lastInvalidationTime = Date_t::now(); while (true) { boost::unique_lock lock(invalidationIntervalMutex); - Date_t sleepUntil = Date_t( - lastInvalidationTime.millis + userCacheInvalidationIntervalSecs * 1000); - Date_t now(curTimeMillis64()); - while (now.millis < sleepUntil.millis) { - invalidationIntervalChangedCondition.timed_wait(lock, - Milliseconds(sleepUntil - now)); - sleepUntil = Date_t( - lastInvalidationTime.millis + (userCacheInvalidationIntervalSecs * 1000)); - now = Date_t(curTimeMillis64()); + Date_t sleepUntil = lastInvalidationTime + Seconds(userCacheInvalidationIntervalSecs); + Date_t now = Date_t::now(); + while (now < sleepUntil) { + invalidationIntervalChangedCondition.wait_for(lock, sleepUntil - now); + sleepUntil = lastInvalidationTime + Seconds(userCacheInvalidationIntervalSecs); + now = Date_t::now(); } lastInvalidationTime = now; lock.unlock(); diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp index d5d5654fbc5..b2047138669 100644 --- a/src/mongo/db/concurrency/lock_state.cpp +++ b/src/mongo/db/concurrency/lock_state.cpp @@ -229,7 +229,7 @@ namespace { LockResult CondVarLockGrantNotification::wait(unsigned timeoutMs) { boost::unique_lock lock(_mutex); while (_result == LOCK_INVALID) { - if (!_cond.timed_wait(lock, Milliseconds(timeoutMs))) { + if (boost::cv_status::timeout == _cond.wait_for(lock, Milliseconds(timeoutMs))) { // Timeout return LOCK_TIMEOUT; } diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 1b4963fa4b0..fa360169fa0 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -205,7 +205,7 @@ namespace mongo { toLog.append( "hostname", getHostNameCached() ); toLog.appendTimeT( "startTime", time(0) ); - toLog.append( "startTimeLocal", dateToCtimeString(curTimeMillis64()) ); + toLog.append( "startTimeLocal", dateToCtimeString(Date_t::now()) ); toLog.append("cmdLine", serverGlobalParams.parsedOpts); toLog.append( "pid", ProcessId::getCurrent().asLongLong() ); diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index 1c751d906a4..ab1b6463f98 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -136,8 +136,8 @@ namespace mongo { Status status = repl::getGlobalReplicationCoordinator()->stepDown( txn, force, - repl::ReplicationCoordinator::Milliseconds(timeoutSecs * 1000), - repl::ReplicationCoordinator::Milliseconds(120 * 1000)); + Seconds(timeoutSecs), + Seconds(120)); if (!status.isOK() && status.code() != ErrorCodes::NotMaster) { // ignore not master return appendCommandStatus(result, status); } diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp index 1d7cae4632c..24be8b1f4f3 100644 --- a/src/mongo/db/dbhelpers.cpp +++ b/src/mongo/db/dbhelpers.cpp @@ -355,7 +355,7 @@ namespace mongo { long long numDeleted = 0; - long long millisWaitingForReplication = 0; + Milliseconds millisWaitingForReplication{0}; while ( 1 ) { // Scoping for write lock. @@ -468,14 +468,14 @@ namespace mongo { else { massertStatusOK(replStatus.status); } - millisWaitingForReplication += replStatus.duration.total_milliseconds(); + millisWaitingForReplication += replStatus.duration; } } if (writeConcern.shouldWaitForOtherNodes()) log(LogComponent::kSharding) << "Helpers::removeRangeUnlocked time spent waiting for replication: " - << millisWaitingForReplication << "ms" << endl; + << durationCount(millisWaitingForReplication) << "ms" << endl; MONGO_LOG_COMPONENT(1, LogComponent::kSharding) << "end removal of " << min << " to " << max << " in " << ns diff --git a/src/mongo/db/field_parser_test.cpp b/src/mongo/db/field_parser_test.cpp index 902b6548e64..184d883a2b4 100644 --- a/src/mongo/db/field_parser_test.cpp +++ b/src/mongo/db/field_parser_test.cpp @@ -72,7 +72,7 @@ namespace { valBool = true; valArray = BSON_ARRAY(1 << 2 << 3); valObj = BSON("a" << 1); - valDate = 1ULL; + valDate = Date_t::fromMillisSinceEpoch(1); valString = "a string"; valOID = OID::gen(); valLong = 1LL; @@ -132,13 +132,13 @@ namespace { } TEST_F(ExtractionFixture, GetDate) { - BSONField notThere("otherDate", 99ULL); + BSONField notThere("otherDate", Date_t::fromMillisSinceEpoch(99)); BSONField wrongType(aString.name()); Date_t val; ASSERT_TRUE(FieldParser::extract(doc, aDate, &val)); ASSERT_EQUALS(val, valDate); ASSERT_TRUE(FieldParser::extract(doc, notThere, &val)); - ASSERT_EQUALS(val, 99ULL); + ASSERT_EQUALS(val, Date_t::fromMillisSinceEpoch(99)); ASSERT_FALSE(FieldParser::extract(doc, wrongType, &val)); } diff --git a/src/mongo/db/hasher_test.cpp b/src/mongo/db/hasher_test.cpp index 02351127c48..0966bfbf3f8 100644 --- a/src/mongo/db/hasher_test.cpp +++ b/src/mongo/db/hasher_test.cpp @@ -343,12 +343,12 @@ namespace { BSONObjBuilder builder1; BSONObjBuilder builder2; - BSONObj o = BSON( "check" << Date_t( 0x5566778811223344LL ) ); + BSONObj o = BSON( "check" << Date_t::fromMillisSinceEpoch( 0x5566778811223344LL ) ); ASSERT_EQUALS( hashIt( o ), 4476222765095560467LL ); o = builder1.append( "check", Timestamp(0x55667788LL, 0x11223344LL) ).obj(); ASSERT_EQUALS( hashIt( o ), 4873046866288452390LL ); - o = BSON( "check" << Date_t( 0 ) ); + o = BSON( "check" << Date_t() ); ASSERT_EQUALS( hashIt( o ), -1178696894582842035LL ); o = builder2.appendTimestamp( "check", 0 ).obj(); ASSERT_EQUALS( hashIt( o ), -7867208682377458672LL ); diff --git a/src/mongo/db/pipeline/document_value_test.cpp b/src/mongo/db/pipeline/document_value_test.cpp index 0deb17f7341..0afffb5b639 100644 --- a/src/mongo/db/pipeline/document_value_test.cpp +++ b/src/mongo/db/pipeline/document_value_test.cpp @@ -525,7 +525,7 @@ namespace DocumentTests { class Date { public: void run() { - Value value = Value(Date_t(999)); + Value value = Value(Date_t::fromMillisSinceEpoch(999)); ASSERT_EQUALS( 999, value.getDate() ); ASSERT_EQUALS( mongo::Date, value.getType() ); assertRoundTrips( value ); @@ -807,7 +807,7 @@ namespace DocumentTests { /** Coerce Date(0) to bool. */ class DateToBool : public ToBoolTrue { - Value value() { return Value(Date_t(0)); } + Value value() { return Value(Date_t{}); } }; /** Coerce js literal regex to bool. */ @@ -1014,7 +1014,7 @@ namespace DocumentTests { /** Coerce date to date. */ class DateToDate : public ToDateBase { - Value value() { return Value(Date_t(888)); } + Value value() { return Value(Date_t::fromMillisSinceEpoch(888)); } long long expected() { return 888; } }; @@ -1083,7 +1083,7 @@ namespace DocumentTests { /** Coerce date to string. */ class DateToString : public ToStringBase { - Value value() { return Value(Date_t(1234567890LL*1000)); } + Value value() { return Value(Date_t::fromMillisSinceEpoch(1234567890LL*1000)); } string expected() { return "2009-02-13T23:31:30"; } // from js }; @@ -1120,7 +1120,7 @@ namespace DocumentTests { class DateToTimestamp { public: void run() { - ASSERT_THROWS( Value(Date_t(1010)).coerceToTimestamp(), + ASSERT_THROWS( Value(Date_t::fromMillisSinceEpoch(1010)).coerceToTimestamp(), UserException ); } }; @@ -1261,10 +1261,16 @@ namespace DocumentTests { assertComparison( 1, true, false ); // Date. - assertComparison( 0, Date_t( 555 ), Date_t( 555 ) ); - assertComparison( 1, Date_t( 555 ), Date_t( 554 ) ); + assertComparison( 0, + Date_t::fromMillisSinceEpoch( 555 ), + Date_t::fromMillisSinceEpoch( 555 ) ); + assertComparison( 1, + Date_t::fromMillisSinceEpoch( 555 ), + Date_t::fromMillisSinceEpoch( 554 ) ); // Negative date. - assertComparison( 1, Date_t( 0 ), Date_t( -1 ) ); + assertComparison( 1, + Date_t::fromMillisSinceEpoch( 0 ), + Date_t::fromMillisSinceEpoch( -1 ) ); // Regex. assertComparison( 0, fromjson( "{'':/a/}" ), fromjson( "{'':/a/}" ) ); @@ -1290,8 +1296,8 @@ namespace DocumentTests { assertComparison(-1, Value(vector()), Value(BSONBinData("", 0, MD5Type))); assertComparison(-1, Value(BSONBinData("", 0, MD5Type)), Value(mongo::OID())); assertComparison(-1, Value(mongo::OID()), Value(false)); - assertComparison(-1, Value(false), Value(Date_t(0))); - assertComparison(-1, Value(Date_t(0)), Value(Timestamp())); + assertComparison(-1, Value(false), Value(Date_t())); + assertComparison(-1, Value(Date_t()), Value(Timestamp())); assertComparison(-1, Value(Timestamp()), Value(BSONRegEx(""))); assertComparison(-1, Value(BSONRegEx("")), Value(BSONDBRef("", mongo::OID()))); assertComparison(-1, Value(BSONDBRef("", mongo::OID())), Value(BSONCode(""))); diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp index defc38d8c12..e8c121c2b04 100644 --- a/src/mongo/db/pipeline/expression.cpp +++ b/src/mongo/db/pipeline/expression.cpp @@ -422,7 +422,7 @@ namespace { if (haveDate) { if (totalType == NumberDouble) longTotal = static_cast(doubleTotal); - return Value(Date_t(longTotal)); + return Value(Date_t::fromMillisSinceEpoch(longTotal)); } else if (totalType == NumberLong) { return Value(longTotal); @@ -2548,7 +2548,7 @@ namespace { } else if (rhs.numeric()) { long long millisSinceEpoch = lhs.getDate() - rhs.coerceToLong(); - return Value(Date_t(millisSinceEpoch)); + return Value(Date_t::fromMillisSinceEpoch(millisSinceEpoch)); } else { uasserted(16613, str::stream() << "cant $subtract a " diff --git a/src/mongo/db/pipeline/value.cpp b/src/mongo/db/pipeline/value.cpp index b156d290613..c949601ac4d 100644 --- a/src/mongo/db/pipeline/value.cpp +++ b/src/mongo/db/pipeline/value.cpp @@ -186,8 +186,7 @@ namespace mongo { break; case Date: - // this is really signed but typed as unsigned for historical reasons - _storage.dateValue = static_cast(elem.date().millis); + _storage.dateValue = elem.date().toMillisSinceEpoch(); break; case RegEx: { @@ -288,7 +287,7 @@ namespace mongo { case NumberDouble: return builder << val.getDouble(); case String: return builder << val.getStringData(); case Bool: return builder << val.getBool(); - case Date: return builder << Date_t(val.getDate()); + case Date: return builder << Date_t::fromMillisSinceEpoch(val.getDate()); case bsonTimestamp: return builder << val.getTimestamp(); case Object: return builder << val.getDocument(); case Symbol: return builder << BSONSymbol(val.getStringData()); @@ -1018,7 +1017,7 @@ namespace mongo { case NumberLong: return Value(buf.read()); case NumberDouble: return Value(buf.read()); case Bool: return Value(bool(buf.read())); - case Date: return Value(Date_t(buf.read())); + case Date: return Value(Date_t::fromMillisSinceEpoch(buf.read())); case bsonTimestamp: return Value(buf.read()); // types that are like strings diff --git a/src/mongo/db/pipeline/value.h b/src/mongo/db/pipeline/value.h index 5324cc1b432..ecc66719d11 100644 --- a/src/mongo/db/pipeline/value.h +++ b/src/mongo/db/pipeline/value.h @@ -91,9 +91,7 @@ namespace mongo { explicit Value(const UndefinedLabeler&) : _storage(Undefined) {} // BSONUndefined explicit Value(const MinKeyLabeler&) : _storage(MinKey) {} // MINKEY explicit Value(const MaxKeyLabeler&) : _storage(MaxKey) {} // MAXKEY - explicit Value(const Date_t& date) - : _storage(Date, static_cast(date.millis)) // millis really signed - {} + explicit Value(const Date_t& date) : _storage(Date, date.toMillisSinceEpoch()) {} // TODO: add an unsafe version that can share storage with the BSONElement /// Deep-convert from BSONElement to Value @@ -317,7 +315,7 @@ namespace mongo { inline Timestamp Value::getTimestamp() const { verify(getType() == bsonTimestamp); - return Date_t(_storage.timestampValue); + return Timestamp(_storage.timestampValue); } inline const char* Value::getRegex() const { diff --git a/src/mongo/db/query/index_bounds_builder_test.cpp b/src/mongo/db/query/index_bounds_builder_test.cpp index 36aea6dca63..14db9b7a1f1 100644 --- a/src/mongo/db/query/index_bounds_builder_test.cpp +++ b/src/mongo/db/query/index_bounds_builder_test.cpp @@ -271,7 +271,7 @@ namespace { TEST(IndexBoundsBuilderTest, TranslateLtDate) { IndexEntry testIndex = IndexEntry(BSONObj()); - BSONObj obj = BSON("a" << LT << Date_t(5000)); + BSONObj obj = BSON("a" << LT << Date_t::fromMillisSinceEpoch(5000)); auto_ptr expr(parseMatchExpression(obj)); BSONElement elt = obj.firstElement(); OrderedIntervalList oil; diff --git a/src/mongo/db/range_deleter.cpp b/src/mongo/db/range_deleter.cpp index bde2e3ad36c..caa2c63804c 100644 --- a/src/mongo/db/range_deleter.cpp +++ b/src/mongo/db/range_deleter.cpp @@ -83,28 +83,28 @@ namespace mongo { // We always log the first cursors waiting message (so we have cursor ids in the logs). // After 15 minutes (the cursor timeout period), we start logging additional messages at // a 1 minute interval. - static const long long kLogCursorsThresholdMillis = 15 * 60 * 1000; - static const long long kLogCursorsIntervalMillis = 1 * 60 * 1000; + static const auto kLogCursorsThreshold = stdx::chrono::minutes{15}; + static const auto kLogCursorsInterval = stdx::chrono::minutes{1}; Date_t currentTime = jsTime(); - long long elapsedMillisSinceQueued = 0; + Milliseconds elapsedMillisSinceQueued{0}; // We always log the first message when lastLoggedTime == 0 - if (entry->lastLoggedTS != 0) { + if (entry->lastLoggedTS != Date_t()) { if (currentTime > entry->stats.queueStartTS) elapsedMillisSinceQueued = currentTime - entry->stats.queueStartTS; // Not logging, threshold not passed - if (elapsedMillisSinceQueued < kLogCursorsThresholdMillis) + if (elapsedMillisSinceQueued < kLogCursorsThreshold) return; - long long elapsedMillisSinceLog = 0; + Milliseconds elapsedMillisSinceLog{0}; if (currentTime > entry->lastLoggedTS) elapsedMillisSinceLog = currentTime - entry->lastLoggedTS; // Not logging, logged a short time ago - if (elapsedMillisSinceLog < kLogCursorsIntervalMillis) + if (elapsedMillisSinceLog < kLogCursorsInterval) return; } @@ -119,9 +119,10 @@ namespace mongo { log() << "waiting for open cursors before removing range " << "[" << entry->options.range.minKey << ", " << entry->options.range.maxKey << ") " << "in " << entry->options.range.ns - << (entry->lastLoggedTS == 0 ? + << (entry->lastLoggedTS == Date_t() ? string("") : - string(str::stream() << ", elapsed secs: " << elapsedMillisSinceQueued / 1000)) + string(str::stream() << ", elapsed secs: " << + durationCount(elapsedMillisSinceQueued))) << ", cursor ids: [" << string(cursorList) << "]"; entry->lastLoggedTS = currentTime; @@ -276,21 +277,23 @@ namespace { repl::ReplicationCoordinator::StatusAndDuration replStatus = repl::getGlobalReplicationCoordinator()->awaitReplicationOfLastOpForClient( txn, writeConcern); - repl::ReplicationCoordinator::Milliseconds elapsedTime = replStatus.duration; + Milliseconds elapsedTime = replStatus.duration; if (replStatus.status.code() == ErrorCodes::ExceededTimeLimit) { *errMsg = str::stream() << "rangeDeleter timed out after " - << elapsedTime.total_seconds() << " seconds while waiting" - << " for deletions to be replicated to majority nodes"; + << durationCount(elapsedTime) + << " seconds while waiting" + " for deletions to be replicated to majority nodes"; log() << *errMsg; } else if (replStatus.status.code() == ErrorCodes::NotMaster) { *errMsg = str::stream() << "rangeDeleter no longer PRIMARY after " - << elapsedTime.total_seconds() << " seconds while waiting" - << " for deletions to be replicated to majority nodes"; + << durationCount(elapsedTime) + << " seconds while waiting" + " for deletions to be replicated to majority nodes"; } else { - LOG(elapsedTime.total_seconds() < 30 ? 1 : 0) - << "rangeDeleter took " << elapsedTime.total_seconds() << " seconds " + LOG(elapsedTime < Seconds(30) ? 1 : 0) + << "rangeDeleter took " << durationCount(elapsedTime) << " seconds " << " waiting for deletes to be replicated to majority nodes"; fassert(18512, replStatus.status); @@ -601,10 +604,7 @@ namespace { } RangeDeleteEntry::RangeDeleteEntry(const RangeDeleterOptions& options) - : options(options), - notifyDone(NULL), - lastLoggedTS(0) { - } + : options(options), notifyDone(NULL) {} BSONObj RangeDeleteEntry::toBSON() const { BSONObjBuilder builder; diff --git a/src/mongo/db/repl/base_cloner_test_fixture.cpp b/src/mongo/db/repl/base_cloner_test_fixture.cpp index 45d1ca8b29d..2abe7d75a01 100644 --- a/src/mongo/db/repl/base_cloner_test_fixture.cpp +++ b/src/mongo/db/repl/base_cloner_test_fixture.cpp @@ -131,7 +131,7 @@ namespace repl { boost::unique_lock lk(_mutex); if (_status == getDefaultStatus()) { try { - _setStatusCondition.timed_wait(lk, ReplicationExecutor::Milliseconds(1000)); + _setStatusCondition.wait_for(lk, Milliseconds(1000)); } catch (const boost::thread_interrupted&) { } @@ -142,7 +142,7 @@ namespace repl { void BaseClonerTest::scheduleNetworkResponse(NetworkOperationIterator noi, const BSONObj& obj) { auto net = getNet(); - ReplicationExecutor::Milliseconds millis(0); + Milliseconds millis(0); RemoteCommandResponse response(obj, millis); ReplicationExecutor::ResponseStatus responseStatus(response); net->scheduleResponse(noi, net->now(), responseStatus); diff --git a/src/mongo/db/repl/check_quorum_for_config_change_test.cpp b/src/mongo/db/repl/check_quorum_for_config_change_test.cpp index 677141c727e..dbb5fb562f1 100644 --- a/src/mongo/db/repl/check_quorum_for_config_change_test.cpp +++ b/src/mongo/db/repl/check_quorum_for_config_change_test.cpp @@ -190,12 +190,12 @@ namespace { const int numCommandsExpected = config.getNumMembers() - 1; for (int i = 0; i < numCommandsExpected; ++i) { _net->scheduleResponse(_net->getNextReadyRequest(), - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(ErrorCodes::NoSuchKey, "No reply")); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NodeNotFound, status); ASSERT_REASON_CONTAINS( @@ -248,11 +248,11 @@ namespace { ASSERT(seenHosts.insert(request.target).second) << "Already saw " << request.target.toString(); _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); ASSERT_OK(waitForQuorumCheck()); } @@ -291,17 +291,17 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h2", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(ErrorCodes::NoSuchKey, "No response")); } else { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), Milliseconds(8)))); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NodeNotFound, status); @@ -346,19 +346,19 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h4", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 0 << "mismatch" << true), Milliseconds(8)))); } else { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), Milliseconds(8)))); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NewReplicaSetConfigurationIncompatible, status); @@ -402,7 +402,7 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h5", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 0 << "set" << "rs0" << @@ -411,12 +411,12 @@ namespace { } else { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), Milliseconds(8)))); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NewReplicaSetConfigurationIncompatible, status); @@ -463,7 +463,7 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h5", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 0 << "set" << "rs0" << @@ -474,7 +474,7 @@ namespace { _net->blackHole(noi); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NewReplicaSetConfigurationIncompatible, status); @@ -522,7 +522,7 @@ namespace { hbResp.noteHasData(); if (request.target == HostAndPort("h5", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( hbResp.toBSON(), Milliseconds(8)))); @@ -531,7 +531,7 @@ namespace { _net->blackHole(noi); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::CannotInitializeNodeWithData, status); @@ -571,7 +571,7 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h1", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 0 << "set" << "rs0" << @@ -582,7 +582,7 @@ namespace { _net->blackHole(noi); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NewReplicaSetConfigurationIncompatible, status); @@ -623,18 +623,18 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h2", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 0 << "mismatch" << true), Milliseconds(8)))); } else { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(ErrorCodes::NoSuchKey, "No response")); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NewReplicaSetConfigurationIncompatible, status); @@ -677,18 +677,18 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h1", 1) || request.target == HostAndPort("h5", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), Milliseconds(8)))); } else { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(ErrorCodes::NoSuchKey, "No response")); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NodeNotFound, status); @@ -730,18 +730,18 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h5", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), Milliseconds(8)))); } else { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(ErrorCodes::NoSuchKey, "No response")); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); Status status = waitForQuorumCheck(); ASSERT_EQUALS(ErrorCodes::NodeNotFound, status); @@ -779,7 +779,7 @@ namespace { "Already saw " << request.target.toString(); if (request.target == HostAndPort("h1", 1) || request.target == HostAndPort("h2", 1)) { _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), Milliseconds(8)))); @@ -788,7 +788,7 @@ namespace { _net->blackHole(noi); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); ASSERT_OK(waitForQuorumCheck()); } diff --git a/src/mongo/db/repl/data_replicator.cpp b/src/mongo/db/repl/data_replicator.cpp index 4d1964c59ae..288f218c19f 100644 --- a/src/mongo/db/repl/data_replicator.cpp +++ b/src/mongo/db/repl/data_replicator.cpp @@ -61,7 +61,7 @@ namespace repl { MONGO_FP_DECLARE(failInitialSyncWithBadHost); namespace { - int NoSyncSourceRetryDelayMS = 4000; + const Milliseconds NoSyncSourceRetryDelayMS{4000}; std::string toString(DataReplicatiorState s) { switch (s) { @@ -499,7 +499,7 @@ namespace repl { if (status.code() == ErrorCodes::InvalidSyncSource) { // Error, sync source - Date_t until = 0; + Date_t until{}; _replCoord->blacklistSyncSource(_syncSource, until); _syncSource = HostAndPort(); } diff --git a/src/mongo/db/repl/data_replicator_test.cpp b/src/mongo/db/repl/data_replicator_test.cpp index db8ed712737..8fc727c7b38 100644 --- a/src/mongo/db/repl/data_replicator_test.cpp +++ b/src/mongo/db/repl/data_replicator_test.cpp @@ -84,7 +84,7 @@ namespace { void scheduleNetworkResponse(const BSONObj& obj) { NetworkInterfaceMock* net = getNet(); ASSERT_TRUE(net->hasReadyRequests()); - ReplicationExecutor::Milliseconds millis(0); + Milliseconds millis(0); RemoteCommandResponse response(obj, millis); ReplicationExecutor::ResponseStatus responseStatus(response); net->scheduleResponse(net->getNextReadyRequest(), net->now(), responseStatus); diff --git a/src/mongo/db/repl/elect_cmd_runner_test.cpp b/src/mongo/db/repl/elect_cmd_runner_test.cpp index ef9751dc084..f4d4c913bf1 100644 --- a/src/mongo/db/repl/elect_cmd_runner_test.cpp +++ b/src/mongo/db/repl/elect_cmd_runner_test.cpp @@ -199,15 +199,15 @@ namespace { ASSERT_EQUALS(stripRound(electRequest), stripRound(noi->getRequest().cmdObj)); ASSERT_EQUALS(HostAndPort("h1"), noi->getRequest().target); _net->scheduleResponse(noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1 << "vote" << 1 << "round" << 380865962699346850ll), Milliseconds(8)))); - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitForTest(); ASSERT_EQUALS(electCmdRunner.getReceivedVotes(), 2); } diff --git a/src/mongo/db/repl/fetcher_test.cpp b/src/mongo/db/repl/fetcher_test.cpp index 427f888ff50..c78ade64872 100644 --- a/src/mongo/db/repl/fetcher_test.cpp +++ b/src/mongo/db/repl/fetcher_test.cpp @@ -109,7 +109,7 @@ namespace { void FetcherTest::scheduleNetworkResponse(const BSONObj& obj) { NetworkInterfaceMock* net = getNet(); ASSERT_TRUE(net->hasReadyRequests()); - ReplicationExecutor::Milliseconds millis(0); + Milliseconds millis(0); RemoteCommandResponse response(obj, millis); ReplicationExecutor::ResponseStatus responseStatus(response); net->scheduleResponse(net->getNextReadyRequest(), net->now(), responseStatus); diff --git a/src/mongo/db/repl/freshness_checker.cpp b/src/mongo/db/repl/freshness_checker.cpp index 2c5ef4872b8..17a501f2ce4 100644 --- a/src/mongo/db/repl/freshness_checker.cpp +++ b/src/mongo/db/repl/freshness_checker.cpp @@ -88,7 +88,7 @@ namespace repl { BSONObjBuilder freshCmdBuilder; freshCmdBuilder.append("replSetFresh", 1); freshCmdBuilder.append("set", _rsConfig.getReplSetName()); - freshCmdBuilder.append("opTime", Date_t(_lastOpTimeApplied.asULL())); + freshCmdBuilder.append("opTime", Date_t::fromMillisSinceEpoch(_lastOpTimeApplied.asLL())); freshCmdBuilder.append("who", selfConfig.getHostAndPort().toString()); freshCmdBuilder.appendIntOrLL("cfgver", _rsConfig.getConfigVersion()); freshCmdBuilder.append("id", selfConfig.getId()); diff --git a/src/mongo/db/repl/freshness_checker_test.cpp b/src/mongo/db/repl/freshness_checker_test.cpp index 08766cfd7ca..6f2e3ab9a85 100644 --- a/src/mongo/db/repl/freshness_checker_test.cpp +++ b/src/mongo/db/repl/freshness_checker_test.cpp @@ -123,7 +123,7 @@ namespace { const MemberConfig& myConfig = rsConfig.getMemberAt(selfIndex); return BSON("replSetFresh" << 1 << "set" << rsConfig.getReplSetName() << - "opTime" << Date_t(lastOpTimeApplied.asULL()) << + "opTime" << Date_t::fromMillisSinceEpoch(lastOpTimeApplied.asLL()) << "who" << myConfig.getHostAndPort().toString() << "cfgver" << rsConfig.getConfigVersion() << "id" << myConfig.getId()); @@ -186,19 +186,19 @@ namespace { ASSERT_EQUALS(HostAndPort("h1"), noi->getRequest().target); _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1 << "id" << 2 << "set" << "rs0" << "who" << "h1" << "cfgver" << 1 << - "opTime" << Date_t(Timestamp(0,0).asULL())), + "opTime" << Date_t()), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); ASSERT_EQUALS(shouldAbortElection(), FreshnessChecker::FreshnessTie); } @@ -254,7 +254,7 @@ namespace { ASSERT_EQUALS(HostAndPort("h1"), noi->getRequest().target); _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1 << "id" << 2 << @@ -262,12 +262,12 @@ namespace { "who" << "h1" << "cfgver" << 1 << "fresher" << true << - "opTime" << Date_t(Timestamp(0,0).asULL())), + "opTime" << Date_t()), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); stopCapturingLogMessages(); @@ -300,19 +300,20 @@ namespace { ASSERT_EQUALS(HostAndPort("h1"), noi->getRequest().target); _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1 << "id" << 2 << "set" << "rs0" << "who" << "h1" << "cfgver" << 1 << - "opTime" << Date_t(Timestamp(10,0).asULL())), + "opTime" << Date_t::fromMillisSinceEpoch( + Timestamp(10,0).asLL())), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); stopCapturingLogMessages(); @@ -344,7 +345,7 @@ namespace { ASSERT_EQUALS(HostAndPort("h1"), noi->getRequest().target); _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1 << "id" << 2 << @@ -354,9 +355,9 @@ namespace { "opTime" << 3), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); stopCapturingLogMessages(); @@ -391,7 +392,7 @@ namespace { ASSERT_EQUALS(HostAndPort("h1"), noi->getRequest().target); _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1 << "id" << 2 << @@ -400,12 +401,13 @@ namespace { "cfgver" << 1 << "veto" << true << "errmsg" << "I'd rather you didn't" << - "opTime" << Date_t(Timestamp(0,0).asULL())), + "opTime" << Date_t::fromMillisSinceEpoch( + Timestamp(0,0).asLL())), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); stopCapturingLogMessages(); @@ -460,20 +462,20 @@ namespace { "set" << "rs0" << "who" << target.toString() << "cfgver" << 1 << - "opTime" << Date_t(Timestamp(0,0).asULL()); + "opTime" << Date_t::fromMillisSinceEpoch(Timestamp(0,0).asLL()); if (target.host() == "h1") { responseBuilder << "fresher" << true; } _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( responseBuilder.obj(), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); stopCapturingLogMessages(); ASSERT_EQUALS(shouldAbortElection(), FreshnessChecker::FresherNodeFound); @@ -524,10 +526,10 @@ namespace { "set" << "rs0" << "who" << target.toString() << "cfgver" << 1 << - "opTime" << Date_t(Timestamp(20,0).asULL()); + "opTime" << Date_t::fromMillisSinceEpoch(Timestamp(20,0).asLL()); _net->scheduleResponse( noi, - startDate + 20, + startDate + Milliseconds(20), ResponseStatus(RemoteCommandResponse( responseBuilder.obj(), Milliseconds(8)))); @@ -539,20 +541,20 @@ namespace { "set" << "rs0" << "who" << target.toString() << "cfgver" << 1 << - "opTime" << Date_t(Timestamp(10,0).asULL()); + "opTime" << Date_t::fromMillisSinceEpoch(Timestamp(10,0).asLL()); _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( responseBuilder.obj(), Milliseconds(8)))); } } - _net->runUntil(startDate + 10); - ASSERT_EQUALS(startDate + 10, _net->now()); + _net->runUntil(startDate + Milliseconds(10)); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); ASSERT_EQUALS(0, countLogLinesContaining("not electing self, we are not freshest")); - _net->runUntil(startDate + 20); - ASSERT_EQUALS(startDate + 20, _net->now()); + _net->runUntil(startDate + Milliseconds(20)); + ASSERT_EQUALS(startDate + Milliseconds(20), _net->now()); _net->exitNetwork(); waitOnChecker(); stopCapturingLogMessages(); @@ -602,18 +604,18 @@ namespace { responseBuilder << "opTime" << 3; } else { - responseBuilder << "opTime" << Date_t(Timestamp(0,0).asULL()); + responseBuilder << "opTime" << Date_t::fromMillisSinceEpoch(Timestamp(0,0).asLL()); } _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( responseBuilder.obj(), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); stopCapturingLogMessages(); ASSERT_EQUALS(shouldAbortElection(), FreshnessChecker::FresherNodeFound); @@ -660,20 +662,20 @@ namespace { "set" << "rs0" << "who" << target.toString() << "cfgver" << 1 << - "opTime" << Date_t(Timestamp(0,0).asULL()); + "opTime" << Date_t::fromMillisSinceEpoch(Timestamp(0,0).asLL()); if (target.host() == "h1") { responseBuilder << "veto" << true << "errmsg" << "I'd rather you didn't"; } _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( responseBuilder.obj(), Milliseconds(8)))); } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); stopCapturingLogMessages(); ASSERT_EQUALS(shouldAbortElection(), FreshnessChecker::FresherNodeFound); @@ -727,10 +729,10 @@ namespace { "cfgver" << 1 << "veto" << true << "errmsg" << "I'd rather you didn't" << - "opTime" << Date_t(Timestamp(10,0).asULL()); + "opTime" << Date_t::fromMillisSinceEpoch(Timestamp(10,0).asLL()); _net->scheduleResponse( noi, - startDate + 20, + startDate + Milliseconds(20), ResponseStatus(RemoteCommandResponse( responseBuilder.obj(), Milliseconds(8)))); @@ -742,21 +744,21 @@ namespace { "set" << "rs0" << "who" << target.toString() << "cfgver" << 1 << - "opTime" << Date_t(Timestamp(10,0).asULL()); + "opTime" << Date_t::fromMillisSinceEpoch(Timestamp(10,0).asLL()); _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( responseBuilder.obj(), Milliseconds(8)))); } } - _net->runUntil(startDate + 10); - ASSERT_EQUALS(startDate + 10, _net->now()); + _net->runUntil(startDate + Milliseconds(10)); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); ASSERT_EQUALS(0, countLogLinesContaining("not electing self, h4:27017 would veto with '" "errmsg: \"I'd rather you didn't\"'")); - _net->runUntil(startDate + 20); - ASSERT_EQUALS(startDate + 20, _net->now()); + _net->runUntil(startDate + Milliseconds(20)); + ASSERT_EQUALS(startDate + Milliseconds(20), _net->now()); _net->exitNetwork(); waitOnChecker(); stopCapturingLogMessages(); @@ -799,7 +801,7 @@ namespace { if (target.host() == "h2" || target.host() == "h3") { _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(ErrorCodes::NoSuchKey, "No response")); } else { @@ -810,18 +812,18 @@ namespace { "set" << "rs0" << "who" << target.toString() << "cfgver" << 1 << - "opTime" << Date_t(Timestamp(0,0).asULL()); + "opTime" << Date_t::fromMillisSinceEpoch(Timestamp(0,0).asLL()); _net->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse( responseBuilder.obj(), Milliseconds(8)))); } } - _net->runUntil(startDate + 10); + _net->runUntil(startDate + Milliseconds(10)); _net->exitNetwork(); - ASSERT_EQUALS(startDate + 10, _net->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), _net->now()); waitOnChecker(); ASSERT_EQUALS(shouldAbortElection(),FreshnessChecker::None); } @@ -874,14 +876,14 @@ namespace { ResponseStatus lessFresh() { BSONObjBuilder bb; bb.append("ok", 1.0); - bb.appendDate("opTime", Timestamp(10, 0).asULL()); + bb.appendDate("opTime", Date_t::fromMillisSinceEpoch(Timestamp(10, 0).asLL())); return ResponseStatus(NetworkInterfaceMock::Response(bb.obj(), Milliseconds(10))); } ResponseStatus moreFreshViaOpTime() { BSONObjBuilder bb; bb.append("ok", 1.0); - bb.appendDate("opTime", Timestamp(110, 0).asULL()); + bb.appendDate("opTime", Date_t::fromMillisSinceEpoch(Timestamp(110, 0).asLL())); return ResponseStatus(NetworkInterfaceMock::Response(bb.obj(), Milliseconds(10))); } @@ -903,7 +905,7 @@ namespace { ResponseStatus tiedForFreshness() { BSONObjBuilder bb; bb.append("ok", 1.0); - bb.appendDate("opTime", Timestamp(100, 0).asULL()); + bb.appendDate("opTime", Date_t::fromMillisSinceEpoch(Timestamp(100, 0).asLL())); return ResponseStatus(NetworkInterfaceMock::Response(bb.obj(), Milliseconds(10))); } diff --git a/src/mongo/db/repl/heartbeat_response_action.cpp b/src/mongo/db/repl/heartbeat_response_action.cpp index 4f26bc2953e..49ed33c4780 100644 --- a/src/mongo/db/repl/heartbeat_response_action.cpp +++ b/src/mongo/db/repl/heartbeat_response_action.cpp @@ -63,11 +63,7 @@ namespace repl { return result; } - HeartbeatResponseAction::HeartbeatResponseAction() : - _action(NoAction), - _primaryIndex(-1), - _nextHeartbeatStartDate(0) { - } + HeartbeatResponseAction::HeartbeatResponseAction() : _action(NoAction), _primaryIndex(-1) {} void HeartbeatResponseAction::setNextHeartbeatStartDate(Date_t when) { _nextHeartbeatStartDate = when; diff --git a/src/mongo/db/repl/is_master_response.cpp b/src/mongo/db/repl/is_master_response.cpp index a789fd7b6dd..ab38c295d14 100644 --- a/src/mongo/db/repl/is_master_response.cpp +++ b/src/mongo/db/repl/is_master_response.cpp @@ -152,7 +152,7 @@ namespace { if (_buildIndexesSet) builder->append(kBuildIndexesFieldName, _buildIndexes); if (_slaveDelaySet) - builder->append(kSlaveDelayFieldName, _slaveDelay.total_seconds()); + builder->appendIntOrLL(kSlaveDelayFieldName, durationCount(_slaveDelay)); if (_tagsSet) { BSONObjBuilder tags(builder->subobjStart(kTagsFieldName)); for (unordered_map::const_iterator it = _tags.begin(); diff --git a/src/mongo/db/repl/master_slave.cpp b/src/mongo/db/repl/master_slave.cpp index 76b6231f924..2b5235bcc46 100644 --- a/src/mongo/db/repl/master_slave.cpp +++ b/src/mongo/db/repl/master_slave.cpp @@ -326,7 +326,7 @@ namespace repl { DBDirectClient c(txn); BSONObj op = c.findOne( "local.oplog.$main", QUERY( "op" << NE << "n" ).sort( BSON( "$natural" << -1 ) ) ); if ( !op.isEmpty() ) { - tmp.syncedTo = op[ "ts" ].date(); + tmp.syncedTo = op[ "ts" ].timestamp(); } } addSourceToList(txn, v, tmp, old); @@ -541,7 +541,7 @@ namespace repl { return true; } BSONElement ts = op.getField( "ts" ); - if ( ( ts.type() == Date || ts.type() == bsonTimestamp ) && ___databaseIgnorer.ignoreAt( db, ts.date() ) ) { + if ( ( ts.type() == Date || ts.type() == bsonTimestamp ) && ___databaseIgnorer.ignoreAt( db, ts.timestamp() ) ) { // Database is ignored due to a previous indication that it is // missing from master after optime "ts". return false; diff --git a/src/mongo/db/repl/member_config.cpp b/src/mongo/db/repl/member_config.cpp index 6f3bcf40501..02711adedd3 100644 --- a/src/mongo/db/repl/member_config.cpp +++ b/src/mongo/db/repl/member_config.cpp @@ -259,7 +259,7 @@ namespace { } if (_slaveDelay < Seconds(0) || _slaveDelay > kMaxSlaveDelay) { return Status(ErrorCodes::BadValue, str::stream() << kSlaveDelayFieldName << - " field value of " << _slaveDelay.total_seconds() << + " field value of " << durationCount(_slaveDelay) << " seconds is out of range"); } if (_slaveDelay > Seconds(0) && _priority != 0) { @@ -310,7 +310,7 @@ namespace { } tags.done(); - configBuilder.append("slaveDelay", _slaveDelay.total_seconds()); + configBuilder.append("slaveDelay", durationCount(_slaveDelay)); configBuilder.append("votes", getNumVotes()); return configBuilder.obj(); } diff --git a/src/mongo/db/repl/member_config_test.cpp b/src/mongo/db/repl/member_config_test.cpp index 9d3a0f7b276..6411156f4f8 100644 --- a/src/mongo/db/repl/member_config_test.cpp +++ b/src/mongo/db/repl/member_config_test.cpp @@ -46,7 +46,7 @@ namespace { ASSERT_EQUALS(0, mc.getId()); ASSERT_EQUALS(HostAndPort("localhost", 12345), mc.getHostAndPort()); ASSERT_EQUALS(1.0, mc.getPriority()); - ASSERT_EQUALS(0, mc.getSlaveDelay().total_seconds()); + ASSERT_EQUALS(Seconds(0), mc.getSlaveDelay()); ASSERT_TRUE(mc.isVoter()); ASSERT_FALSE(mc.isHidden()); ASSERT_FALSE(mc.isArbiter()); @@ -79,7 +79,7 @@ namespace { mc.initialize(BSON("_id" << "0" << "host" << "localhost:12345"), &tagConfig)); ASSERT_EQUALS(ErrorCodes::TypeMismatch, - mc.initialize(BSON("_id" << Date_t(0) << "host" << "localhost:12345"), + mc.initialize(BSON("_id" << Date_t() << "host" << "localhost:12345"), &tagConfig)); } @@ -161,7 +161,9 @@ namespace { &tagConfig)); ASSERT_EQUALS(ErrorCodes::TypeMismatch, - mc.initialize(BSON("_id" << 0 << "host" << "h" << "votes" << Date_t(2)), + mc.initialize(BSON("_id" << 0 << + "host" << "h" << + "votes" << Date_t::fromMillisSinceEpoch(2)), &tagConfig)); } @@ -179,7 +181,9 @@ namespace { ASSERT_EQUALS(100.8, mc.getPriority()); ASSERT_EQUALS(ErrorCodes::TypeMismatch, - mc.initialize(BSON("_id" << 0 << "host" << "h" << "priority" << Date_t(2)), + mc.initialize(BSON("_id" << 0 << + "host" << "h" << + "priority" << Date_t::fromMillisSinceEpoch(2)), &tagConfig)); } @@ -188,7 +192,7 @@ namespace { MemberConfig mc; ASSERT_OK(mc.initialize(BSON("_id" << 0 << "host" << "h" << "slaveDelay" << 100), &tagConfig)); - ASSERT_EQUALS(100, mc.getSlaveDelay().total_seconds()); + ASSERT_EQUALS(Seconds(100), mc.getSlaveDelay()); } TEST(MemberConfig, ParseTags) { diff --git a/src/mongo/db/repl/member_heartbeat_data.cpp b/src/mongo/db/repl/member_heartbeat_data.cpp index 5ae8f1fbffc..c4c99f5bd28 100644 --- a/src/mongo/db/repl/member_heartbeat_data.cpp +++ b/src/mongo/db/repl/member_heartbeat_data.cpp @@ -41,9 +41,6 @@ namespace repl { MemberHeartbeatData::MemberHeartbeatData() : _health(-1), - _upSince(0), - _lastHeartbeat(0), - _lastHeartbeatRecv(0), _authIssue(false) { _lastResponse.setState(MemberState::RS_UNKNOWN); @@ -55,7 +52,7 @@ namespace repl { const HostAndPort& host, ReplSetHeartbeatResponse hbResponse) { _health = 1; - if (_upSince == 0) { + if (_upSince == Date_t()) { _upSince = now; } _authIssue = false; @@ -82,7 +79,7 @@ namespace repl { void MemberHeartbeatData::setDownValues(Date_t now, const std::string& heartbeatMessage) { _health = 0; - _upSince = 0; + _upSince = Date_t(); _lastHeartbeat = now; _authIssue = false; @@ -96,7 +93,7 @@ namespace repl { void MemberHeartbeatData::setAuthIssue(Date_t now) { _health = 0; // set health to 0 so that this doesn't count towards majority. - _upSince = 0; + _upSince = Date_t(); _lastHeartbeat = now; _authIssue = true; diff --git a/src/mongo/db/repl/network_interface_impl.cpp b/src/mongo/db/repl/network_interface_impl.cpp index 3dd08e51a14..69ab9dc921e 100644 --- a/src/mongo/db/repl/network_interface_impl.cpp +++ b/src/mongo/db/repl/network_interface_impl.cpp @@ -159,7 +159,7 @@ namespace { if (waitTime <= Milliseconds(0)) { break; } - _isExecutorRunnableCondition.timed_wait(lk, waitTime); + _isExecutorRunnableCondition.wait_for(lk, waitTime); } _isExecutorRunnable = false; } @@ -184,13 +184,13 @@ namespace { if (_threads.size() > kMinThreads) { const Date_t nowDate = now(); const Date_t nextThreadRetirementDate = - _lastFullUtilizationDate + kMaxIdleThreadAge.total_milliseconds(); + _lastFullUtilizationDate + kMaxIdleThreadAge; if (nowDate > nextThreadRetirementDate) { _lastFullUtilizationDate = nowDate; break; } } - _hasPending.timed_wait(lk, kMaxIdleThreadAge); + _hasPending.wait_for(lk, kMaxIdleThreadAge); continue; } CommandData todo = _pending.front(); @@ -243,7 +243,7 @@ namespace { _startNewNetworkThread_inlock(); } if (_numIdleThreads <= _pending.size()) { - _lastFullUtilizationDate = curTimeMillis64(); + _lastFullUtilizationDate = Date_t::now(); } _hasPending.notify_one(); } @@ -270,7 +270,7 @@ namespace { } Date_t NetworkInterfaceImpl::now() { - return curTimeMillis64(); + return Date_t::now(); } OperationContext* NetworkInterfaceImpl::createOperationContext() { diff --git a/src/mongo/db/repl/network_interface_mock.cpp b/src/mongo/db/repl/network_interface_mock.cpp index ed10d4743a0..80263365eba 100644 --- a/src/mongo/db/repl/network_interface_mock.cpp +++ b/src/mongo/db/repl/network_interface_mock.cpp @@ -41,13 +41,10 @@ namespace repl { NetworkInterfaceMock::NetworkInterfaceMock() : _waitingToRunMask(0), _currentlyRunning(kNoThread), + _now(fassertStatusOK(18653, dateFromISOString("2014-08-01T00:00:00Z"))), _hasStarted(false), _inShutdown(false), - _executorNextWakeupDate(~0ULL) { - - StatusWith initialNow = dateFromISOString("2014-08-01T00:00:00Z"); - fassert(18653, initialNow.getStatus()); - _now = initialNow.getValue(); + _executorNextWakeupDate(Date_t::max()) { } NetworkInterfaceMock::~NetworkInterfaceMock() { diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index d99aab42b66..5d76b2c7614 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -892,7 +892,7 @@ namespace { if (!lastOp.isEmpty()) { LOG(1) << "replSet setting last OpTime"; - setNewOptime(lastOp[ "ts" ].date()); + setNewOptime(lastOp[ "ts" ].timestamp()); } } diff --git a/src/mongo/db/repl/oplogreader.cpp b/src/mongo/db/repl/oplogreader.cpp index 5a0e1054d12..bea0484fc44 100644 --- a/src/mongo/db/repl/oplogreader.cpp +++ b/src/mongo/db/repl/oplogreader.cpp @@ -144,7 +144,7 @@ namespace repl { void OplogReader::connectToSyncSource(OperationContext* txn, Timestamp lastOpTimeFetched, ReplicationCoordinator* replCoord) { - const Timestamp sentinel(Milliseconds(curTimeMillis64()).total_seconds(), 0); + const Timestamp sentinel(duration_cast(Milliseconds(curTimeMillis64())), 0); Timestamp oldestOpTimeSeen = sentinel; invariant(conn() == NULL); @@ -182,7 +182,7 @@ namespace repl { LOG(2) << "can't connect to " << candidate.toString() << " to read operations"; resetConnection(); - replCoord->blacklistSyncSource(candidate, Date_t(curTimeMillis64() + 10*1000)); + replCoord->blacklistSyncSource(candidate, Date_t::now() + Seconds(10)); continue; } // Read the first (oldest) op and confirm that it's not newer than our last @@ -193,8 +193,7 @@ namespace repl { // This member's got a bad op in its oplog. warning() << "oplog invalid format on node " << candidate.toString(); resetConnection(); - replCoord->blacklistSyncSource(candidate, - Date_t(curTimeMillis64() + 600*1000)); + replCoord->blacklistSyncSource(candidate, Date_t::now() + Minutes(10)); continue; } Timestamp remoteOldOpTime = tsElem.timestamp(); @@ -202,8 +201,7 @@ namespace repl { if (lastOpTimeFetched < remoteOldOpTime) { // We're too stale to use this sync source. resetConnection(); - replCoord->blacklistSyncSource(candidate, - Date_t(curTimeMillis64() + 600*1000)); + replCoord->blacklistSyncSource(candidate, Date_t::now() + Minutes(10)); if (oldestOpTimeSeen > remoteOldOpTime) { warning() << "we are too stale to use " << candidate.toString() << " as a sync source"; diff --git a/src/mongo/db/repl/read_after_optime_args_test.cpp b/src/mongo/db/repl/read_after_optime_args_test.cpp index d780500d9c2..557767c2886 100644 --- a/src/mongo/db/repl/read_after_optime_args_test.cpp +++ b/src/mongo/db/repl/read_after_optime_args_test.cpp @@ -46,7 +46,7 @@ namespace { ASSERT_EQ(Timestamp(20, 30), readAfterOpTime.getOpTime().getTimestamp()); ASSERT_EQ(2, readAfterOpTime.getOpTime().getTerm()); - ASSERT_EQ(100, readAfterOpTime.getTimeout().total_milliseconds()); + ASSERT_EQ(Milliseconds(100), readAfterOpTime.getTimeout()); } TEST(ReadAfterParse, Empty) { @@ -54,7 +54,7 @@ namespace { ASSERT_OK(readAfterOpTime.initialize(BSON("find" << "test"))); ASSERT(readAfterOpTime.getOpTime().getTimestamp().isNull()); - ASSERT_EQ(0, readAfterOpTime.getTimeout().total_milliseconds()); + ASSERT_EQ(Milliseconds::zero(), readAfterOpTime.getTimeout()); } TEST(ReadAfterParse, BadRootType) { @@ -133,7 +133,7 @@ namespace { ASSERT_EQ(Timestamp(1, 0), readAfterOpTime.getOpTime().getTimestamp()); ASSERT_EQ(2, readAfterOpTime.getOpTime().getTerm()); - ASSERT_EQ(0, readAfterOpTime.getTimeout().total_milliseconds()); + ASSERT_EQ(Milliseconds::zero(), readAfterOpTime.getTimeout()); } TEST(ReadAfterParse, BadTimeoutType) { @@ -170,7 +170,7 @@ namespace { ASSERT_EQ(Timestamp(20, 30), readAfterOpTime.getOpTime().getTimestamp()); ASSERT_EQ(2, readAfterOpTime.getOpTime().getTerm()); - ASSERT_EQ(0, readAfterOpTime.getTimeout().total_milliseconds()); + ASSERT_EQ(Milliseconds::zero(), readAfterOpTime.getTimeout()); } } // unnamed namespace diff --git a/src/mongo/db/repl/read_after_optime_response.cpp b/src/mongo/db/repl/read_after_optime_response.cpp index 7caffe09a96..3a6d5fc9962 100644 --- a/src/mongo/db/repl/read_after_optime_response.cpp +++ b/src/mongo/db/repl/read_after_optime_response.cpp @@ -42,7 +42,7 @@ namespace repl { const string ReadAfterOpTimeResponse::kWaitedMSFieldName("waitedMS"); ReadAfterOpTimeResponse::ReadAfterOpTimeResponse(Status status): - ReadAfterOpTimeResponse(status, boost::posix_time::milliseconds(0), false) { + ReadAfterOpTimeResponse(status, stdx::chrono::milliseconds(0), false) { } ReadAfterOpTimeResponse::ReadAfterOpTimeResponse(): @@ -50,12 +50,12 @@ namespace repl { } ReadAfterOpTimeResponse::ReadAfterOpTimeResponse(Status status, - boost::posix_time::milliseconds duration): + stdx::chrono::milliseconds duration): ReadAfterOpTimeResponse(status, duration, true) { } ReadAfterOpTimeResponse::ReadAfterOpTimeResponse(Status status, - boost::posix_time::milliseconds duration, + stdx::chrono::milliseconds duration, bool waited): _waited(waited), _duration(duration), @@ -67,15 +67,14 @@ namespace repl { return; } - builder->append(kWaitedMSFieldName, - static_cast(_duration.total_milliseconds())); + builder->append(kWaitedMSFieldName, durationCount(_duration)); } bool ReadAfterOpTimeResponse::didWait() const { return _waited; } - boost::posix_time::milliseconds ReadAfterOpTimeResponse::getDuration() const { + stdx::chrono::milliseconds ReadAfterOpTimeResponse::getDuration() const { return _duration; } diff --git a/src/mongo/db/repl/read_after_optime_response.h b/src/mongo/db/repl/read_after_optime_response.h index b906dc196d4..33163131363 100644 --- a/src/mongo/db/repl/read_after_optime_response.h +++ b/src/mongo/db/repl/read_after_optime_response.h @@ -28,10 +28,10 @@ #pragma once -#include #include #include "mongo/base/status.h" +#include "mongo/stdx/chrono.h" namespace mongo { @@ -56,7 +56,7 @@ namespace repl { /** * Constructs a response with wait set to true along with the given parameters. */ - ReadAfterOpTimeResponse(Status status, boost::posix_time::milliseconds duration); + ReadAfterOpTimeResponse(Status status, stdx::chrono::milliseconds duration); /** * Appends to the builder the timeout and duration info if didWait() is true. @@ -70,7 +70,7 @@ namespace repl { * Returns the amount of duration waiting for opTime to pass. * Valid only if didWait is true. */ - boost::posix_time::milliseconds getDuration() const; + stdx::chrono::milliseconds getDuration() const; /** * Returns more details about an error if it occurred. @@ -79,11 +79,11 @@ namespace repl { private: ReadAfterOpTimeResponse(Status status, - boost::posix_time::milliseconds duration, + stdx::chrono::milliseconds duration, bool waited); bool _waited; - boost::posix_time::milliseconds _duration; + stdx::chrono::milliseconds _duration; Status _status; }; diff --git a/src/mongo/db/repl/read_after_optime_response_test.cpp b/src/mongo/db/repl/read_after_optime_response_test.cpp index a30824a57b8..09d70204255 100644 --- a/src/mongo/db/repl/read_after_optime_response_test.cpp +++ b/src/mongo/db/repl/read_after_optime_response_test.cpp @@ -62,10 +62,10 @@ namespace { TEST(ReadAfterResponse, WaitedWithDuration) { ReadAfterOpTimeResponse response(Status(ErrorCodes::InternalError, "test"), - boost::posix_time::milliseconds(7)); + stdx::chrono::milliseconds(7)); ASSERT_TRUE(response.didWait()); - ASSERT_EQUALS(7, response.getDuration().total_milliseconds()); + ASSERT_EQUALS(Milliseconds(7), response.getDuration()); ASSERT_EQ(ErrorCodes::InternalError, response.getStatus().code()); BSONObjBuilder builder; diff --git a/src/mongo/db/repl/repl_set_heartbeat_response.cpp b/src/mongo/db/repl/repl_set_heartbeat_response.cpp index 8dac175ddf9..8ea4bd0028f 100644 --- a/src/mongo/db/repl/repl_set_heartbeat_response.cpp +++ b/src/mongo/db/repl/repl_set_heartbeat_response.cpp @@ -90,13 +90,14 @@ namespace { builder->append(kOkFieldName, 1.0); if (_opTimeSet) { - builder->appendDate(kOpTimeFieldName, _opTime.asULL()); + builder->appendDate(kOpTimeFieldName, Date_t::fromMillisSinceEpoch(_opTime.asLL())); } if (_timeSet) { - *builder << kTimeFieldName << _time.total_seconds(); + *builder << kTimeFieldName << durationCount(_time); } if (_electionTimeSet) { - builder->appendDate(kElectionTimeFieldName, _electionTime.asULL()); + builder->appendDate(kElectionTimeFieldName, + Date_t::fromMillisSinceEpoch(_electionTime.asLL())); } if (_configSet) { *builder << kConfigFieldName << _config.toBSON(); diff --git a/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp b/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp index 05e634fbc03..7f482f5e3d9 100644 --- a/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp +++ b/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp @@ -153,7 +153,7 @@ namespace { ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString()); // set opTime - hbResponse.setOpTime(Date_t(10)); + hbResponse.setOpTime(Timestamp(10)); ++fieldsSet; ASSERT_EQUALS(false, hbResponse.hasState()); ASSERT_EQUALS(true, hbResponse.hasElectionTime()); @@ -201,7 +201,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); hbResponseObj = hbResponse.toBSON(); ASSERT_EQUALS(fieldsSet, hbResponseObj.nFields()); @@ -234,7 +234,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); ASSERT_EQUALS(true, hbResponse.isElectable()); hbResponseObj = hbResponse.toBSON(); @@ -270,7 +270,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); ASSERT_EQUALS(true, hbResponse.isElectable()); ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString()); @@ -309,7 +309,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); ASSERT_EQUALS(true, hbResponse.isElectable()); ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString()); @@ -349,7 +349,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); ASSERT_EQUALS(true, hbResponse.isElectable()); ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString()); @@ -391,7 +391,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); ASSERT_EQUALS(true, hbResponse.isElectable()); ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString()); @@ -434,7 +434,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); ASSERT_EQUALS(true, hbResponse.isElectable()); ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString()); @@ -477,7 +477,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); ASSERT_EQUALS(true, hbResponse.isElectable()); ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString()); @@ -520,7 +520,7 @@ namespace { ASSERT_EQUALS(1, hbResponse.getVersion()); ASSERT_EQUALS(Timestamp(10,0), hbResponse.getElectionTime()); ASSERT_EQUALS(Timestamp(0,10), hbResponse.getOpTime()); - ASSERT_EQUALS(10, hbResponse.getTime().total_seconds()); + ASSERT_EQUALS(Seconds(10), hbResponse.getTime()); ASSERT_EQUALS(true, hbResponse.isElectable()); ASSERT_EQUALS(config.toBSON().toString(), hbResponse.getConfig().toBSON().toString()); @@ -670,7 +670,7 @@ namespace { ReplSetHeartbeatResponse hbResponseTimestamp; BSONObjBuilder initializerDate; BSONObjBuilder initializerTimestamp; - Date_t electionTime = Date_t(974132); + Date_t electionTime = Date_t::fromMillisSinceEpoch(974132); initializerDate.append("ok", 1.0); initializerDate.append("v", 1); @@ -680,7 +680,7 @@ namespace { initializerTimestamp.append("ok", 1.0); initializerTimestamp.append("v", 1); - initializerTimestamp.appendTimestamp("electionTime", electionTime); + initializerTimestamp.appendTimestamp("electionTime", electionTime.toULL()); result = hbResponseTimestamp.initialize(initializerTimestamp.obj()); ASSERT_EQUALS(Status::OK(), result); @@ -692,7 +692,7 @@ namespace { ReplSetHeartbeatResponse hbResponseTimestamp; BSONObjBuilder initializerDate; BSONObjBuilder initializerTimestamp; - Date_t opTime = Date_t(974132); + Date_t opTime = Date_t::fromMillisSinceEpoch(974132); initializerDate.append("ok", 1.0); initializerDate.append("v", 1); @@ -702,7 +702,7 @@ namespace { initializerTimestamp.append("ok", 1.0); initializerTimestamp.append("v", 1); - initializerTimestamp.appendTimestamp("opTime", opTime); + initializerTimestamp.appendTimestamp("opTime", opTime.toULL()); result = hbResponseTimestamp.initialize(initializerTimestamp.obj()); ASSERT_EQUALS(Status::OK(), result); diff --git a/src/mongo/db/repl/repl_set_html_summary.cpp b/src/mongo/db/repl/repl_set_html_summary.cpp index 465bfdeb95e..65524427b4a 100644 --- a/src/mongo/db/repl/repl_set_html_summary.cpp +++ b/src/mongo/db/repl/repl_set_html_summary.cpp @@ -68,8 +68,7 @@ namespace { } unsigned int timeDifference(Date_t now, Date_t past) { - return static_cast ((past ? - (now - past) / 1000 /* convert millis to secs */ : 0)); + return static_cast(past != Date_t() ? durationCount(now - past) : 0); } std::string stateAsHtml(const MemberState& s) { @@ -174,7 +173,7 @@ namespace { memberTable << td(red(str::stream() << memberHB.getHealth(), !up)); const unsigned int uptime = timeDifference(_now, memberHB.getUpSince()); memberTable << td(ago(uptime)); - if (memberHB.getLastHeartbeat() == 0) { + if (memberHB.getLastHeartbeat() == Date_t()) { memberTable << td("never"); } else { @@ -191,7 +190,7 @@ namespace { memberTable << td( grey(str::stream() << "(was " << state << ')', true) ); } memberTable << td(grey(memberHB.getLastHeartbeatMsg(), !up)); - memberTable << td(memberHB.getLastHeartbeat() == 0 ? + memberTable << td(memberHB.getLastHeartbeat() == Date_t() ? "?" : memberHB.getOpTime().toString()); } memberTable << _tr(); diff --git a/src/mongo/db/repl/replica_set_config.cpp b/src/mongo/db/repl/replica_set_config.cpp index 1e7c343db7e..dda9e25cf55 100644 --- a/src/mongo/db/repl/replica_set_config.cpp +++ b/src/mongo/db/repl/replica_set_config.cpp @@ -274,7 +274,7 @@ namespace { if (_heartbeatTimeoutPeriod < Seconds(0)) { return Status(ErrorCodes::BadValue, str::stream() << kSettingsFieldName << '.' << kHeartbeatTimeoutFieldName << " field value must be non-negative, " - "but found " << _heartbeatTimeoutPeriod.total_seconds()); + "but found " << _heartbeatTimeoutPeriod.count()); } if (_members.size() > kMaxMembers || _members.empty()) { return Status(ErrorCodes::BadValue, str::stream() << @@ -539,7 +539,7 @@ namespace { BSONObjBuilder settingsBuilder(configBuilder.subobjStart(kSettingsFieldName)); settingsBuilder.append(kChainingAllowedFieldName, _chainingAllowed); - settingsBuilder.append(kHeartbeatTimeoutFieldName, _heartbeatTimeoutPeriod.total_seconds()); + settingsBuilder.appendIntOrLL(kHeartbeatTimeoutFieldName, _heartbeatTimeoutPeriod.count()); BSONObjBuilder gleModes(settingsBuilder.subobjStart(kGetLastErrorModesFieldName)); for (StringMap::const_iterator mode = diff --git a/src/mongo/db/repl/replica_set_config.h b/src/mongo/db/repl/replica_set_config.h index c51ef2ebb40..fcd880705ea 100644 --- a/src/mongo/db/repl/replica_set_config.h +++ b/src/mongo/db/repl/replica_set_config.h @@ -161,7 +161,7 @@ namespace repl { * Seconds object. */ Milliseconds getHeartbeatTimeoutPeriodMillis() const { - return Milliseconds(_heartbeatTimeoutPeriod.total_milliseconds()); + return _heartbeatTimeoutPeriod; } /** diff --git a/src/mongo/db/repl/replica_set_config_test.cpp b/src/mongo/db/repl/replica_set_config_test.cpp index bf2b8f91151..8bc5a247498 100644 --- a/src/mongo/db/repl/replica_set_config_test.cpp +++ b/src/mongo/db/repl/replica_set_config_test.cpp @@ -50,7 +50,7 @@ namespace { ASSERT_EQUALS(0, config.membersBegin()->getId()); ASSERT_EQUALS(1, config.getDefaultWriteConcern().wNumNodes); ASSERT_EQUALS("", config.getDefaultWriteConcern().wMode); - ASSERT_EQUALS(10, config.getHeartbeatTimeoutPeriod().total_seconds()); + ASSERT_EQUALS(Seconds(10), config.getHeartbeatTimeoutPeriod()); ASSERT_TRUE(config.isChainingAllowed()); ASSERT_EQUALS(0, config.getProtocolVersion()); } @@ -78,7 +78,7 @@ namespace { ASSERT_EQUALS(0, config.getDefaultWriteConcern().wNumNodes); ASSERT_EQUALS("majority", config.getDefaultWriteConcern().wMode); ASSERT_FALSE(config.isChainingAllowed()); - ASSERT_EQUALS(120, config.getHeartbeatTimeoutPeriod().total_seconds()); + ASSERT_EQUALS(Seconds(120), config.getHeartbeatTimeoutPeriod()); ASSERT_EQUALS(2, config.getProtocolVersion()); } @@ -603,7 +603,7 @@ namespace { "host" << "localhost:12345")) << "settings" << BSON("heartbeatTimeoutSecs" << 20)))); ASSERT_OK(config.validate()); - ASSERT_EQUALS(20, config.getHeartbeatTimeoutPeriod().total_seconds()); + ASSERT_EQUALS(Seconds(20), config.getHeartbeatTimeoutPeriod()); ASSERT_OK(config.initialize( BSON("_id" << "rs0" << diff --git a/src/mongo/db/repl/replication_coordinator.h b/src/mongo/db/repl/replication_coordinator.h index 2f5a685c986..a1e7a975bd5 100644 --- a/src/mongo/db/repl/replication_coordinator.h +++ b/src/mongo/db/repl/replication_coordinator.h @@ -28,7 +28,6 @@ #pragma once -#include #include #include "mongo/base/disallow_copying.h" @@ -37,6 +36,7 @@ #include "mongo/db/repl/repl_settings.h" #include "mongo/db/repl/reporter.h" #include "mongo/util/net/hostandport.h" +#include "mongo/util/time_support.h" namespace mongo { @@ -89,8 +89,6 @@ namespace repl { public: - typedef boost::posix_time::milliseconds Milliseconds; - struct StatusAndDuration { public: Status status; diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index 37808512255..eecf48f5a2d 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -793,8 +793,7 @@ namespace { while (ts > _getMyLastOptime_inlock()) { Status interruptedStatus = txn->checkForInterruptNoAssert(); if (!interruptedStatus.isOK()) { - return ReadAfterOpTimeResponse(interruptedStatus, - Milliseconds(timer.millis())); + return ReadAfterOpTimeResponse(interruptedStatus, Milliseconds(timer.millis())); } if (_inShutdown) { @@ -803,14 +802,13 @@ namespace { Milliseconds(timer.millis())); } - const auto elapsedMS = timer.millis(); - if (timeout.total_milliseconds() > 0 && - elapsedMS > timeout.total_milliseconds()) { + const Microseconds elapsedTime{timer.micros()}; + if (timeout > Microseconds::zero() && elapsedTime > timeout) { return ReadAfterOpTimeResponse( Status(ErrorCodes::ReadAfterOptimeTimeout, str::stream() << "timed out waiting for opTime: " << ts.toString()), - Milliseconds(timer.millis())); + duration_cast(elapsedTime)); } boost::condition_variable condVar; @@ -820,21 +818,19 @@ namespace { nullptr, // Don't care about write concern. &condVar); - uint64_t maxTimeMicrosRemaining = txn->getRemainingMaxTimeMicros(); - auto maxTimeMSRemaining = (maxTimeMicrosRemaining == 0) ? - std::numeric_limits::max() : (maxTimeMicrosRemaining / 1000); - - auto timeoutMSRemaining = (timeout.total_milliseconds() == 0) ? - std::numeric_limits::max() : - static_cast(timeout.total_milliseconds() - elapsedMS); - - auto sleepTimeMS = std::min(maxTimeMSRemaining, timeoutMSRemaining); - - if (sleepTimeMS == std::numeric_limits::max()) { + const Microseconds maxTimeMicrosRemaining{txn->getRemainingMaxTimeMicros()}; + Microseconds waitTime = Microseconds::max(); + if (maxTimeMicrosRemaining != Microseconds::zero()) { + waitTime = maxTimeMicrosRemaining; + } + if (timeout != Microseconds::zero()) { + waitTime = std::min(timeout - elapsedTime, waitTime); + } + if (waitTime == Microseconds::max()) { condVar.wait(lock); } else { - condVar.timed_wait(lock, Milliseconds(sleepTimeMS)); + condVar.wait_for(lock, waitTime); } } @@ -1134,7 +1130,7 @@ namespace { condVar.wait(*lock); } else { - condVar.timed_wait(*lock, Milliseconds(writeConcern.wTimeout - elapsed)); + condVar.wait_for(*lock, Milliseconds(writeConcern.wTimeout - elapsed)); } } catch (const boost::thread_interrupted&) {} } @@ -1152,8 +1148,8 @@ namespace { const Milliseconds& waitTime, const Milliseconds& stepdownTime) { const Date_t startTime = _replExecutor.now(); - const Date_t stepDownUntil(startTime.millis + stepdownTime.total_milliseconds()); - const Date_t waitUntil(startTime.millis + waitTime.total_milliseconds()); + const Date_t stepDownUntil = startTime + stepdownTime; + const Date_t waitUntil = startTime + waitTime; if (!getMemberState().primary()) { // Note this check is inherently racy - it's always possible for the node to @@ -1169,7 +1165,8 @@ namespace { _externalState->killAllUserOperations(txn); if (lockState == LOCK_WAITING) { - lockState = txn->lockState()->lockGlobalComplete(stepdownTime.total_milliseconds()); + lockState = txn->lockState()->lockGlobalComplete( + durationCount(stepdownTime)); if (lockState == LOCK_TIMEOUT) { return Status(ErrorCodes::ExceededTimeLimit, "Could not acquire the global shared lock within the amount of time " diff --git a/src/mongo/db/repl/replication_coordinator_impl_elect.cpp b/src/mongo/db/repl/replication_coordinator_impl_elect.cpp index a7804698f25..612990e8048 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_elect.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_elect.cpp @@ -173,9 +173,9 @@ namespace { break; case FreshnessChecker::FreshnessTie: if ((_selfIndex != 0) && !_sleptLastElection) { - const long long ms = _replExecutor.nextRandomInt64(1000) + 50; + const auto ms = Milliseconds(_replExecutor.nextRandomInt64(1000) + 50); const Date_t nextCandidateTime = now + ms; - log() << "possible election tie; sleeping " << ms << "ms until " << + log() << "possible election tie; sleeping " << ms.count() << "ms until " << dateToISOStringLocal(nextCandidateTime); _topCoord->setElectionSleepUntil(nextCandidateTime); _replExecutor.scheduleWorkAt( @@ -241,7 +241,7 @@ namespace { " votes, but needed at least " << _rsConfig.getMajorityVoteCount(); // Suppress ourselves from standing for election again, giving other nodes a chance // to win their elections. - const long long ms = _replExecutor.nextRandomInt64(1000) + 50; + const auto ms = Milliseconds(_replExecutor.nextRandomInt64(1000) + 50); const Date_t now(_replExecutor.now()); const Date_t nextCandidateTime = now + ms; log() << "waiting until " << nextCandidateTime << " before standing for election again"; diff --git a/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp index babcd22d423..b1342d65fb2 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_elect_test.cpp @@ -97,7 +97,8 @@ namespace { net->scheduleResponse(noi, net->now(), makeResponseStatus( BSON("ok" << 1 << "fresher" << false << - "opTime" << Date_t(Timestamp(0, 0).asULL()) << + "opTime" << Date_t::fromMillisSinceEpoch( + Timestamp(0, 0).asLL()) << "veto" << false))); } else { @@ -354,7 +355,7 @@ namespace { BSONObjBuilder respObj2; respObj2 << "ok" << 1; hbResp2.addToBSON(&respObj2); - net->runUntil(net->now() + 10*1000); // run until we've sent a heartbeat request + net->runUntil(net->now() + Seconds(10)); // run until we've sent a heartbeat request const NetworkInterfaceMock::NetworkOperationIterator noi2 = net->getNextReadyRequest(); net->scheduleResponse(noi2, net->now(), makeResponseStatus(respObj2.obj())); net->runReadyNetworkOperations(); diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp index 30c564284b1..0dec8c5b1a6 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_test.cpp @@ -115,8 +115,10 @@ namespace { BSONObjBuilder responseBuilder; responseBuilder << "ok" << 1; hbResp.addToBSON(&responseBuilder); - net->scheduleResponse(noi, startDate + 200, makeResponseStatus(responseBuilder.obj())); - assertRunUntil(startDate + 200); + net->scheduleResponse(noi, + startDate + Milliseconds(200), + makeResponseStatus(responseBuilder.obj())); + assertRunUntil(startDate + Milliseconds(200)); // Because the new config is stored using an out-of-band thread, we need to perform some // extra synchronization to let the executor finish the heartbeat reconfig. We know that @@ -174,8 +176,10 @@ namespace { BSONObjBuilder responseBuilder; responseBuilder << "ok" << 1; hbResp.addToBSON(&responseBuilder); - net->scheduleResponse(noi, startDate + 200, makeResponseStatus(responseBuilder.obj())); - assertRunUntil(startDate + 2200); + net->scheduleResponse(noi, + startDate + Milliseconds(200), + makeResponseStatus(responseBuilder.obj())); + assertRunUntil(startDate + Milliseconds(2200)); // Because the new config is stored using an out-of-band thread, we need to perform some // extra synchronization to let the executor finish the heartbeat reconfig. We know that diff --git a/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp index 672d1b42cf8..4fdaba5a70e 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_reconfig_test.cpp @@ -415,7 +415,7 @@ namespace { BSONObjBuilder respObj2; respObj2 << "ok" << 1; hbResp2.addToBSON(&respObj2); - net->runUntil(net->now() + 10*1000); // run until we've sent a heartbeat request + net->runUntil(net->now() + Seconds(10)); // run until we've sent a heartbeat request const NetworkInterfaceMock::NetworkOperationIterator noi2 = net->getNextReadyRequest(); net->scheduleResponse(noi2, net->now(), makeResponseStatus(respObj2.obj())); net->runReadyNetworkOperations(); @@ -457,7 +457,7 @@ namespace { net->blackHole(net->getNextReadyRequest()); // schedule hb reconfig - net->runUntil(net->now() + 10*1000); // run until we've sent a heartbeat request + net->runUntil(net->now() + Seconds(10)); // run until we've sent a heartbeat request const NetworkInterfaceMock::NetworkOperationIterator noi = net->getNextReadyRequest(); ReplSetHeartbeatResponse hbResp; ReplicaSetConfig config; diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index 9df1c10e0c1..fb53986c747 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -249,11 +249,11 @@ namespace { ASSERT_EQUALS(HostAndPort("node2", 54321), noi->getRequest().target); ASSERT_EQUALS("admin", noi->getRequest().dbname); ASSERT_EQUALS(hbArgs.toBSON(), noi->getRequest().cmdObj); - getNet()->scheduleResponse(noi, startDate + 10, ResponseStatus(ErrorCodes::NoSuchKey, - "No response")); - getNet()->runUntil(startDate + 10); + getNet()->scheduleResponse(noi, startDate + Milliseconds(10), + ResponseStatus(ErrorCodes::NoSuchKey, "No response")); + getNet()->runUntil(startDate + Milliseconds(10)); getNet()->exitNetwork(); - ASSERT_EQUALS(startDate + 10, getNet()->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), getNet()->now()); prsiThread.join(); ASSERT_EQUALS(ErrorCodes::NodeNotFound, status); ASSERT_EQUALS(MemberState::RS_STARTUP, getReplCoord()->getMemberState().s); @@ -284,11 +284,11 @@ namespace { hbResp.setVersion(0); getNet()->scheduleResponse( noi, - startDate + 10, + startDate + Milliseconds(10), ResponseStatus(RemoteCommandResponse(hbResp.toBSON(), Milliseconds(8)))); - getNet()->runUntil(startDate + 10); + getNet()->runUntil(startDate + Milliseconds(10)); getNet()->exitNetwork(); - ASSERT_EQUALS(startDate + 10, getNet()->now()); + ASSERT_EQUALS(startDate + Milliseconds(10), getNet()->now()); prsiThread.join(); ASSERT_OK(status); ASSERT_EQUALS(ReplicationCoordinator::modeReplSet, getReplCoord()->getReplicationMode()); @@ -655,7 +655,7 @@ namespace { ReplicationAwaiter(ReplicationCoordinatorImpl* replCoord, OperationContext* txn) : _replCoord(replCoord), _finished(false), _result(ReplicationCoordinator::StatusAndDuration( - Status::OK(), ReplicationCoordinator::Milliseconds(0))) {} + Status::OK(), Milliseconds(0))) {} void setOpTime(const OpTime& ot) { _optime = ot; @@ -683,7 +683,7 @@ namespace { ASSERT(_finished); _finished = false; _result = ReplicationCoordinator::StatusAndDuration( - Status::OK(), ReplicationCoordinator::Milliseconds(0)); + Status::OK(), Milliseconds(0)); } private: @@ -960,7 +960,7 @@ namespace { simulateSuccessfulElection(); enterNetwork(); - getNet()->runUntil(getNet()->now() + 2000); + getNet()->runUntil(getNet()->now() + Seconds(2)); ASSERT(getNet()->hasReadyRequests()); NetworkInterfaceMock::NetworkOperationIterator noi = getNet()->getNextReadyRequest(); RemoteCommandRequest request = noi->getRequest(); @@ -987,7 +987,7 @@ namespace { ASSERT_TRUE(getReplCoord()->getMemberState().primary()); ASSERT_OK(getReplCoord()->stepDown(&txn, false, Milliseconds(0), Milliseconds(1000))); enterNetwork(); // So we can safely inspect the topology coordinator - ASSERT_EQUALS(Date_t(getNet()->now().millis + 1000), getTopoCoord().getStepDownTime()); + ASSERT_EQUALS(getNet()->now() + Seconds(1), getTopoCoord().getStepDownTime()); ASSERT_TRUE(getTopoCoord().getMemberState().secondary()); exitNetwork(); ASSERT_TRUE(getReplCoord()->getMemberState().secondary()); @@ -1007,7 +1007,7 @@ namespace { ASSERT_TRUE(getReplCoord()->getMemberState().primary()); ASSERT_OK(getReplCoord()->stepDown(&txn, true, Milliseconds(0), Milliseconds(1000))); getNet()->enterNetwork(); // Must do this before inspecting the topocoord - Date_t stepdownUntil = Date_t(getNet()->now().millis + 1000); + Date_t stepdownUntil = getNet()->now() + Seconds(1); ASSERT_EQUALS(stepdownUntil, getTopoCoord().getStepDownTime()); ASSERT_TRUE(getTopoCoord().getMemberState().secondary()); ASSERT_TRUE(getReplCoord()->getMemberState().secondary()); @@ -1111,11 +1111,11 @@ namespace { runner.reset(); getNet()->enterNetwork(); const Date_t startDate = getNet()->now(); - while (startDate + 1000 < getNet()->now()) { + while (startDate + Milliseconds(1000) < getNet()->now()) { while (getNet()->hasReadyRequests()) { getNet()->blackHole(getNet()->getNextReadyRequest()); } - getNet()->runUntil(startDate + 1000); + getNet()->runUntil(startDate + Milliseconds(1000)); } getNet()->exitNetwork(); ASSERT_TRUE(getReplCoord()->getMemberState().primary()); @@ -1148,7 +1148,7 @@ namespace { // Make a secondary actually catch up enterNetwork(); - getNet()->runUntil(getNet()->now() + 2000); + getNet()->runUntil(getNet()->now() + Milliseconds(2000)); ASSERT(getNet()->hasReadyRequests()); NetworkInterfaceMock::NetworkOperationIterator noi = getNet()->getNextReadyRequest(); RemoteCommandRequest request = noi->getRequest(); @@ -1506,7 +1506,7 @@ namespace { ASSERT_TRUE(response.isPassive()); ASSERT_FALSE(response.isHidden()); ASSERT_TRUE(response.shouldBuildIndexes()); - ASSERT_EQUALS(0, response.getSlaveDelay().total_seconds()); + ASSERT_EQUALS(Seconds(0), response.getSlaveDelay()); ASSERT_EQUALS(h4, response.getMe()); std::vector hosts = response.getHosts(); diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp index 160cb55281d..cc0e45329b1 100644 --- a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp +++ b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp @@ -191,7 +191,7 @@ namespace { net->scheduleResponse(noi, net->now(), makeResponseStatus( BSON("ok" << 1 << "fresher" << false << - "opTime" << Date_t(Timestamp(0, 0).asULL()) << + "opTime" << Date_t() << "veto" << false))); } else if (request.cmdObj.firstElement().fieldNameStringData() == "replSetElect") { @@ -234,7 +234,7 @@ namespace { while (replCoord->getMemberState().primary()) { log() << "Waiting on network in state " << replCoord->getMemberState(); getNet()->enterNetwork(); - net->runUntil(net->now() + 10000); + net->runUntil(net->now() + Seconds(10)); const NetworkInterfaceMock::NetworkOperationIterator noi = net->getNextReadyRequest(); const RemoteCommandRequest& request = noi->getRequest(); log() << request.target.toString() << " processing " << request.cmdObj; diff --git a/src/mongo/db/repl/replication_executor.cpp b/src/mongo/db/repl/replication_executor.cpp index 55090641b44..118ad0d0ded 100644 --- a/src/mongo/db/repl/replication_executor.cpp +++ b/src/mongo/db/repl/replication_executor.cpp @@ -293,8 +293,7 @@ namespace { scheduledRequest.expirationDate = RemoteCommandRequest::kNoExpirationDate; } else { - scheduledRequest.expirationDate = - _networkInterface->now() + scheduledRequest.timeout.total_milliseconds(); + scheduledRequest.expirationDate = _networkInterface->now() + scheduledRequest.timeout; } boost::lock_guard lk(_mutex); StatusWith handle = enqueueWork_inlock( @@ -466,7 +465,7 @@ namespace { return std::make_pair(WorkItem(), CallbackHandle()); } lk.unlock(); - if (nextWakeupDate == Date_t(~0ULL)) { + if (nextWakeupDate == Date_t::max()) { _networkInterface->waitForWork(); } else { @@ -493,7 +492,7 @@ namespace { _readyQueue.splice(_readyQueue.end(), _sleepersQueue, _sleepersQueue.begin(), iter); if (iter == _sleepersQueue.end()) { // indicate no sleeper to wait for - return Date_t(~0ULL); + return Date_t::max(); } return iter->readyDate; } diff --git a/src/mongo/db/repl/replication_executor.h b/src/mongo/db/repl/replication_executor.h index ea19ac411c2..c01bc48e648 100644 --- a/src/mongo/db/repl/replication_executor.h +++ b/src/mongo/db/repl/replication_executor.h @@ -28,7 +28,6 @@ #pragma once -#include #include #include #include @@ -110,7 +109,6 @@ namespace repl { class ReplicationExecutor { MONGO_DISALLOW_COPYING(ReplicationExecutor); public: - typedef boost::posix_time::milliseconds Milliseconds; struct CallbackData; class CallbackHandle; class EventHandle; diff --git a/src/mongo/db/repl/replication_executor_test.cpp b/src/mongo/db/repl/replication_executor_test.cpp index 5b1c62ea13d..a2894d5be15 100644 --- a/src/mongo/db/repl/replication_executor_test.cpp +++ b/src/mongo/db/repl/replication_executor_test.cpp @@ -284,22 +284,22 @@ namespace { Status status3(ErrorCodes::InternalError, "Not mutated"); const Date_t now = net->now(); const ReplicationExecutor::CallbackHandle cb1 = - unittest::assertGet(executor.scheduleWorkAt(Date_t(now.millis + 100), + unittest::assertGet(executor.scheduleWorkAt(now + Milliseconds(100), stdx::bind(setStatus, stdx::placeholders::_1, &status1))); - unittest::assertGet(executor.scheduleWorkAt(Date_t(now.millis + 5000), + unittest::assertGet(executor.scheduleWorkAt(now + Milliseconds(5000), stdx::bind(setStatus, stdx::placeholders::_1, &status3))); const ReplicationExecutor::CallbackHandle cb2 = - unittest::assertGet(executor.scheduleWorkAt(Date_t(now.millis + 200), + unittest::assertGet(executor.scheduleWorkAt(now + Milliseconds(200), stdx::bind(setStatusAndShutdown, stdx::placeholders::_1, &status2))); const Date_t startTime = net->now(); - net->runUntil(startTime + 200 /*ms*/); - ASSERT_EQUALS(startTime + 200, net->now()); + net->runUntil(startTime + Milliseconds(200)); + ASSERT_EQUALS(startTime + Milliseconds(200), net->now()); executor.wait(cb1); executor.wait(cb2); ASSERT_OK(status1); @@ -457,7 +457,7 @@ namespace { HostAndPort("lazy", 27017), "admin", BSON("sleep" << 1), - ReplicationExecutor::Milliseconds(1)); + Milliseconds(1)); ReplicationExecutor::CallbackHandle cbHandle = unittest::assertGet( executor.scheduleRemoteCommand( request, @@ -469,10 +469,10 @@ namespace { const Date_t startTime = net->now(); NetworkInterfaceMock::NetworkOperationIterator noi = net->getNextReadyRequest(); net->scheduleResponse(noi, - startTime + 2, + startTime + Milliseconds(2), ResponseStatus(ErrorCodes::ExceededTimeLimit, "I took too long")); - net->runUntil(startTime + 2); - ASSERT_EQUALS(startTime + 2, net->now()); + net->runUntil(startTime + Milliseconds(2)); + ASSERT_EQUALS(startTime + Milliseconds(2), net->now()); executor.wait(cbHandle); ASSERT_EQUALS(ErrorCodes::ExceededTimeLimit, status); } diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp index 147877e12c0..b33d03d7bf3 100644 --- a/src/mongo/db/repl/replication_info.cpp +++ b/src/mongo/db/repl/replication_info.cpp @@ -126,8 +126,9 @@ namespace repl { Query().sort( BSON( "$natural" << -1 ) ) ); bb.appendDate( "masterFirst" , first["ts"].timestampTime() ); bb.appendDate( "masterLast" , last["ts"].timestampTime() ); - double lag = (double) (last["ts"].timestampTime() - s["syncedTo"].timestampTime()); - bb.append( "lagSeconds" , lag / 1000 ); + const auto lag = + (last["ts"].timestampTime() - s["syncedTo"].timestampTime()); + bb.append("lagSeconds", durationCount(lag) / 1000.0); } conn.done(); } diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp index 342ee8e514b..c91cc42ec2d 100644 --- a/src/mongo/db/repl/replset_commands.cpp +++ b/src/mongo/db/repl/replset_commands.cpp @@ -534,8 +534,8 @@ namespace { status = getGlobalReplicationCoordinator()->stepDown( txn, force, - ReplicationCoordinator::Milliseconds(secondaryCatchUpPeriodSecs * 1000), - ReplicationCoordinator::Milliseconds(stepDownForSecs * 1000)); + Seconds(secondaryCatchUpPeriodSecs), + Seconds(stepDownForSecs)); return appendCommandStatus(result, status); } } cmdReplSetStepDown; diff --git a/src/mongo/db/repl/reporter_test.cpp b/src/mongo/db/repl/reporter_test.cpp index c060f714339..098096461c1 100644 --- a/src/mongo/db/repl/reporter_test.cpp +++ b/src/mongo/db/repl/reporter_test.cpp @@ -99,7 +99,7 @@ namespace { void ReporterTest::scheduleNetworkResponse(const BSONObj& obj) { NetworkInterfaceMock* net = getNet(); ASSERT_TRUE(net->hasReadyRequests()); - ReplicationExecutor::Milliseconds millis(0); + Milliseconds millis(0); RemoteCommandResponse response(obj, millis); ReplicationExecutor::ResponseStatus responseStatus(response); net->scheduleResponse(net->getNextReadyRequest(), net->now(), responseStatus); diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp index 174999bf601..374d700d828 100644 --- a/src/mongo/db/repl/rs_initialsync.cpp +++ b/src/mongo/db/repl/rs_initialsync.cpp @@ -356,7 +356,7 @@ namespace { truncateAndResetOplog(&txn, replCoord, bgsync); OplogReader r; - Timestamp now(Milliseconds(curTimeMillis64()).total_seconds(), 0); + Timestamp now(duration_cast(Milliseconds(curTimeMillis64())), 0); while (r.getHost().empty()) { // We must prime the sync source selector so that it considers all candidates regardless diff --git a/src/mongo/db/repl/scatter_gather_test.cpp b/src/mongo/db/repl/scatter_gather_test.cpp index a98c5a1f51f..1fc6765e58e 100644 --- a/src/mongo/db/repl/scatter_gather_test.cpp +++ b/src/mongo/db/repl/scatter_gather_test.cpp @@ -186,29 +186,29 @@ namespace { net->enterNetwork(); NetworkInterfaceMock::NetworkOperationIterator noi = net->getNextReadyRequest(); net->scheduleResponse(noi, - net->now()+2000, + net->now() + Seconds(2), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), - boost::posix_time::milliseconds(10)))); + Milliseconds(10)))); ASSERT_FALSE(ranCompletion); noi = net->getNextReadyRequest(); net->scheduleResponse(noi, - net->now()+2000, + net->now() + Seconds(2), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), - boost::posix_time::milliseconds(10)))); + Milliseconds(10)))); ASSERT_FALSE(ranCompletion); noi = net->getNextReadyRequest(); net->scheduleResponse(noi, - net->now()+5000, + net->now() + Seconds(5), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), - boost::posix_time::milliseconds(10)))); + Milliseconds(10)))); ASSERT_FALSE(ranCompletion); - net->runUntil(net->now()+2000); + net->runUntil(net->now() + Seconds(2)); ASSERT_TRUE(ranCompletion); delete sga; @@ -290,32 +290,31 @@ namespace { net->enterNetwork(); NetworkInterfaceMock::NetworkOperationIterator noi = net->getNextReadyRequest(); net->scheduleResponse(noi, - net->now()+2000, + net->now() + Seconds(2), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), - boost::posix_time::milliseconds(10)))); + Milliseconds(10)))); ASSERT_FALSE(ranCompletion); noi = net->getNextReadyRequest(); net->scheduleResponse(noi, - net->now()+2000, + net->now() + Seconds(2), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), - boost::posix_time::milliseconds(10)))); + Milliseconds(10)))); ASSERT_FALSE(ranCompletion); noi = net->getNextReadyRequest(); net->scheduleResponse(noi, - net->now()+5000, + net->now() + Seconds(5), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), - boost::posix_time::milliseconds(10)))); + Milliseconds(10)))); ASSERT_FALSE(ranCompletion); - net->runUntil(net->now()+2000); + net->runUntil(net->now() + Seconds(2)); ASSERT_TRUE(ranCompletion); - net->runReadyNetworkOperations(); // the third resposne should not be processed, so the count should not increment ASSERT_EQUALS(2, sga.getResponseCount()); @@ -400,7 +399,7 @@ namespace { net->now(), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), - boost::posix_time::milliseconds(10)))); + Milliseconds(10)))); net->runReadyNetworkOperations(); noi = net->getNextReadyRequest(); @@ -412,7 +411,7 @@ namespace { net->now(), ResponseStatus(RemoteCommandResponse( BSON("ok" << 1), - boost::posix_time::milliseconds(10)))); + Milliseconds(10)))); net->runReadyNetworkOperations(); net->exitNetwork(); diff --git a/src/mongo/db/repl/sync_source_feedback.cpp b/src/mongo/db/repl/sync_source_feedback.cpp index 674555f7c53..6773758ef7c 100644 --- a/src/mongo/db/repl/sync_source_feedback.cpp +++ b/src/mongo/db/repl/sync_source_feedback.cpp @@ -127,8 +127,7 @@ namespace repl { catch (const DBException& e) { log() << "SyncSourceFeedback error sending update: " << e.what() << endl; // blacklist sync target for .5 seconds and find a new one - replCoord->blacklistSyncSource(_syncTarget, - Date_t(curTimeMillis64() + 500)); + replCoord->blacklistSyncSource(_syncTarget, Date_t::now() + Milliseconds(500)); BackgroundSync::get()->clearSyncTarget(); _resetConnection(); return e.toStatus(); @@ -141,8 +140,7 @@ namespace repl { // to the syncsource having a newer config if (status != ErrorCodes::InvalidReplicaSetConfig || res["cfgver"].eoo() || res["cfgver"].numberLong() < replCoord->getConfig().getConfigVersion()) { - replCoord->blacklistSyncSource(_syncTarget, - Date_t(curTimeMillis64() + 500)); + replCoord->blacklistSyncSource(_syncTarget, Date_t::now() + Milliseconds(500)); BackgroundSync::get()->clearSyncTarget(); _resetConnection(); } diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp index 0f169b561f6..763a4067147 100644 --- a/src/mongo/db/repl/sync_tail.cpp +++ b/src/mongo/db/repl/sync_tail.cpp @@ -500,7 +500,7 @@ namespace { tryToGoLiveAsASecondary(&txn, replCoord); } - const int slaveDelaySecs = replCoord->getSlaveDelaySecs().total_seconds(); + const int slaveDelaySecs = replCoord->getSlaveDelaySecs().count(); if (!ops.empty() && slaveDelaySecs > 0) { const BSONObj& lastOp = ops.getDeque().back(); const unsigned int opTimestampSecs = lastOp["ts"].timestamp().getSecs(); @@ -620,7 +620,7 @@ namespace { void SyncTail::handleSlaveDelay(const BSONObj& lastOp) { ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator(); - int slaveDelaySecs = replCoord->getSlaveDelaySecs().total_seconds(); + int slaveDelaySecs = replCoord->getSlaveDelaySecs().count(); // ignore slaveDelay if the box is still initializing. once // it becomes secondary we can worry about it. @@ -645,7 +645,7 @@ namespace { sleepsecs(6); // Handle reconfigs that changed the slave delay - if (replCoord->getSlaveDelaySecs().total_seconds() != slaveDelaySecs) + if (replCoord->getSlaveDelaySecs().count() != slaveDelaySecs) break; } } diff --git a/src/mongo/db/repl/topology_coordinator_impl.cpp b/src/mongo/db/repl/topology_coordinator_impl.cpp index 497c9f43c04..9f0d069b1cb 100644 --- a/src/mongo/db/repl/topology_coordinator_impl.cpp +++ b/src/mongo/db/repl/topology_coordinator_impl.cpp @@ -68,7 +68,7 @@ namespace { // Interval between the time the last heartbeat from a node was received successfully, or // the time when we gave up retrying, and when the next heartbeat should be sent to a target. - const Milliseconds kHeartbeatInterval(Seconds(2).total_milliseconds()); + const auto kHeartbeatInterval = Seconds{2}; // Maximum number of retries for a failed heartbeat. const int kMaxHeartbeatRetries = 2; @@ -103,7 +103,6 @@ namespace { PingStats::PingStats() : count(0), value(std::numeric_limits::max()), - _lastHeartbeatStartDate(0), _numFailuresSinceLastStart(std::numeric_limits::max()) { } @@ -131,8 +130,6 @@ namespace { _maxSyncSourceLagSecs(maxSyncSourceLagSecs), _selfIndex(-1), _stepDownPending(false), - _stepDownUntil(0), - _electionSleepUntil(0), _maintenanceModeCalls(0), _followerMode(MemberState::RS_STARTUP2) { @@ -221,17 +218,17 @@ namespace { } else { // choose a time that will exclude no candidates, since we don't see a primary - primaryOpTime = Timestamp(_maxSyncSourceLagSecs.total_seconds(), 0); + primaryOpTime = Timestamp(_maxSyncSourceLagSecs, 0); } if (primaryOpTime.getSecs() < - static_cast(_maxSyncSourceLagSecs.total_seconds())) { + static_cast(_maxSyncSourceLagSecs.count())) { // erh - I think this means there was just a new election // and we don't yet know the new primary's optime - primaryOpTime = Timestamp(_maxSyncSourceLagSecs.total_seconds(), 0); + primaryOpTime = Timestamp(_maxSyncSourceLagSecs, 0); } - Timestamp oldestSyncOpTime(primaryOpTime.getSecs() - _maxSyncSourceLagSecs.total_seconds(), 0); + Timestamp oldestSyncOpTime(primaryOpTime.getSecs() - _maxSyncSourceLagSecs.count(), 0); int closestIndex = -1; @@ -482,7 +479,7 @@ namespace { else if (args.opTime < _latestKnownOpTime(lastOpApplied)) { weAreFresher = true; } - response->appendDate("opTime", lastOpApplied.asULL()); + response->appendDate("opTime", Date_t::fromMillisSinceEpoch(lastOpApplied.asLL())); response->append("fresher", weAreFresher); std::string errmsg; @@ -623,12 +620,12 @@ namespace { << highestPriority->getHostAndPort().toString(); vote = -10000; } - else if (_voteLease.when.millis + VoteLease::leaseTime.total_milliseconds() >= now.millis && + else if (_voteLease.when + VoteLease::leaseTime >= now && _voteLease.whoId != args.whoid) { log() << "replSet voting no for " << hopeful->getHostAndPort().toString() << "; voted for " << _voteLease.whoHostAndPort.toString() << ' ' - << (now.millis - _voteLease.when.millis) / 1000 << " secs ago"; + << durationCount(now - _voteLease.when) << " secs ago"; } else { _voteLease.when = now; @@ -705,7 +702,7 @@ namespace { // Heartbeat status message response->setHbMsg(_getHbmsg(now)); - response->setTime(Seconds(Milliseconds(now.asInt64()).total_seconds())); + response->setTime(duration_cast(now - Date_t{})); response->setOpTime(lastOpApplied); if (!_syncSource.empty()) { @@ -764,7 +761,7 @@ namespace { const HostAndPort& target) { PingStats& hbStats = _pings[target]; - Milliseconds alreadyElapsed(now.asInt64() - hbStats.getLastHeartbeatStartDate().asInt64()); + Milliseconds alreadyElapsed = now - hbStats.getLastHeartbeatStartDate(); if (!_rsConfig.isInitialized() || (hbStats.getNumFailuresSinceLastStart() > kMaxHeartbeatRetries) || (alreadyElapsed >= _rsConfig.getHeartbeatTimeoutPeriodMillis())) { @@ -794,10 +791,8 @@ namespace { const Milliseconds timeoutPeriod( _rsConfig.isInitialized() ? _rsConfig.getHeartbeatTimeoutPeriodMillis() : - Milliseconds( - ReplicaSetConfig::kDefaultHeartbeatTimeoutPeriod.total_milliseconds())); - const Milliseconds timeout( - timeoutPeriod.total_milliseconds() - alreadyElapsed.total_milliseconds()); + ReplicaSetConfig::kDefaultHeartbeatTimeoutPeriod); + const Milliseconds timeout = timeoutPeriod - alreadyElapsed; return std::make_pair(hbArgs, timeout); } @@ -810,12 +805,12 @@ namespace { const MemberState originalState = getMemberState(); PingStats& hbStats = _pings[target]; - invariant(hbStats.getLastHeartbeatStartDate() != Date_t(0)); + invariant(hbStats.getLastHeartbeatStartDate() != Date_t()); if (!hbResponse.isOK()) { hbStats.miss(); } else { - hbStats.hit(networkRoundTripTime.total_milliseconds()); + hbStats.hit(networkRoundTripTime.count()); // Log diagnostics. if (hbResponse.getValue().isStateDisagreement()) { LOG(1) << target << @@ -827,7 +822,7 @@ namespace { (hbResponse.getStatus().code() == ErrorCodes::Unauthorized) || (hbResponse.getStatus().code() == ErrorCodes::AuthenticationFailed); - Milliseconds alreadyElapsed(now.asInt64() - hbStats.getLastHeartbeatStartDate().asInt64()); + const Milliseconds alreadyElapsed = now - hbStats.getLastHeartbeatStartDate(); Date_t nextHeartbeatStartDate; // determine next start time if (_rsConfig.isInitialized() && @@ -835,13 +830,13 @@ namespace { (alreadyElapsed < _rsConfig.getHeartbeatTimeoutPeriodMillis())) { if (isUnauthorized) { - nextHeartbeatStartDate = now + kHeartbeatInterval.total_milliseconds(); + nextHeartbeatStartDate = now + kHeartbeatInterval; } else { nextHeartbeatStartDate = now; } } else { - nextHeartbeatStartDate = now + kHeartbeatInterval.total_milliseconds(); + nextHeartbeatStartDate = now + kHeartbeatInterval; } if (hbResponse.isOK() && hbResponse.getValue().hasConfig()) { @@ -912,7 +907,7 @@ namespace { LOG(3) << "Bad heartbeat response from " << target << "; trying again; Retries left: " << (kMaxHeartbeatRetries - hbStats.getNumFailuresSinceLastStart()) << - "; " << alreadyElapsed.total_milliseconds() << "ms have already elapsed"; + "; " << alreadyElapsed.count() << "ms have already elapsed"; } } else { @@ -997,9 +992,7 @@ namespace { << highestPriorityMember.getPriority() << " and is only " << (latestOpTime.getSecs() - highestPriorityMemberOptime.getSecs()) << " seconds behind me"; - const Date_t until = now + - VoteLease::leaseTime.total_milliseconds() + - kHeartbeatInterval.total_milliseconds(); + const Date_t until = now + VoteLease::leaseTime + kHeartbeatInterval; if (_electionSleepUntil < until) { _electionSleepUntil = until; } @@ -1337,7 +1330,8 @@ namespace { response->append("stateStr", myState.toString()); response->append("uptime", selfUptime); response->append("optime", lastOpApplied); - response->appendDate("optimeDate", Date_t(lastOpApplied.getSecs() * 1000ULL)); + response->appendDate("optimeDate", + Date_t::fromDurationSinceEpoch(Seconds(lastOpApplied.getSecs()))); if (_maintenanceModeCalls) { response->append("maintenanceMode", _maintenanceModeCalls); } @@ -1364,7 +1358,8 @@ namespace { bb.append("uptime", selfUptime); if (!_selfConfig().isArbiter()) { bb.append("optime", lastOpApplied); - bb.appendDate("optimeDate", Date_t(lastOpApplied.getSecs() * 1000ULL)); + bb.appendDate("optimeDate", + Date_t::fromDurationSinceEpoch(Seconds(lastOpApplied.getSecs()))); } if (!_syncSource.empty() && !_iAmPrimary()) { @@ -1381,7 +1376,8 @@ namespace { if (myState.primary()) { bb.append("electionTime", _electionTime); - bb.appendDate("electionDate", Date_t(_electionTime.getSecs() * 1000ULL)); + bb.appendDate("electionDate", + Date_t::fromDurationSinceEpoch(Seconds(_electionTime.getSecs()))); } bb.appendIntOrLL("configVersion", _rsConfig.getConfigVersion()); bb.append("self", true); @@ -1406,12 +1402,16 @@ namespace { bb.append("stateStr", it->getState().toString()); } - const unsigned int uptime = static_cast ((it->getUpSince() ? - (now - it->getUpSince()) / 1000 /* convert millis to secs */ : 0)); + const unsigned int uptime = static_cast( + (it->getUpSince() != Date_t()? + durationCount(now - it->getUpSince()) : + 0)); bb.append("uptime", uptime); if (!itConfig.isArbiter()) { bb.append("optime", it->getOpTime()); - bb.appendDate("optimeDate", Date_t(it->getOpTime().getSecs() * 1000ULL)); + bb.appendDate( + "optimeDate", + Date_t::fromDurationSinceEpoch(Seconds(it->getOpTime().getSecs()))); } bb.appendDate("lastHeartbeat", it->getLastHeartbeat()); bb.appendDate("lastHeartbeatRecv", it->getLastHeartbeatRecv()); @@ -1433,7 +1433,8 @@ namespace { if (state == MemberState::RS_PRIMARY) { bb.append("electionTime", it->getElectionTime()); bb.appendDate("electionDate", - Date_t(it->getElectionTime().getSecs() * 1000ULL)); + Date_t::fromDurationSinceEpoch( + Seconds(it->getElectionTime().getSecs()))); } bb.appendIntOrLL("configVersion", it->getConfigVersion()); membersOut.push_back(bb.obj()); @@ -1473,7 +1474,7 @@ namespace { { for (ReplicaSetConfig::MemberIterator it = _rsConfig.membersBegin(); it != _rsConfig.membersEnd(); ++it) { - if (it->isHidden() || it->getSlaveDelay().total_seconds() > 0) { + if (it->isHidden() || it->getSlaveDelay() > Seconds{0}) { continue; } @@ -1501,7 +1502,7 @@ namespace { else if (selfConfig.getPriority() == 0) { response->setIsPassive(true); } - if (selfConfig.getSlaveDelay().total_seconds()) { + if (selfConfig.getSlaveDelay().count()) { response->setSlaveDelay(selfConfig.getSlaveDelay()); } if (selfConfig.isHidden()) { @@ -1552,7 +1553,7 @@ namespace { response->append("warning", "you really want to freeze for only 1 second?"); if (!_iAmPrimary()) { - _stepDownUntil = std::max(_stepDownUntil, Date_t(now + (secs * 1000))); + _stepDownUntil = std::max(_stepDownUntil, now + Seconds(secs)); log() << "'freezing' for " << secs << " seconds"; } else { @@ -1679,7 +1680,7 @@ namespace { } std::string TopologyCoordinatorImpl::_getHbmsg(Date_t now) const { // ignore messages over 2 minutes old - if ((now - _hbmsgTime) > 120) { + if ((now - _hbmsgTime) > Seconds{120}) { return ""; } return _hbmsg; @@ -1747,7 +1748,7 @@ namespace { } if (_voteLease.whoId != -1 && _voteLease.whoId !=_rsConfig.getMemberAt(_selfIndex).getId() && - _voteLease.when.millis + VoteLease::leaseTime.total_milliseconds() >= now.millis) { + _voteLease.when + VoteLease::leaseTime >= now) { result |= VotedTooRecently; } @@ -1884,11 +1885,11 @@ namespace { return false; } int selfId = _selfConfig().getId(); - if ((_voteLease.when + VoteLease::leaseTime.total_milliseconds() >= now) + if ((_voteLease.when + VoteLease::leaseTime >= now) && (_voteLease.whoId != selfId)) { log() << "not voting yea for " << selfId << " voted for " << _voteLease.whoHostAndPort.toString() << ' ' << - (now - _voteLease.when) / 1000 << " secs ago"; + durationCount(now - _voteLease.when) << " secs ago"; return false; } _voteLease.when = now; @@ -1941,7 +1942,7 @@ namespace { // Clear voteLease time, if we voted for ourselves in this election. // This will allow us to vote for others. if (_voteLease.whoId == _selfConfig().getId()) { - _voteLease.when = 0; + _voteLease.when = Date_t(); } } @@ -2070,7 +2071,7 @@ namespace { return false; } unsigned int currentSecs = currentOpTime.getSecs(); - unsigned int goalSecs = currentSecs + _maxSyncSourceLagSecs.total_seconds(); + unsigned int goalSecs = currentSecs + _maxSyncSourceLagSecs.count(); for (std::vector::const_iterator it = _hbdata.begin(); it != _hbdata.end(); @@ -2084,7 +2085,7 @@ namespace { goalSecs < it->getOpTime().getSecs()) { log() << "changing sync target because current sync target's most recent OpTime is " << currentOpTime.toStringLong() << " which is more than " - << _maxSyncSourceLagSecs.total_seconds() << " seconds behind member " + << _maxSyncSourceLagSecs.count() << " seconds behind member " << candidateConfig.getHostAndPort().toString() << " whose most recent OpTime is " << it->getOpTime().toStringLong(); invariant(itIndex != _selfIndex); diff --git a/src/mongo/db/repl/topology_coordinator_impl.h b/src/mongo/db/repl/topology_coordinator_impl.h index d6914e4c7db..951dc62a5a7 100644 --- a/src/mongo/db/repl/topology_coordinator_impl.h +++ b/src/mongo/db/repl/topology_coordinator_impl.h @@ -404,9 +404,8 @@ namespace repl { static const Seconds leaseTime; - VoteLease() : when(0), whoId(-1) { } Date_t when; - int whoId; + int whoId = -1; HostAndPort whoHostAndPort; } _voteLease; diff --git a/src/mongo/db/repl/topology_coordinator_impl_test.cpp b/src/mongo/db/repl/topology_coordinator_impl_test.cpp index 8a38fc6e5c5..7dd54ae1e35 100644 --- a/src/mongo/db/repl/topology_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/topology_coordinator_impl_test.cpp @@ -53,6 +53,12 @@ namespace mongo { namespace repl { namespace { + Date_t operator++(Date_t& d, int) { + Date_t result = d; + d += Milliseconds(1); + return result; + } + bool stringContains(const std::string &haystack, const std::string& needle) { return haystack.find(needle) != std::string::npos; } @@ -61,7 +67,7 @@ namespace { public: virtual void setUp() { _topo.reset(new TopologyCoordinatorImpl(Seconds(100))); - _now = 0; + _now = Date_t(); _selfIndex = -1; _cbData.reset(new ReplicationExecutor::CallbackData( NULL, ReplicationExecutor::CallbackHandle(), Status::OK())); @@ -101,7 +107,7 @@ namespace { // If "now" is passed in, set _now to now+1 void updateConfig(BSONObj cfg, int selfIndex, - Date_t now = Date_t(-1), + Date_t now = Date_t::fromMillisSinceEpoch(-1), Timestamp lastOp = Timestamp()) { ReplicaSetConfig config; ASSERT_OK(config.initialize(cfg)); @@ -109,13 +115,14 @@ namespace { _selfIndex = selfIndex; - if (now == Date_t(-1)) { - getTopoCoord().updateConfig(config, selfIndex, _now++, lastOp); + if (now == Date_t::fromMillisSinceEpoch(-1)) { + getTopoCoord().updateConfig(config, selfIndex, _now, lastOp); + _now += Milliseconds(1); } else { invariant(now > _now); getTopoCoord().updateConfig(config, selfIndex, now, lastOp); - _now = now + 1; + _now = now + Milliseconds(1); } } @@ -143,8 +150,7 @@ namespace { ErrorCodes::Error errcode = ErrorCodes::HostUnreachable) { // timed out heartbeat to mark a node as down - Milliseconds roundTripTime{ - ReplicaSetConfig::kDefaultHeartbeatTimeoutPeriod.total_milliseconds()}; + Milliseconds roundTripTime{ReplicaSetConfig::kDefaultHeartbeatTimeoutPeriod}; return _receiveHeartbeatHelper(Status(errcode, ""), member, setName, @@ -194,7 +200,7 @@ namespace { getTopoCoord().prepareHeartbeatRequest(now(), setName, member); - now() += roundTripTime.total_milliseconds(); + now() += roundTripTime; return getTopoCoord().processHeartbeatResponse(now(), roundTripTime, member, @@ -498,8 +504,8 @@ namespace { getTopoCoord().chooseNewSyncSource(now()++, Timestamp(0,0)); ASSERT_EQUALS(HostAndPort("h3"), getTopoCoord().getSyncSourceAddress()); - - Date_t expireTime = 1000; + + Date_t expireTime = Date_t::fromMillisSinceEpoch(1000); getTopoCoord().blacklistSyncSource(HostAndPort("h3"), expireTime); getTopoCoord().chooseNewSyncSource(now()++, Timestamp(0,0)); // Should choose second best choice now that h3 is blacklisted. @@ -536,7 +542,7 @@ namespace { getTopoCoord().chooseNewSyncSource(now()++, Timestamp(0,0)); ASSERT_EQUALS(HostAndPort("h2"), getTopoCoord().getSyncSourceAddress()); - Date_t expireTime = 1000; + Date_t expireTime = Date_t::fromMillisSinceEpoch(1000); getTopoCoord().blacklistSyncSource(HostAndPort("h2"), expireTime); getTopoCoord().chooseNewSyncSource(now()++, Timestamp(0,0)); // Can't choose any sync source now. @@ -774,10 +780,10 @@ namespace { // information for replSetGetStatus from a different source than the nodes that aren't // ourself. After this setup, we call prepareStatusResponse and make sure that the fields // returned for each member match our expectations. - Date_t startupTime(100); - Date_t heartbeatTime = 5000; + Date_t startupTime = Date_t::fromMillisSinceEpoch(100); + Date_t heartbeatTime = Date_t::fromMillisSinceEpoch(5000); Seconds uptimeSecs(10); - Date_t curTime = heartbeatTime + uptimeSecs.total_milliseconds(); + Date_t curTime = heartbeatTime + uptimeSecs; Timestamp electionTime(1, 2); Timestamp oplogProgress(3, 4); std::string setName = "mySet"; @@ -789,16 +795,16 @@ namespace { BSON("_id" << 2 << "host" << "test2:1234") << BSON("_id" << 3 << "host" << "test3:1234"))), 3, - startupTime + 1); + startupTime + Milliseconds(1)); // Now that the replica set is setup, put the members into the states we want them in. HostAndPort member = HostAndPort("test0:1234"); StatusWith hbResponse = StatusWith(Status(ErrorCodes::HostUnreachable, "")); - getTopoCoord().prepareHeartbeatRequest(startupTime + 2, setName, member); - Date_t timeoutTime = startupTime + 2 + - ReplicaSetConfig::kDefaultHeartbeatTimeoutPeriod.total_milliseconds(); + getTopoCoord().prepareHeartbeatRequest(startupTime + Milliseconds(2), setName, member); + Date_t timeoutTime = startupTime + Milliseconds(2) + + ReplicaSetConfig::kDefaultHeartbeatTimeoutPeriod; getTopoCoord().processHeartbeatResponse(timeoutTime, Milliseconds(5000), member, @@ -813,7 +819,7 @@ namespace { hb.setHbMsg("READY"); hb.setOpTime(oplogProgress); hbResponse = StatusWith(hb); - getTopoCoord().prepareHeartbeatRequest(startupTime + 2, + getTopoCoord().prepareHeartbeatRequest(startupTime + Milliseconds(2), setName, member); getTopoCoord().processHeartbeatResponse(heartbeatTime, @@ -828,7 +834,7 @@ namespace { Status resultStatus(ErrorCodes::InternalError, "prepareStatusResponse didn't set result"); getTopoCoord().prepareStatusResponse(cbData(), curTime, - uptimeSecs.total_seconds(), + uptimeSecs.count(), oplogProgress, &statusBuilder, &resultStatus); @@ -853,8 +859,8 @@ namespace { ASSERT_EQUALS(0, member0Status["uptime"].numberInt()); ASSERT_EQUALS(Timestamp(), Timestamp(member0Status["optime"].timestampValue())); ASSERT_TRUE(member0Status.hasField("optimeDate")); - ASSERT_EQUALS(Date_t(Timestamp().getSecs() * 1000ULL), - member0Status["optimeDate"].Date().millis); + ASSERT_EQUALS(Date_t::fromMillisSinceEpoch(Timestamp().getSecs() * 1000ULL), + member0Status["optimeDate"].Date()); ASSERT_EQUALS(timeoutTime, member0Status["lastHeartbeat"].date()); ASSERT_EQUALS(Date_t(), member0Status["lastHeartbeatRecv"].date()); @@ -865,11 +871,11 @@ namespace { ASSERT_EQUALS(MemberState::RS_SECONDARY, member1Status["state"].numberInt()); ASSERT_EQUALS(MemberState(MemberState::RS_SECONDARY).toString(), member1Status["stateStr"].String()); - ASSERT_EQUALS(uptimeSecs.total_seconds(), member1Status["uptime"].numberInt()); + ASSERT_EQUALS(uptimeSecs.count(), member1Status["uptime"].numberInt()); ASSERT_EQUALS(oplogProgress, Timestamp(member1Status["optime"].timestampValue())); ASSERT_TRUE(member1Status.hasField("optimeDate")); - ASSERT_EQUALS(Date_t(oplogProgress.getSecs() * 1000ULL), - member1Status["optimeDate"].Date().millis); + ASSERT_EQUALS(Date_t::fromMillisSinceEpoch(oplogProgress.getSecs() * 1000ULL), + member1Status["optimeDate"].Date()); ASSERT_EQUALS(heartbeatTime, member1Status["lastHeartbeat"].date()); ASSERT_EQUALS(Date_t(), member1Status["lastHeartbeatRecv"].date()); ASSERT_EQUALS("READY", member1Status["lastHeartbeatMessage"].str()); @@ -897,11 +903,11 @@ namespace { ASSERT_EQUALS(MemberState::RS_PRIMARY, selfStatus["state"].numberInt()); ASSERT_EQUALS(MemberState(MemberState::RS_PRIMARY).toString(), selfStatus["stateStr"].str()); - ASSERT_EQUALS(uptimeSecs.total_seconds(), selfStatus["uptime"].numberInt()); + ASSERT_EQUALS(uptimeSecs.count(), selfStatus["uptime"].numberInt()); ASSERT_EQUALS(oplogProgress, Timestamp(selfStatus["optime"].timestampValue())); ASSERT_TRUE(selfStatus.hasField("optimeDate")); - ASSERT_EQUALS(Date_t(oplogProgress.getSecs() * 1000ULL), - selfStatus["optimeDate"].Date().millis); + ASSERT_EQUALS(Date_t::fromMillisSinceEpoch(oplogProgress.getSecs() * 1000ULL), + selfStatus["optimeDate"].Date()); // TODO(spencer): Test electionTime and pingMs are set properly } @@ -909,10 +915,10 @@ namespace { TEST_F(TopoCoordTest, ReplSetGetStatusFails) { // This test starts by configuring a TopologyCoordinator to NOT be a member of a 3 node // replica set. Then running prepareStatusResponse should fail. - Date_t startupTime(100); - Date_t heartbeatTime = 5000; + Date_t startupTime = Date_t::fromMillisSinceEpoch(100); + Date_t heartbeatTime = Date_t::fromMillisSinceEpoch(5000); Seconds uptimeSecs(10); - Date_t curTime = heartbeatTime + uptimeSecs.total_milliseconds(); + Date_t curTime = heartbeatTime + uptimeSecs; Timestamp oplogProgress(3, 4); std::string setName = "mySet"; @@ -922,13 +928,13 @@ namespace { BSON("_id" << 1 << "host" << "test1:1234") << BSON("_id" << 2 << "host" << "test2:1234"))), -1, // This one is not part of the replica set. - startupTime + 1); + startupTime + Milliseconds(1)); BSONObjBuilder statusBuilder; Status resultStatus(ErrorCodes::InternalError, "prepareStatusResponse didn't set result"); getTopoCoord().prepareStatusResponse(cbData(), curTime, - uptimeSecs.total_seconds(), + uptimeSecs.count(), oplogProgress, &statusBuilder, &resultStatus); @@ -1237,12 +1243,12 @@ namespace { "rs0", _target); // 5 seconds to successfully complete the heartbeat before the timeout expires. - ASSERT_EQUALS(5000, request.second.total_milliseconds()); + ASSERT_EQUALS(5000, request.second.count()); // Initial heartbeat request fails at t + 4000ms HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - _firstRequestDate + 4000, // 4 seconds elapsed, retry allowed. + _firstRequestDate + Seconds(4), // 4 seconds elapsed, retry allowed. Milliseconds(3990), // Spent 3.99 of the 4 seconds in the network. _target, StatusWith(ErrorCodes::ExceededTimeLimit, @@ -1252,23 +1258,23 @@ namespace { ASSERT_EQUALS(HeartbeatResponseAction::NoAction, action.getAction()); ASSERT_TRUE(TopologyCoordinator::Role::follower == getTopoCoord().getRole()); // Because the heartbeat failed without timing out, we expect to retry immediately. - ASSERT_EQUALS(Date_t(_firstRequestDate + 4000), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(_firstRequestDate + Seconds(4), action.getNextHeartbeatStartDate()); // First heartbeat retry prepared, at t + 4000ms. request = getTopoCoord().prepareHeartbeatRequest( - _firstRequestDate + 4000, + _firstRequestDate + Milliseconds(4000), "rs0", _target); // One second left to complete the heartbeat. - ASSERT_EQUALS(1000, request.second.total_milliseconds()); + ASSERT_EQUALS(1000, request.second.count()); // Ensure a single failed heartbeat did not cause the node to be marked down BSONObjBuilder statusBuilder; Status resultStatus(ErrorCodes::InternalError, "prepareStatusResponse didn't set result"); getTopoCoord().prepareStatusResponse(cbData(), - _firstRequestDate + 4000, + _firstRequestDate + Milliseconds(4000), 10, Timestamp(100,0), &statusBuilder, @@ -1282,7 +1288,7 @@ namespace { ASSERT_EQUALS(1, member1Status["health"].Double()); } - + Date_t firstRequestDate() { return _firstRequestDate; } @@ -1304,7 +1310,8 @@ namespace { // First retry fails at t + 4500ms HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 4500, // 4.5 of the 5 seconds elapsed; could retry. + firstRequestDate() + Milliseconds(4500), // 4.5 of the 5 seconds elapsed; + // could retry. Milliseconds(400), // Spent 0.4 of the 0.5 seconds in the network. target(), StatusWith(ErrorCodes::NodeNotFound, "Bad DNS?"), @@ -1312,31 +1319,32 @@ namespace { ASSERT_EQUALS(HeartbeatResponseAction::NoAction, action.getAction()); ASSERT_TRUE(TopologyCoordinator::Role::follower == getTopoCoord().getRole()); // Because the first retry failed without timing out, we expect to retry immediately. - ASSERT_EQUALS(Date_t(firstRequestDate() + 4500), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(4500), + action.getNextHeartbeatStartDate()); // Second retry prepared at t + 4500ms. std::pair request = getTopoCoord().prepareHeartbeatRequest( - firstRequestDate() + 4500, + firstRequestDate() + Milliseconds(4500), "rs0", target()); // 500ms left to complete the heartbeat. - ASSERT_EQUALS(500, request.second.total_milliseconds()); - - // Ensure a second failed heartbeat did not cause the node to be marked down - BSONObjBuilder statusBuilder; - Status resultStatus(ErrorCodes::InternalError, - "prepareStatusResponse didn't set result"); - getTopoCoord().prepareStatusResponse(cbData(), - firstRequestDate() + 4000, - 10, - Timestamp(100,0), - &statusBuilder, - &resultStatus); - ASSERT_OK(resultStatus); - BSONObj rsStatus = statusBuilder.obj(); - std::vector memberArray = rsStatus["members"].Array(); - BSONObj member1Status = memberArray[1].Obj(); + ASSERT_EQUALS(500, request.second.count()); + + // Ensure a second failed heartbeat did not cause the node to be marked down + BSONObjBuilder statusBuilder; + Status resultStatus(ErrorCodes::InternalError, + "prepareStatusResponse didn't set result"); + getTopoCoord().prepareStatusResponse(cbData(), + firstRequestDate() + Milliseconds(4000), + 10, + Timestamp(100,0), + &statusBuilder, + &resultStatus); + ASSERT_OK(resultStatus); + BSONObj rsStatus = statusBuilder.obj(); + std::vector memberArray = rsStatus["members"].Array(); + BSONObj member1Status = memberArray[1].Obj(); ASSERT_EQUALS(1, member1Status["_id"].Int()); ASSERT_EQUALS(1, member1Status["health"].Double()); @@ -1499,14 +1507,14 @@ namespace { reconfigResponse.setConfig(newConfig); HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 4500, // Time is left. + firstRequestDate() + Milliseconds(4500), // Time is left. Milliseconds(400), // Spent 0.4 of the 0.5 second in the network. target(), StatusWith(reconfigResponse), Timestamp(0, 0)); // We've never applied anything. ASSERT_EQUALS(HeartbeatResponseAction::Reconfig, action.getAction()); ASSERT_TRUE(TopologyCoordinator::Role::follower == getTopoCoord().getRole()); - ASSERT_EQUALS(Date_t(firstRequestDate() + 6500), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(6500), action.getNextHeartbeatStartDate()); } TEST_F(HeartbeatResponseTestOneRetry, DecideToStepDownRemotePrimary) { @@ -1527,14 +1535,14 @@ namespace { electedMoreRecentlyResponse.setVersion(5); HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 4500, // Time is left. + firstRequestDate() + Milliseconds(4500), // Time is left. Milliseconds(400), // Spent 0.4 of the 0.5 second in the network. target(), StatusWith(electedMoreRecentlyResponse), Timestamp(0,0)); // We've never applied anything. ASSERT_EQUALS(HeartbeatResponseAction::StepDownRemotePrimary, action.getAction()); ASSERT_EQUALS(1, action.getPrimaryConfigIndex()); - ASSERT_EQUALS(Date_t(firstRequestDate() + 6500), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(6500), action.getNextHeartbeatStartDate()); } TEST_F(HeartbeatResponseTestOneRetry, DecideToStepDownSelf) { @@ -1559,14 +1567,14 @@ namespace { electedMoreRecentlyResponse.setVersion(5); action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 4500, // Time is left. + firstRequestDate() + Milliseconds(4500), // Time is left. Milliseconds(400), // Spent 0.4 of the 0.5 second in the network. target(), StatusWith(electedMoreRecentlyResponse), Timestamp(0, 0)); // We've never applied anything. ASSERT_EQUALS(HeartbeatResponseAction::StepDownSelf, action.getAction()); ASSERT_EQUALS(0, action.getPrimaryConfigIndex()); - ASSERT_EQUALS(Date_t(firstRequestDate() + 6500), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(6500), action.getNextHeartbeatStartDate()); // Doesn't actually do the stepdown until stepDownIfPending is called ASSERT_TRUE(TopologyCoordinator::Role::leader == getTopoCoord().getRole()); ASSERT_EQUALS(0, getCurrentPrimaryIndex()); @@ -1602,14 +1610,14 @@ namespace { startElectionResponse.setVersion(5); action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 4500, // Time is left. + firstRequestDate() + Milliseconds(4500), // Time is left. Milliseconds(400), // Spent 0.4 of the 0.5 second in the network. target(), StatusWith(startElectionResponse), election); ASSERT_EQUALS(HeartbeatResponseAction::StartElection, action.getAction()); ASSERT_TRUE(TopologyCoordinator::Role::candidate == getTopoCoord().getRole()); - ASSERT_EQUALS(Date_t(firstRequestDate() + 6500), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(6500), action.getNextHeartbeatStartDate()); } TEST_F(HeartbeatResponseTestTwoRetries, HeartbeatRetriesAtMostTwice) { @@ -1625,7 +1633,8 @@ namespace { // Second retry fails at t + 4800ms HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 4800, // 4.8 of the 5 seconds elapsed; could still retry. + firstRequestDate() + Milliseconds(4800), // 4.8 of the 5 seconds elapsed; + // could still retry. Milliseconds(100), // Spent 0.1 of the 0.3 seconds in the network. target(), StatusWith(ErrorCodes::NodeNotFound, "Bad DNS?"), @@ -1634,24 +1643,25 @@ namespace { ASSERT_TRUE(TopologyCoordinator::Role::follower == getTopoCoord().getRole()); // Because this is the second retry, rather than retry again, we expect to wait for the // heartbeat interval of 2 seconds to elapse. - ASSERT_EQUALS(Date_t(firstRequestDate() + 6800), action.getNextHeartbeatStartDate()); - - // Ensure a third failed heartbeat caused the node to be marked down - BSONObjBuilder statusBuilder; - Status resultStatus(ErrorCodes::InternalError, - "prepareStatusResponse didn't set result"); - getTopoCoord().prepareStatusResponse(cbData(), - firstRequestDate() + 4900, - 10, - Timestamp(100,0), - &statusBuilder, - &resultStatus); - ASSERT_OK(resultStatus); - BSONObj rsStatus = statusBuilder.obj(); - std::vector memberArray = rsStatus["members"].Array(); - BSONObj member1Status = memberArray[1].Obj(); - - ASSERT_EQUALS(1, member1Status["_id"].Int()); + + ASSERT_EQUALS(firstRequestDate() + Milliseconds(6800), action.getNextHeartbeatStartDate()); + + // Ensure a third failed heartbeat caused the node to be marked down + BSONObjBuilder statusBuilder; + Status resultStatus(ErrorCodes::InternalError, + "prepareStatusResponse didn't set result"); + getTopoCoord().prepareStatusResponse(cbData(), + firstRequestDate() + Milliseconds(4900), + 10, + Timestamp(100,0), + &statusBuilder, + &resultStatus); + ASSERT_OK(resultStatus); + BSONObj rsStatus = statusBuilder.obj(); + std::vector memberArray = rsStatus["members"].Array(); + BSONObj member1Status = memberArray[1].Obj(); + + ASSERT_EQUALS(1, member1Status["_id"].Int()); ASSERT_EQUALS(0, member1Status["health"].Double()); } @@ -1673,14 +1683,14 @@ namespace { electedMoreRecentlyResponse.setVersion(5); HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 5000, // Time is left. + firstRequestDate() + Milliseconds(5000), // Time is left. Milliseconds(400), // Spent 0.4 of the 0.5 second in the network. target(), StatusWith(electedMoreRecentlyResponse), Timestamp(0,0)); // We've never applied anything. ASSERT_EQUALS(HeartbeatResponseAction::StepDownRemotePrimary, action.getAction()); ASSERT_EQUALS(1, action.getPrimaryConfigIndex()); - ASSERT_EQUALS(Date_t(firstRequestDate() + 7000), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(7000), action.getNextHeartbeatStartDate()); } TEST_F(HeartbeatResponseTestTwoRetries, DecideToStepDownSelf) { @@ -1705,14 +1715,14 @@ namespace { electedMoreRecentlyResponse.setVersion(5); action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 5000, // Time is left. + firstRequestDate() + Milliseconds(5000), // Time is left. Milliseconds(400), // Spent 0.4 of the 0.5 second in the network. target(), StatusWith(electedMoreRecentlyResponse), Timestamp(0, 0)); // We've never applied anything. ASSERT_EQUALS(HeartbeatResponseAction::StepDownSelf, action.getAction()); ASSERT_EQUALS(0, action.getPrimaryConfigIndex()); - ASSERT_EQUALS(Date_t(firstRequestDate() + 7000), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(7000), action.getNextHeartbeatStartDate()); // Doesn't actually do the stepdown until stepDownIfPending is called ASSERT_TRUE(TopologyCoordinator::Role::leader == getTopoCoord().getRole()); ASSERT_EQUALS(0, getCurrentPrimaryIndex()); @@ -1748,14 +1758,14 @@ namespace { startElectionResponse.setVersion(5); action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 5000, // Time is left. + firstRequestDate() + Milliseconds(5000), // Time is left. Milliseconds(400), // Spent 0.4 of the 0.5 second in the network. target(), StatusWith(startElectionResponse), election); ASSERT_EQUALS(HeartbeatResponseAction::StartElection, action.getAction()); ASSERT_TRUE(TopologyCoordinator::Role::candidate == getTopoCoord().getRole()); - ASSERT_EQUALS(Date_t(firstRequestDate() + 7000), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(7000), action.getNextHeartbeatStartDate()); } TEST_F(HeartbeatResponseTest, HeartbeatTimeoutSuppressesFirstRetry) { @@ -1771,12 +1781,13 @@ namespace { "rs0", target); // 5 seconds to successfully complete the heartbeat before the timeout expires. - ASSERT_EQUALS(5000, request.second.total_milliseconds()); + ASSERT_EQUALS(5000, request.second.count()); // Initial heartbeat request fails at t + 5000ms HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - firstRequestDate + 5000, // Entire heartbeat period elapsed; no retry allowed. + firstRequestDate + Milliseconds(5000), // Entire heartbeat period elapsed; + // no retry allowed. Milliseconds(4990), // Spent 4.99 of the 4 seconds in the network. target, StatusWith(ErrorCodes::ExceededTimeLimit, @@ -1786,7 +1797,7 @@ namespace { ASSERT_EQUALS(HeartbeatResponseAction::NoAction, action.getAction()); ASSERT_TRUE(TopologyCoordinator::Role::follower == getTopoCoord().getRole()); // Because the heartbeat timed out, we'll retry in 2 seconds. - ASSERT_EQUALS(Date_t(firstRequestDate + 7000), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate + Milliseconds(7000), action.getNextHeartbeatStartDate()); } TEST_F(HeartbeatResponseTestOneRetry, HeartbeatTimeoutSuppressesSecondRetry) { @@ -1794,7 +1805,8 @@ namespace { // the heartbeat timeout period expired before the first retry completed. HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 5010, // Entire heartbeat period elapsed; no retry allowed. + firstRequestDate() + Milliseconds(5010), // Entire heartbeat period elapsed; + // no retry allowed. Milliseconds(1000), // Spent 1 of the 1.01 seconds in the network. target(), StatusWith(ErrorCodes::ExceededTimeLimit, @@ -1804,7 +1816,7 @@ namespace { ASSERT_EQUALS(HeartbeatResponseAction::NoAction, action.getAction()); ASSERT_TRUE(TopologyCoordinator::Role::follower == getTopoCoord().getRole()); // Because the heartbeat timed out, we'll retry in 2 seconds. - ASSERT_EQUALS(Date_t(firstRequestDate() + 7010), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(7010), action.getNextHeartbeatStartDate()); } TEST_F(HeartbeatResponseTestTwoRetries, HeartbeatThreeNonconsecutiveFailures) { @@ -1820,7 +1832,7 @@ namespace { // successful response (third response due to the two failures in setUp()) HeartbeatResponseAction action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 4500, + firstRequestDate() + Milliseconds(4500), Milliseconds(400), target(), StatusWith(response), @@ -1829,13 +1841,14 @@ namespace { ASSERT_EQUALS(HeartbeatResponseAction::NoAction, action.getAction()); ASSERT_TRUE(TopologyCoordinator::Role::follower == getTopoCoord().getRole()); // Because the heartbeat succeeded, we'll retry in 2 seconds. - ASSERT_EQUALS(Date_t(firstRequestDate() + 6500), action.getNextHeartbeatStartDate()); + ASSERT_EQUALS(firstRequestDate() + Milliseconds(6500), action.getNextHeartbeatStartDate()); // request next heartbeat - getTopoCoord().prepareHeartbeatRequest(firstRequestDate() + 6500, "rs0", target()); + getTopoCoord().prepareHeartbeatRequest( + firstRequestDate() + Milliseconds(6500), "rs0", target()); // third failed response action = getTopoCoord().processHeartbeatResponse( - firstRequestDate() + 7100, + firstRequestDate() + Milliseconds(7100), Milliseconds(400), target(), StatusWith(Status{ErrorCodes::HostUnreachable, ""}), @@ -1849,7 +1862,7 @@ namespace { Status resultStatus(ErrorCodes::InternalError, "prepareStatusResponse didn't set result"); getTopoCoord().prepareStatusResponse(cbData(), - firstRequestDate() + 7000, + firstRequestDate() + Milliseconds(7000), 600, Timestamp(100,0), &statusBuilder, @@ -2352,8 +2365,8 @@ namespace { // 4. TopologyCoordinator concludes its freshness round successfully and wins the election. setSelfMemberState(MemberState::RS_SECONDARY); - now() += 30000; // we need to be more than LastVote::leaseTime from the start of time or - // else some Date_t math goes horribly awry + now() += Seconds(30); // we need to be more than LastVote::leaseTime from the start of time or + // else some Date_t math goes horribly awry Timestamp election = Timestamp(0,0); Timestamp lastOpTimeApplied = Timestamp(130,0); @@ -2422,8 +2435,8 @@ namespace { // 6. The TopologyCoordinator loses the election. setSelfMemberState(MemberState::RS_SECONDARY); - now() += 30000; // we need to be more than LastVote::leaseTime from the start of time or - // else some Date_t math goes horribly awry + now() += Seconds(30); // we need to be more than LastVote::leaseTime from the start of time or + // else some Date_t math goes horribly awry Timestamp election = Timestamp(0,0); Timestamp lastOpTimeApplied = Timestamp(100,0); @@ -2540,8 +2553,8 @@ namespace { // 5. "host3" sends an elect command, which the TopologyCoordinator responds to negatively. setSelfMemberState(MemberState::RS_SECONDARY); - now() += 30000; // we need to be more than LastVote::leaseTime from the start of time or - // else some Date_t math goes horribly awry + now() += Seconds(30); // we need to be more than LastVote::leaseTime from the start of time or + // else some Date_t math goes horribly awry Timestamp election = Timestamp(0,0); Timestamp lastOpTimeApplied = Timestamp(100,0); @@ -2637,8 +2650,8 @@ namespace { // 5. "host3" sends an elect command, which the TopologyCoordinator responds to negatively. setSelfMemberState(MemberState::RS_SECONDARY); - now() += 30000; // we need to be more than LastVote::leaseTime from the start of time or - // else some Date_t math goes horribly awry + now() += Seconds(30); // we need to be more than LastVote::leaseTime from the start of time or + // else some Date_t math goes horribly awry Timestamp election = Timestamp(0,0); Timestamp lastOpTimeApplied = Timestamp(100,0); @@ -2820,7 +2833,6 @@ namespace { public: PrepareElectResponseTest() : - now(0), round(OID::gen()), cbData(NULL, ReplicationExecutor::CallbackHandle(), Status::OK()) {} @@ -2857,7 +2869,8 @@ namespace { BSONObjBuilder responseBuilder; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder, &result); stopCapturingLogMessages(); BSONObj response = responseBuilder.obj(); ASSERT_OK(result); @@ -2887,7 +2900,8 @@ namespace { BSONObjBuilder responseBuilder; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder, &result); stopCapturingLogMessages(); BSONObj response = responseBuilder.obj(); ASSERT_OK(result); @@ -2916,7 +2930,8 @@ namespace { BSONObjBuilder responseBuilder; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder, &result); stopCapturingLogMessages(); BSONObj response = responseBuilder.obj(); ASSERT_OK(result); @@ -2945,7 +2960,8 @@ namespace { BSONObjBuilder responseBuilder; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder, &result); stopCapturingLogMessages(); BSONObj response = responseBuilder.obj(); ASSERT_OK(result); @@ -2975,7 +2991,8 @@ namespace { BSONObjBuilder responseBuilder; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder, &result); stopCapturingLogMessages(); BSONObj response = responseBuilder.obj(); ASSERT_OK(result); @@ -3004,7 +3021,8 @@ namespace { BSONObjBuilder responseBuilder; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder, &result); stopCapturingLogMessages(); BSONObj response = responseBuilder.obj(); ASSERT_OK(result); @@ -3029,12 +3047,13 @@ namespace { args.cfgver = 10; args.whoid = 1; - heartbeatFromMember(HostAndPort("h3"), "rs0", MemberState::RS_SECONDARY, jsTime()); + heartbeatFromMember(HostAndPort("h3"), "rs0", MemberState::RS_SECONDARY, Timestamp(0, 0)); BSONObjBuilder responseBuilder; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder, &result); stopCapturingLogMessages(); BSONObj response = responseBuilder.obj(); ASSERT_OK(result); @@ -3066,7 +3085,8 @@ namespace { BSONObjBuilder responseBuilder; Status result = Status::OK(); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder, &result); stopCapturingLogMessages(); BSONObj response = responseBuilder.obj(); ASSERT_EQUALS(1, response["vote"].Int()); @@ -3080,12 +3100,13 @@ namespace { args.round = round; args.cfgver = 10; args.whoid = 2; - now = 100; + now = Date_t::fromMillisSinceEpoch(100); BSONObjBuilder responseBuilder1; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); startCapturingLogMessages(); - getTopoCoord().prepareElectResponse(args, now += 60000, Timestamp(), &responseBuilder1, &result); + getTopoCoord().prepareElectResponse( + args, now += Seconds(60), Timestamp(), &responseBuilder1, &result); stopCapturingLogMessages(); BSONObj response1 = responseBuilder1.obj(); ASSERT_OK(result); @@ -3108,7 +3129,7 @@ namespace { "voted for h2:27017 0 secs ago")); // Test that after enough time passes the same vote can proceed - now += 30 * 1000 + 1; // just over 30 seconds later + now += Seconds(30) + Milliseconds(1); // just over 30 seconds later BSONObjBuilder responseBuilder3; startCapturingLogMessages(); @@ -3254,7 +3275,7 @@ namespace { Status result = Status::OK(); BSONObjBuilder response; getTopoCoord().prepareStatusResponse(cbData(), - Date_t(0), + Date_t(), 0, Timestamp(0,0), &response, @@ -3357,7 +3378,7 @@ namespace { ASSERT_TRUE(response.isReplSet()); ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s); ASSERT_EQUALS(Timestamp(0,0), response.getOpTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); ASSERT_EQUALS("", response.getHbMsg()); ASSERT_EQUALS("rs0", response.getReplicaSetName()); ASSERT_EQUALS(1, response.getVersion()); @@ -3380,7 +3401,7 @@ namespace { ASSERT_TRUE(response.isReplSet()); ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s); ASSERT_EQUALS(Timestamp(0,0), response.getOpTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); ASSERT_EQUALS("", response.getHbMsg()); ASSERT_EQUALS("rs0", response.getReplicaSetName()); ASSERT_EQUALS(1, response.getVersion()); @@ -3404,7 +3425,7 @@ namespace { ASSERT_TRUE(response.isReplSet()); ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s); ASSERT_EQUALS(Timestamp(0,0), response.getOpTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); ASSERT_EQUALS("", response.getHbMsg()); ASSERT_EQUALS("rs0", response.getReplicaSetName()); ASSERT_EQUALS(1, response.getVersion()); @@ -3428,7 +3449,7 @@ namespace { ASSERT_TRUE(response.isReplSet()); ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s); ASSERT_EQUALS(Timestamp(0,0), response.getOpTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); ASSERT_EQUALS("", response.getHbMsg()); ASSERT_EQUALS("rs0", response.getReplicaSetName()); ASSERT_EQUALS(1, response.getVersion()); @@ -3451,7 +3472,7 @@ namespace { ASSERT_TRUE(response.isReplSet()); ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s); ASSERT_EQUALS(Timestamp(0,0), response.getOpTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); ASSERT_EQUALS("", response.getHbMsg()); ASSERT_EQUALS("rs0", response.getReplicaSetName()); ASSERT_EQUALS(1, response.getVersion()); @@ -3477,7 +3498,7 @@ namespace { ASSERT_TRUE(response.isReplSet()); ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s); ASSERT_EQUALS(Timestamp(100,0), response.getOpTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); ASSERT_EQUALS("", response.getHbMsg()); ASSERT_EQUALS("rs0", response.getReplicaSetName()); ASSERT_EQUALS(1, response.getVersion()); @@ -3503,7 +3524,7 @@ namespace { ASSERT_TRUE(response.isReplSet()); ASSERT_EQUALS(MemberState::RS_STARTUP, response.getState().s); ASSERT_EQUALS(Timestamp(0,0), response.getOpTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); ASSERT_EQUALS("", response.getHbMsg()); ASSERT_EQUALS("", response.getReplicaSetName()); ASSERT_EQUALS(-2, response.getVersion()); @@ -3530,7 +3551,7 @@ namespace { ASSERT_EQUALS(MemberState::RS_PRIMARY, response.getState().s); ASSERT_EQUALS(Timestamp(11,0), response.getOpTime()); ASSERT_EQUALS(Timestamp(10,0), response.getElectionTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); ASSERT_EQUALS("", response.getHbMsg()); ASSERT_EQUALS("rs0", response.getReplicaSetName()); ASSERT_EQUALS(1, response.getVersion()); @@ -3560,7 +3581,7 @@ namespace { ASSERT_TRUE(response.isReplSet()); ASSERT_EQUALS(MemberState::RS_SECONDARY, response.getState().s); ASSERT_EQUALS(Timestamp(100,0), response.getOpTime()); - ASSERT_EQUALS(Seconds(0).total_milliseconds(), response.getTime().total_milliseconds()); + ASSERT_EQUALS(0, response.getTime().count()); // changed to a syncing message because our sync source changed recently ASSERT_EQUALS("syncing from: h2:27017", response.getHbMsg()); ASSERT_EQUALS("rs0", response.getReplicaSetName()); @@ -3770,7 +3791,7 @@ namespace { BSON("_id" << 1 << "host" << "host2:27017") << BSON("_id" << 2 << "host" << "host3:27017"))), 0, - Date_t(-1), + Date_t::fromMillisSinceEpoch(-1), Timestamp(10,0)); ASSERT_TRUE(TopologyCoordinator::Role::leader == getTopoCoord().getRole()); ASSERT_EQUALS(MemberState::RS_PRIMARY, getTopoCoord().getMemberState().s); @@ -3785,7 +3806,7 @@ namespace { "priority" << 5 << "tags" << BSON("dc" << "NA" << "rack" << "rack1")))), 0, - Date_t(-1), + Date_t::fromMillisSinceEpoch(-1), Timestamp(10,0)); ASSERT_TRUE(TopologyCoordinator::Role::leader == getTopoCoord().getRole()); ASSERT_EQUALS(MemberState::RS_PRIMARY, getTopoCoord().getMemberState().s); @@ -3986,17 +4007,17 @@ namespace { fresherLastOpTimeApplied, lastOpTimeApplied); ASSERT_NO_ACTION(nextAction.getAction()); - getTopoCoord().blacklistSyncSource(HostAndPort("host3"), now() + 100); + getTopoCoord().blacklistSyncSource(HostAndPort("host3"), now() + Milliseconds(100)); // set up complete, time for actual check ASSERT_FALSE(getTopoCoord().shouldChangeSyncSource(HostAndPort("host2"), now())); // unblacklist with too early a time (node should remained blacklisted) - getTopoCoord().unblacklistSyncSource(HostAndPort("host3"), now() + 90); + getTopoCoord().unblacklistSyncSource(HostAndPort("host3"), now() + Milliseconds(90)); ASSERT_FALSE(getTopoCoord().shouldChangeSyncSource(HostAndPort("host2"), now())); // unblacklist and it should succeed - getTopoCoord().unblacklistSyncSource(HostAndPort("host3"), now() + 100); + getTopoCoord().unblacklistSyncSource(HostAndPort("host3"), now() + Milliseconds(100)); startCapturingLogMessages(); ASSERT_TRUE(getTopoCoord().shouldChangeSyncSource(HostAndPort("host2"), now())); stopCapturingLogMessages(); @@ -4219,7 +4240,7 @@ namespace { electArgs.whoid = 20; // need to be 30 secs beyond the start of time to pass last vote lease - now() += 30*1000; + now() += Seconds(30); BSONObjBuilder electResponseBuilder; Status result = Status(ErrorCodes::InternalError, "status not set by prepareElectResponse"); getTopoCoord().prepareElectResponse( diff --git a/src/mongo/db/stats/range_deleter_server_status.cpp b/src/mongo/db/stats/range_deleter_server_status.cpp index 408f7049920..e625e16f01b 100644 --- a/src/mongo/db/stats/range_deleter_server_status.cpp +++ b/src/mongo/db/stats/range_deleter_server_status.cpp @@ -74,16 +74,16 @@ namespace mongo { BSONObjBuilder entryBuilder; entryBuilder.append("deletedDocs", (*it)->deletedDocCount); - if ((*it)->queueEndTS.millis > 0) { + if ((*it)->queueEndTS > Date_t()) { entryBuilder.append("queueStart", (*it)->queueStartTS); entryBuilder.append("queueEnd", (*it)->queueEndTS); } - if ((*it)->deleteEndTS.millis > 0) { + if ((*it)->deleteEndTS > Date_t()) { entryBuilder.append("deleteStart", (*it)->deleteStartTS); entryBuilder.append("deleteEnd", (*it)->deleteEndTS); - if ((*it)->waitForReplEndTS.millis > 0) { + if ((*it)->waitForReplEndTS > Date_t()) { entryBuilder.append("waitForReplStart", (*it)->waitForReplStartTS); entryBuilder.append("waitForReplEnd", (*it)->waitForReplEndTS); } diff --git a/src/mongo/db/storage/key_string.cpp b/src/mongo/db/storage/key_string.cpp index 0df4a8d8096..c77e5fc2e72 100644 --- a/src/mongo/db/storage/key_string.cpp +++ b/src/mongo/db/storage/key_string.cpp @@ -755,8 +755,8 @@ namespace mongo { case CType::kBoolFalse: *stream << false; break; case CType::kDate: - *stream << Date_t(endian::bigToNative(readType(reader, - inverted)) ^ (1LL << 63)); + *stream << Date_t::fromMillisSinceEpoch( + endian::bigToNative(readType(reader, inverted)) ^ (1LL << 63)); break; case CType::kTimestamp: diff --git a/src/mongo/db/storage/key_string_test.cpp b/src/mongo/db/storage/key_string_test.cpp index 267f1ba6501..e085be8fbb9 100644 --- a/src/mongo/db/storage/key_string_test.cpp +++ b/src/mongo/db/storage/key_string_test.cpp @@ -144,7 +144,7 @@ TEST(KeyStringTest, AllTypesSimple) { ROUNDTRIP(BSON("" << BSONUndefined)); ROUNDTRIP(BSON("" << OID("abcdefabcdefabcdefabcdef"))); ROUNDTRIP(BSON("" << true)); - ROUNDTRIP(BSON("" << Date_t(123123123))); + ROUNDTRIP(BSON("" << Date_t::fromMillisSinceEpoch(123123123))); ROUNDTRIP(BSON("" << BSONRegEx("asdf", "x"))); ROUNDTRIP(BSON("" << BSONDBRef("db.c", OID("010203040506070809101112")))); ROUNDTRIP(BSON("" << BSONCode("abc_code"))); @@ -420,7 +420,7 @@ const std::vector& getInterestingElements() { elements.push_back(BSON("" << BSONNULL)); elements.push_back(BSON("" << BSONUndefined)); elements.push_back(BSON("" << OID("abcdefabcdefabcdefabcdef"))); - elements.push_back(BSON("" << Date_t(123))); + elements.push_back(BSON("" << Date_t::fromMillisSinceEpoch(123))); elements.push_back(BSON("" << BSONCode("abc_code"))); elements.push_back(BSON("" << BSONCode(ball))); elements.push_back(BSON("" << BSONCode(ball00n))); diff --git a/src/mongo/db/storage/mmap_v1/btree/key.cpp b/src/mongo/db/storage/mmap_v1/btree/key.cpp index c49e944ceb3..5cc1afbdc69 100644 --- a/src/mongo/db/storage/mmap_v1/btree/key.cpp +++ b/src/mongo/db/storage/mmap_v1/btree/key.cpp @@ -66,11 +66,14 @@ namespace mongo { case Bool: return *l.value() - *r.value(); case bsonTimestamp: - case Date: + case Date: { + const unsigned long long lULL = l.date().toULL(); + const unsigned long long rULL = r.date().toULL(); // unsigned dates for old version - if ( l.date() < r.date() ) + if (lULL < rULL) return -1; - return l.date() == r.date() ? 0 : 1; + return lULL == rULL ? 0 : 1; + } case NumberLong: if( r.type() == NumberLong ) { long long L = l._numberLong(); diff --git a/src/mongo/db/storage/mmap_v1/data_file_sync.cpp b/src/mongo/db/storage/mmap_v1/data_file_sync.cpp index b65124052d7..d4d2cb43fe3 100644 --- a/src/mongo/db/storage/mmap_v1/data_file_sync.cpp +++ b/src/mongo/db/storage/mmap_v1/data_file_sync.cpp @@ -86,7 +86,7 @@ namespace mongo { Date_t start = jsTime(); StorageEngine* storageEngine = getGlobalServiceContext()->getGlobalStorageEngine(); int numFiles = storageEngine->flushAllFiles( true ); - time_flushing = (int) (jsTime() - start); + time_flushing = (jsTime() - start).count(); _flushed(time_flushing); diff --git a/src/mongo/db/storage/mmap_v1/dur.cpp b/src/mongo/db/storage/mmap_v1/dur.cpp index 3a1498093bc..b12098199f1 100644 --- a/src/mongo/db/storage/mmap_v1/dur.cpp +++ b/src/mongo/db/storage/mmap_v1/dur.cpp @@ -701,7 +701,8 @@ namespace { boost::unique_lock lock(flushMutex); for (unsigned i = 0; i <= 2; i++) { - if (flushRequested.timed_wait(lock, Milliseconds(oneThird))) { + if (boost::cv_status::no_timeout == flushRequested.wait_for( + lock, Milliseconds(oneThird))) { // Someone forced a flush break; } diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp index 43845ffaa34..facbb58082c 100644 --- a/src/mongo/db/ttl.cpp +++ b/src/mongo/db/ttl.cpp @@ -231,7 +231,7 @@ namespace mongo { // Read the current time outside of the while loop, so that we don't expand our index // bounds after every WriteConflictException. - unsigned long long now = curTimeMillis64(); + const Date_t now = Date_t::now(); long long numDeleted = 0; int attempt = 1; @@ -284,10 +284,11 @@ namespace mongo { return true; } - const Date_t kDawnOfTime(std::numeric_limits::min()); + const Date_t kDawnOfTime = + Date_t::fromMillisSinceEpoch(std::numeric_limits::min()); const BSONObj startKey = BSON("" << kDawnOfTime); const BSONObj endKey = - BSON("" << Date_t(now - (1000 * secondsExpireElt.numberLong()))); + BSON("" << now - Seconds(secondsExpireElt.numberLong())); const bool endKeyInclusive = true; // The canonical check as to whether a key pattern element is "ascending" or // "descending" is (elt.number() >= 0). This is defined by the Ordering class. diff --git a/src/mongo/db/write_concern.cpp b/src/mongo/db/write_concern.cpp index dfe7ba02d3a..24f69f78156 100644 --- a/src/mongo/db/write_concern.cpp +++ b/src/mongo/db/write_concern.cpp @@ -271,8 +271,8 @@ namespace mongo { } // Add stats result->writtenTo = repl::getGlobalReplicationCoordinator()->getHostsWrittenTo(replOpTime); - gleWtimeStats.recordMillis(replStatus.duration.total_milliseconds()); - result->wTime = replStatus.duration.total_milliseconds(); + gleWtimeStats.recordMillis(replStatus.duration.count()); + result->wTime = replStatus.duration.count(); return replStatus.status; } diff --git a/src/mongo/dbtests/config_upgrade_tests.cpp b/src/mongo/dbtests/config_upgrade_tests.cpp index e76760d283f..41ae04a0f80 100644 --- a/src/mongo/dbtests/config_upgrade_tests.cpp +++ b/src/mongo/dbtests/config_upgrade_tests.cpp @@ -138,7 +138,7 @@ namespace mongo { ping.setConfigVersion(CURRENT_CONFIG_VERSION); if (i % 2 == 0) { - ping.setPing(ping.getPing() - 10 * 60 * 1000); + ping.setPing(ping.getPing() - Minutes(10)); } client.insert(MongosType::ConfigNS, ping.toBSON()); diff --git a/src/mongo/dbtests/expressiontests.cpp b/src/mongo/dbtests/expressiontests.cpp index a1c9fd3a7e1..8a4592bc89a 100644 --- a/src/mongo/dbtests/expressiontests.cpp +++ b/src/mongo/dbtests/expressiontests.cpp @@ -177,7 +177,7 @@ namespace ExpressionTests { /** Single Date argument. */ class Date : public SingleOperandBase { - BSONObj operand() { return BSON( "" << Date_t(12345) ); } + BSONObj operand() { return BSON( "" << Date_t::fromMillisSinceEpoch(12345) ); } }; /** Single null argument. */ @@ -258,8 +258,8 @@ namespace ExpressionTests { /** Adding an int and a Date produces a Date. */ class IntDate : public TwoOperandBase { BSONObj operand1() { return BSON( "" << 6 ); } - BSONObj operand2() { return BSON( "" << Date_t(123450) ); } - BSONObj expectedResult() { return BSON( "" << Date_t(123456) ); } + BSONObj operand2() { return BSON( "" << Date_t::fromMillisSinceEpoch(123450) ); } + BSONObj expectedResult() { return BSON( "" << Date_t::fromMillisSinceEpoch(123456) ); } }; /** Adding a long and a double produces a double. */ diff --git a/src/mongo/dbtests/jsobjtests.cpp b/src/mongo/dbtests/jsobjtests.cpp index 62a69fc6ded..674c65c8591 100644 --- a/src/mongo/dbtests/jsobjtests.cpp +++ b/src/mongo/dbtests/jsobjtests.cpp @@ -679,20 +679,26 @@ namespace JsobjTests { { { // check signed dates with new key format - KeyV1Owned a( BSONObjBuilder().appendDate("", -50).obj() ); - KeyV1Owned b( BSONObjBuilder().appendDate("", 50).obj() ); + KeyV1Owned a( BSONObjBuilder().appendDate( + "", Date_t::fromMillisSinceEpoch(-50)).obj() ); + KeyV1Owned b( BSONObjBuilder().appendDate( + "", Date_t::fromMillisSinceEpoch(50)).obj() ); ASSERT( a.woCompare(b, Ordering::make(BSONObj())) < 0 ); } { // backward compatibility - KeyBson a( BSONObjBuilder().appendDate("", -50).obj() ); - KeyBson b( BSONObjBuilder().appendDate("", 50).obj() ); + KeyBson a( BSONObjBuilder().appendDate( + "", Date_t::fromMillisSinceEpoch(-50)).obj() ); + KeyBson b( BSONObjBuilder().appendDate( + "", Date_t::fromMillisSinceEpoch(50)).obj() ); ASSERT( a.woCompare(b, Ordering::make(BSONObj())) > 0 ); } { // this is an uncompactable key: - BSONObj uc1 = BSONObjBuilder().appendDate("", -50).appendCode("", "abc").obj(); - BSONObj uc2 = BSONObjBuilder().appendDate("", 55).appendCode("", "abc").obj(); + BSONObj uc1 = BSONObjBuilder().appendDate( + "", Date_t::fromMillisSinceEpoch(-50)).appendCode("", "abc").obj(); + BSONObj uc2 = BSONObjBuilder().appendDate( + "", Date_t::fromMillisSinceEpoch(55)).appendCode("", "abc").obj(); ASSERT( uc1.woCompare(uc2, Ordering::make(BSONObj())) < 0 ); { KeyV1Owned a(uc1); @@ -1308,10 +1314,11 @@ namespace JsobjTests { public: void run() { OID oid; - const Date_t base( ::time( 0 ) ); + const Date_t base(Date_t::now()); oid.init( base ); - ASSERT_EQUALS( base.millis / 1000, oid.asDateT().millis / 1000 ); + ASSERT_EQUALS(base.toMillisSinceEpoch() / 1000, + oid.asDateT().toMillisSinceEpoch() / 1000); ASSERT_EQUALS( base.toTimeT(), oid.asTimeT() ); } }; @@ -1320,14 +1327,14 @@ namespace JsobjTests { public: void run() { OID min, oid, max; - Date_t now = jsTime(); + Date_t now = Date_t::now(); oid.init(); // slight chance this has different time. If its a problem, can change. min.init(now); max.init(now, true); - ASSERT_EQUALS( (unsigned)oid.asTimeT() , now/1000 ); - ASSERT_EQUALS( (unsigned)min.asTimeT() , now/1000 ); - ASSERT_EQUALS( (unsigned)max.asTimeT() , now/1000 ); + ASSERT_EQUALS( oid.asTimeT() , now.toTimeT() ); + ASSERT_EQUALS( min.asTimeT() , now.toTimeT() ); + ASSERT_EQUALS( max.asTimeT() , now.toTimeT() ); ASSERT( BSON("" << min).woCompare( BSON("" << oid) ) < 0 ); ASSERT( BSON("" << max).woCompare( BSON("" << oid) )> 0 ); } @@ -1543,9 +1550,9 @@ namespace JsobjTests { class DateBuilder { public: void run() { - BSONObj o = BSON("" << Date_t(1234567890)); + BSONObj o = BSON("" << Date_t::fromMillisSinceEpoch(1234567890)); ASSERT( o.firstElement().type() == Date ); - ASSERT( o.firstElement().date() == Date_t(1234567890) ); + ASSERT( o.firstElement().date() == Date_t::fromMillisSinceEpoch(1234567890) ); } }; @@ -1568,22 +1575,17 @@ namespace JsobjTests { class TimeTBuilder { public: void run() { - Date_t before = jsTime(); - sleepmillis(2); - time_t now = jsTime().toTimeT(); - sleepmillis(2); - Date_t after = jsTime(); - + Date_t aDate = Date_t::now(); + time_t aTime = aDate.toTimeT(); BSONObjBuilder b; - b.appendTimeT("now", now); + b.appendTimeT("now", aTime); BSONObj o = b.obj(); ASSERT( o.valid() ); BSONElement e = o["now"]; - ASSERT( e.type() == Date ); - ASSERT( e.date()/1000 >= before/1000 ); - ASSERT( e.date()/1000 <= after/1000 ); + ASSERT_EQUALS(Date, e.type()); + ASSERT_EQUALS(aTime, e.date().toTimeT()); } }; @@ -1819,7 +1821,7 @@ namespace JsobjTests { objb.appendTimeT(objb.numStr(i++), dt); arrb.appendTimeT(dt); - Date_t date(0); + Date_t date{}; objb.appendDate(objb.numStr(i++), date); arrb.appendDate(date); diff --git a/src/mongo/dbtests/jsontests.cpp b/src/mongo/dbtests/jsontests.cpp index 828e35c20e3..e9cc4e39dd1 100644 --- a/src/mongo/dbtests/jsontests.cpp +++ b/src/mongo/dbtests/jsontests.cpp @@ -426,7 +426,7 @@ namespace JsonTests { void run() { BSONObjBuilder b; - b.appendDate( "a", 0 ); + b.appendDate( "a", Date_t() ); BSONObj built = b.done(); ASSERT_EQUALS( "{ \"a\" : { \"$date\" : \"1969-12-31T19:00:00.000-0500\" } }", built.jsonString( Strict ) ); @@ -435,7 +435,7 @@ namespace JsonTests { // Test dates above our maximum formattable date. See SERVER-13760. BSONObjBuilder b2; - b2.appendDate("a", 32535262800000ULL); + b2.appendDate("a", Date_t::fromMillisSinceEpoch(32535262800000LL)); BSONObj built2 = b2.done(); ASSERT_EQUALS( "{ \"a\" : { \"$date\" : { \"$numberLong\" : \"32535262800000\" } } }", @@ -451,7 +451,7 @@ namespace JsonTests { public: void run() { BSONObjBuilder b; - b.appendDate( "a", -1 ); + b.appendDate( "a", Date_t::fromMillisSinceEpoch(-1) ); BSONObj built = b.done(); ASSERT_EQUALS( "{ \"a\" : { \"$date\" : { \"$numberLong\" : \"-1\" } } }", built.jsonString( Strict ) ); @@ -565,7 +565,7 @@ namespace JsonTests { b.appendUndefined( "h" ); b.append( "i" , oid ); b.appendBool( "j" , 1 ); - b.appendDate( "k" , 123 ); + b.appendDate( "k" , Date_t::fromMillisSinceEpoch(123) ); b.appendNull( "l" ); b.appendRegex( "m" , "a" ); b.appendDBRef( "n" , "foo" , oid ); @@ -592,6 +592,7 @@ namespace JsonTests { virtual ~Base() {} void run() { ASSERT( fromjson( json() ).valid() ); + assertEquals( bson(), fromjson( json() ), "mode: json-to-bson" ); assertEquals( bson(), fromjson( tojson( bson() ) ), "mode: " ); assertEquals( bson(), fromjson( tojson( bson(), Strict ) ), "mode: strict" ); assertEquals( bson(), fromjson( tojson( bson(), TenGen ) ), "mode: tengen" ); @@ -1532,7 +1533,7 @@ namespace JsonTests { class Date : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", 0 ); + b.appendDate( "a", Date_t() ); return b.obj(); } virtual string json() const { @@ -1540,21 +1541,10 @@ namespace JsonTests { } }; - class DateNegZero : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendDate( "a", -0 ); - return b.obj(); - } - virtual string json() const { - return "{ \"a\" : { \"$date\" : -0 } }"; - } - }; - class DateNonzero : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", 1000000000 ); + b.appendDate( "a", Date_t::fromMillisSinceEpoch(1000000000) ); return b.obj(); } virtual string json() const { @@ -1654,7 +1644,7 @@ namespace JsonTests { class DateStrictMaxUnsigned : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", -1 ); + b.appendDate( "a", Date_t::fromMillisSinceEpoch(-1) ); return b.obj(); } virtual string json() const { @@ -1668,7 +1658,7 @@ namespace JsonTests { class DateMaxUnsigned : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", -1 ); + b.appendDate( "a", Date_t::fromMillisSinceEpoch(-1) ); return b.obj(); } virtual string json() const { @@ -1682,7 +1672,7 @@ namespace JsonTests { class DateStrictNegative : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", -1 ); + b.appendDate( "a", Date_t::fromMillisSinceEpoch(-1) ); return b.obj(); } virtual string json() const { @@ -1693,7 +1683,7 @@ namespace JsonTests { class DateNegative : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", -1 ); + b.appendDate( "a", Date_t::fromMillisSinceEpoch(-1) ); return b.obj(); } virtual string json() const { @@ -2598,8 +2588,8 @@ namespace JsonTests { BSONObj bson() const { BSONObjBuilder e; - e.appendDate( "$gt" , 1257829200000LL ); - e.appendDate( "$lt" , 1257829200100LL ); + e.appendDate( "$gt" , Date_t::fromMillisSinceEpoch(1257829200000LL) ); + e.appendDate( "$lt" , Date_t::fromMillisSinceEpoch(1257829200100LL) ); BSONObjBuilder b; b.append( "time.valid" , e.obj() ); @@ -2812,7 +2802,6 @@ namespace JsonTests { // "1969-12-31T19:00:00-05:00" actually represents the Unix timestamp of zero, but we // cannot parse it because the body of the date is before 1970. //add< FromJsonTests::Date >(); - //add< FromJsonTests::DateNegZero >(); add< FromJsonTests::DateNonzero >(); add< FromJsonTests::DateStrictTooLong >(); add< FromJsonTests::DateTooLong >(); diff --git a/src/mongo/dbtests/jstests.cpp b/src/mongo/dbtests/jstests.cpp index a83e153185d..07098656497 100644 --- a/src/mongo/dbtests/jstests.cpp +++ b/src/mongo/dbtests/jstests.cpp @@ -428,7 +428,7 @@ namespace JSTests { BSONObj o; { BSONObjBuilder b; - b.appendDate( "d" , 123456789 ); + b.appendDate( "d" , Date_t::fromMillisSinceEpoch(123456789) ); o = b.obj(); } s->setObject( "x" , o ); @@ -530,7 +530,7 @@ namespace JSTests { { BSONObj t = b.done(); - ASSERT_EQUALS( 1234000U , t["d"].timestampTime() ); + ASSERT_EQUALS( Date_t::fromMillisSinceEpoch(1234000) , t["d"].timestampTime() ); ASSERT_EQUALS( 9876U , t["d"].timestampInc() ); } @@ -545,8 +545,8 @@ namespace JSTests { ASSERT_EQUALS( bsonTimestamp , out["d"].type() ); ASSERT_EQUALS( 9876U , out["d"].timestampInc() ); - ASSERT_EQUALS( 1234000U , out["d"].timestampTime() ); - ASSERT_EQUALS( 123456789U , out["a"].date() ); + ASSERT_EQUALS( Date_t::fromMillisSinceEpoch(1234000) , out["d"].timestampTime() ); + ASSERT_EQUALS( Date_t::fromMillisSinceEpoch(123456789) , out["a"].date() ); delete s; } @@ -1617,7 +1617,7 @@ namespace JSTests { class Date : public TestRoundTrip { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", 0 ); + b.appendDate( "a", Date_t() ); return b.obj(); } virtual string json() const { @@ -1628,7 +1628,7 @@ namespace JSTests { class DateNonzero : public TestRoundTrip { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", 100 ); + b.appendDate( "a", Date_t::fromMillisSinceEpoch(100) ); return b.obj(); } virtual string json() const { @@ -1639,7 +1639,7 @@ namespace JSTests { class DateNegative : public TestRoundTrip { virtual BSONObj bson() const { BSONObjBuilder b; - b.appendDate( "a", -1 ); + b.appendDate( "a", Date_t::fromMillisSinceEpoch(-1) ); return b.obj(); } virtual string json() const { diff --git a/src/mongo/dbtests/merge_chunk_tests.cpp b/src/mongo/dbtests/merge_chunk_tests.cpp index 1b263b35af4..1766f3c252a 100644 --- a/src/mongo/dbtests/merge_chunk_tests.cpp +++ b/src/mongo/dbtests/merge_chunk_tests.cpp @@ -67,7 +67,7 @@ namespace mongo { coll.setNs(nss); coll.setKeyPattern( ranges.begin()->keyPattern ); coll.setEpoch( startVersion.epoch() ); - coll.setUpdatedAt( 1ULL ); + coll.setUpdatedAt( Date_t::fromMillisSinceEpoch(1) ); ASSERT_OK(coll.validate()); DBDirectClient client(&_txn); diff --git a/src/mongo/dbtests/mock/mock_replica_set.cpp b/src/mongo/dbtests/mock/mock_replica_set.cpp index ea1ebde067a..16d6adbf2d1 100644 --- a/src/mongo/dbtests/mock/mock_replica_set.cpp +++ b/src/mongo/dbtests/mock/mock_replica_set.cpp @@ -219,8 +219,8 @@ namespace mongo { builder.append("passive", true); } - if (member->getSlaveDelay().total_seconds()) { - builder.append("slaveDelay", member->getSlaveDelay().total_seconds()); + if (member->getSlaveDelay().count()) { + builder.appendIntOrLL("slaveDelay", member->getSlaveDelay().count()); } if (member->isHidden()) { diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp index 5aac0a989e5..e804fc12e50 100644 --- a/src/mongo/dbtests/querytests.cpp +++ b/src/mongo/dbtests/querytests.cpp @@ -660,9 +660,9 @@ namespace QueryTests { "capped" << true << "size" << 8192 ), info ); - Date_t one = getNextGlobalTimestamp().asULL(); - Date_t two = getNextGlobalTimestamp().asULL(); - Date_t three = getNextGlobalTimestamp().asULL(); + Date_t one = Date_t::fromMillisSinceEpoch(getNextGlobalTimestamp().asLL()); + Date_t two = Date_t::fromMillisSinceEpoch(getNextGlobalTimestamp().asLL()); + Date_t three = Date_t::fromMillisSinceEpoch(getNextGlobalTimestamp().asLL()); insert( ns, BSON( "ts" << one ) ); insert( ns, BSON( "ts" << two ) ); insert( ns, BSON( "ts" << three ) ); @@ -675,7 +675,7 @@ namespace QueryTests { ClientCursorPin clientCursor( ctx.db()->getCollection( ns )->getCursorManager(), cursorId ); - ASSERT_EQUALS( three.millis, clientCursor.c()->getSlaveReadTill().asULL() ); + ASSERT_EQUALS( three.toULL(), clientCursor.c()->getSlaveReadTill().asULL() ); } }; diff --git a/src/mongo/dbtests/repltests.cpp b/src/mongo/dbtests/repltests.cpp index cf6d2576323..e803447e623 100644 --- a/src/mongo/dbtests/repltests.cpp +++ b/src/mongo/dbtests/repltests.cpp @@ -343,7 +343,7 @@ namespace ReplTests { } void check() const { BSONObj o = _client.findOne( ns(), QUERY( "a" << 1 ) ); - ASSERT( 0 != o.getField( "t" ).date() ); + ASSERT( Date_t{} != o.getField( "t" ).date() ); ASSERT_EQUALS( date_, o.getField( "t" ).date() ); } void reset() const { @@ -432,7 +432,7 @@ namespace ReplTests { } void check() const { BSONObj o = _client.findOne( ns(), QUERY( "_id" << 1 ) ); - ASSERT( 0 != o.getField( "t" ).date() ); + ASSERT( Date_t{} != o.getField( "t" ).date() ); ASSERT_EQUALS( date_, o.getField( "t" ).date() ); } void reset() const { diff --git a/src/mongo/logger/log_test.cpp b/src/mongo/logger/log_test.cpp index 4d616a1a42b..ca60eb28040 100644 --- a/src/mongo/logger/log_test.cpp +++ b/src/mongo/logger/log_test.cpp @@ -89,17 +89,17 @@ namespace { MessageLogDomain domain; // Appending to the domain before attaching the appender does not affect the appender. - domain.append(MessageEventEphemeral(0ULL, LogSeverity::Log(), "", "1")); + domain.append(MessageEventEphemeral(Date_t(), LogSeverity::Log(), "", "1")); ASSERT_EQUALS(0, dynamic_cast(countAppender.get())->getCount()); // Appending to the domain after attaching the appender does affect the appender. MessageLogDomain::AppenderHandle handle = domain.attachAppender(countAppender); - domain.append(MessageEventEphemeral(0ULL, LogSeverity::Log(), "", "2")); + domain.append(MessageEventEphemeral(Date_t(), LogSeverity::Log(), "", "2")); countAppender = domain.detachAppender(handle); ASSERT_EQUALS(1, dynamic_cast(countAppender.get())->getCount()); // Appending to the domain after detaching the appender does not affect the appender. - domain.append(MessageEventEphemeral(0ULL, LogSeverity::Log(), "", "3")); + domain.append(MessageEventEphemeral(Date_t(), LogSeverity::Log(), "", "3")); ASSERT_EQUALS(1, dynamic_cast(countAppender.get())->getCount()); } @@ -383,7 +383,7 @@ namespace { // Log severity should always be logged as a single capital letter. TEST_F(LogTestUnadornedEncoder, MessageEventDetailsEncoderLogSeverity) { - Date_t d(curTimeMillis64()); + Date_t d = Date_t::now(); StringData ctx("WHAT", StringData::LiteralTag()); StringData msg("HUH", StringData::LiteralTag()); // Severe is indicated by (F)atal. @@ -406,7 +406,7 @@ namespace { // Non-default log component short name should always be logged. TEST_F(LogTestUnadornedEncoder, MessageEventDetailsEncoderLogComponent) { - Date_t d(curTimeMillis64()); + Date_t d = Date_t::now(); StringData ctx("WHAT", StringData::LiteralTag()); StringData msg("HUH", StringData::LiteralTag()); for (int i = 0; i < int(LogComponent::kNumLogComponents); ++i) { diff --git a/src/mongo/logger/logstream_builder.cpp b/src/mongo/logger/logstream_builder.cpp index 1ed0e701c45..1adef55dd6d 100644 --- a/src/mongo/logger/logstream_builder.cpp +++ b/src/mongo/logger/logstream_builder.cpp @@ -127,7 +127,7 @@ namespace logger { if (_os) { if ( !_baseMessage.empty() ) _baseMessage.push_back(' '); _baseMessage += _os->str(); - MessageEventEphemeral message(curTimeMillis64(), _severity, _component, _contextName, + MessageEventEphemeral message(Date_t::now(), _severity, _component, _contextName, _baseMessage); _domain->append(message); if (_tee) { diff --git a/src/mongo/logger/logstream_builder.h b/src/mongo/logger/logstream_builder.h index 7c923d6ece3..638534484ee 100644 --- a/src/mongo/logger/logstream_builder.h +++ b/src/mongo/logger/logstream_builder.h @@ -35,6 +35,7 @@ #include "mongo/logger/log_component.h" #include "mongo/logger/log_severity.h" #include "mongo/logger/message_log_domain.h" +#include "mongo/stdx/chrono.h" #include "mongo/util/exit_code.h" namespace mongo { @@ -130,6 +131,12 @@ namespace logger { LogstreamBuilder& operator<<(unsigned long long x) { stream() << x; return *this; } LogstreamBuilder& operator<<(bool x) { stream() << x; return *this; } + template + LogstreamBuilder& operator<<(stdx::chrono::duration d) { + stream() << d; + return *this; + } + template LogstreamBuilder& operator<<(const T& x) { stream() << x.toString(); diff --git a/src/mongo/logger/message_event.h b/src/mongo/logger/message_event.h index b38e792dcd1..516af0f3f84 100644 --- a/src/mongo/logger/message_event.h +++ b/src/mongo/logger/message_event.h @@ -67,7 +67,7 @@ namespace logger { _contextName(contextName), _message(message) {} - uint64_t getDate() const { return _date; } + Date_t getDate() const { return _date; } LogSeverity getSeverity() const { return _severity; } LogComponent getComponent() const { return _component; } StringData getContextName() const { return _contextName; } diff --git a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp index 88c1c57c21f..4037f70d43b 100644 --- a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp +++ b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp @@ -1582,7 +1582,7 @@ namespace { lk.lock(); _consistentFromLastCheck = isConsistent; if (_inShutdown) break; - _consistencyCheckerCV.timed_wait(lk, Seconds(60)); + _consistencyCheckerCV.wait_for(lk, Seconds(60)); } LOG(1) << "Consistency checker thread shutting down"; } diff --git a/src/mongo/s/catalog/legacy/cluster_client_internal.cpp b/src/mongo/s/catalog/legacy/cluster_client_internal.cpp index 020ab7ec5a2..96c1e4ab998 100644 --- a/src/mongo/s/catalog/legacy/cluster_client_internal.cpp +++ b/src/mongo/s/catalog/legacy/cluster_client_internal.cpp @@ -91,19 +91,18 @@ namespace mongo { Date_t lastPing = ping.getPing(); - long long quietIntervalMillis = 0; + Minutes quietIntervalMins{0}; Date_t currentJsTime = jsTime(); if (currentJsTime >= lastPing) { - quietIntervalMillis = static_cast(currentJsTime - lastPing); + quietIntervalMins = duration_cast(currentJsTime - lastPing); } - long long quietIntervalMins = quietIntervalMillis / (60 * 1000); // We assume that anything that hasn't pinged in 5 minutes is probably down - if (quietIntervalMins >= 5) { - log() << "stale mongos detected " << quietIntervalMins << " minutes ago," - << " network location is " << pingDoc["_id"].String() - << ", not checking version" << endl; - } + if (quietIntervalMins >= Minutes{5}) { + log() << "stale mongos detected " << quietIntervalMins.count() + << " minutes ago, network location is " << pingDoc["_id"].String() + << ", not checking version"; + } else { if (versionCmp(mongoVersion, minMongoVersion) < 0) { return Status(ErrorCodes::RemoteValidationError, diff --git a/src/mongo/s/catalog/legacy/distlock.cpp b/src/mongo/s/catalog/legacy/distlock.cpp index 01d3b9b005a..d55e7cb87b7 100644 --- a/src/mongo/s/catalog/legacy/distlock.cpp +++ b/src/mongo/s/catalog/legacy/distlock.cpp @@ -169,7 +169,7 @@ namespace mongo { bool success = false; BSONObj result; string errMsg; - long long delay = 0; + Milliseconds delay{0}; scoped_ptr connPtr; try { @@ -204,7 +204,7 @@ namespace mongo { // Make sure that our delay is not more than 2x our maximum network skew, since this is the max our remote // time value can be off by if we assume a response in the middle of the delay. - if ( delay > (long long) ( maxNetSkew * 2 ) ) { + if (delay > Milliseconds(maxNetSkew * 2)) { throw TimeNotFoundException( str::stream() << "server " << server.toString() << " in cluster " << cluster.toString() @@ -245,9 +245,10 @@ namespace mongo { // Remote time can be delayed by at most MAX_NET_SKEW // Skew is how much time we'd have to add to local to get to remote - avgSkews[s] += (long long) (remote - local); + avgSkews[s] += (remote - local).count(); - LOG( logLvl + 1 ) << "skew from remote server " << server << " found: " << (long long) (remote - local) << endl; + LOG( logLvl + 1 ) << "skew from remote server " << server << " found: " + << (remote - local).count(); } } @@ -387,7 +388,7 @@ namespace mongo { LOG( logLvl ) << "empty ping found for process in lock '" << lockName << "'" << endl; // TODO: Using 0 as a "no time found" value Will fail if dates roll over, but then, so will a lot. lastPing = BSON( LockpingsType::process(o[LocksType::process()].String()) << - LockpingsType::ping((Date_t) 0) ); + LockpingsType::ping(Date_t()) ); } unsigned long long elapsed = 0; @@ -422,7 +423,7 @@ namespace mongo { if(_lastPingCheck.remote >= remote) elapsed = 0; else - elapsed = remote - _lastPingCheck.remote; + elapsed = (remote - _lastPingCheck.remote).count(); } } catch( LockException& e ) { diff --git a/src/mongo/s/catalog/legacy/distlock.h b/src/mongo/s/catalog/legacy/distlock.h index 98602448642..a9667307414 100644 --- a/src/mongo/s/catalog/legacy/distlock.h +++ b/src/mongo/s/catalog/legacy/distlock.h @@ -129,9 +129,7 @@ namespace mongo { : id(_id), lastPing(_lastPing), remote(_remote), ts(_ts){ } - PingData() - : id(""), lastPing(0), remote(0), ts(){ - } + PingData() : id(""), ts() {} std::string id; Date_t lastPing; diff --git a/src/mongo/s/catalog/legacy/legacy_dist_lock_pinger.cpp b/src/mongo/s/catalog/legacy/legacy_dist_lock_pinger.cpp index d8c5f3c1fe6..a6ac69f3162 100644 --- a/src/mongo/s/catalog/legacy/legacy_dist_lock_pinger.cpp +++ b/src/mongo/s/catalog/legacy/legacy_dist_lock_pinger.cpp @@ -53,7 +53,7 @@ namespace { void LegacyDistLockPinger::_distLockPingThread(ConnectionString addr, const string& process, - stdx::chrono::milliseconds sleepTime) { + Milliseconds sleepTime) { setThreadName("LockPinger"); string pingId = pingThreadId(addr, process); @@ -73,11 +73,11 @@ namespace { ScopedDbConnection conn(addr.toString(), 30.0); pingTime = jsTime(); - Date_t elapsed(pingTime.millis - lastPingTime.millis); - if (elapsed.millis > static_cast(10 * sleepTime.count())) { + const auto elapsed = pingTime - lastPingTime; + if (elapsed > 10 * sleepTime) { warning() << "Lock pinger for addr: " << addr << ", proc: " << process - << " was inactive for " << elapsed.millis << " ms"; + << " was inactive for " << elapsed; } lastPingTime = pingTime; @@ -133,7 +133,7 @@ namespace { // of another pinger is too skewed). This is still fine as the lock logic only // checks if there is a change in the ping document and the document going away // is a valid change. - Date_t fourDays = pingTime - (4 * 86400 * 1000); // 4 days + Date_t fourDays = pingTime - stdx::chrono::hours{4 * 24}; conn->remove(LockpingsType::ConfigNS, BSON(LockpingsType::process() << NIN << pids << LockpingsType::ping() << LT << fourDays)); diff --git a/src/mongo/s/catalog/legacy/legacy_dist_lock_pinger.h b/src/mongo/s/catalog/legacy/legacy_dist_lock_pinger.h index 6d0ac4ebf6f..e7dec414bb9 100644 --- a/src/mongo/s/catalog/legacy/legacy_dist_lock_pinger.h +++ b/src/mongo/s/catalog/legacy/legacy_dist_lock_pinger.h @@ -36,9 +36,9 @@ #include "mongo/base/status.h" #include "mongo/client/dbclientinterface.h" #include "mongo/s/catalog/dist_lock_manager.h" -#include "mongo/stdx/chrono.h" #include "mongo/stdx/memory.h" #include "mongo/util/concurrency/mutex.h" +#include "mongo/util/time_support.h" namespace mongo { @@ -51,7 +51,7 @@ namespace mongo { /** * Starts pinging the process id for the given lock. */ - Status startPing(const DistributedLock& lock, stdx::chrono::milliseconds sleepTime); + Status startPing(const DistributedLock& lock, Milliseconds sleepTime); /** * Adds a distributed lock that has the given id to the unlock list. The unlock list @@ -82,7 +82,7 @@ namespace mongo { void distLockPingThread(ConnectionString addr, long long clockSkew, const std::string& processId, - stdx::chrono::milliseconds sleepTime); + Milliseconds sleepTime); /** * Function for repeatedly pinging the process id. Also attempts to unlock all the @@ -90,7 +90,7 @@ namespace mongo { */ void _distLockPingThread(ConnectionString addr, const std::string& process, - stdx::chrono::milliseconds sleepTime); + Milliseconds sleepTime); /** * Returns true if a request has been made to stop pinging the give process id. @@ -105,7 +105,7 @@ namespace mongo { /** * Blocks until duration has elapsed or if the ping thread is interrupted. */ - void waitTillNextPingTime(stdx::chrono::milliseconds duration); + void waitTillNextPingTime(Milliseconds duration); // // All member variables are labeled with one of the following codes indicating the diff --git a/src/mongo/s/catalog/type_actionlog.cpp b/src/mongo/s/catalog/type_actionlog.cpp index 8d208778e0f..49dd09b6958 100644 --- a/src/mongo/s/catalog/type_actionlog.cpp +++ b/src/mongo/s/catalog/type_actionlog.cpp @@ -123,7 +123,7 @@ namespace mongo { _what.clear(); _isWhatSet = false; - _time = 0ULL; + _time = Date_t(); _isTimeSet = false; _details = BSONObj(); diff --git a/src/mongo/s/catalog/type_changelog.cpp b/src/mongo/s/catalog/type_changelog.cpp index f73b90f72c0..40db60dbf94 100644 --- a/src/mongo/s/catalog/type_changelog.cpp +++ b/src/mongo/s/catalog/type_changelog.cpp @@ -158,7 +158,7 @@ namespace mongo { _clientAddr.clear(); _isClientAddrSet = false; - _time = 0ULL; + _time = Date_t(); _isTimeSet = false; _what.clear(); diff --git a/src/mongo/s/catalog/type_changelog_test.cpp b/src/mongo/s/catalog/type_changelog_test.cpp index 5777a3b7e37..0844b231497 100644 --- a/src/mongo/s/catalog/type_changelog_test.cpp +++ b/src/mongo/s/catalog/type_changelog_test.cpp @@ -53,7 +53,7 @@ namespace { BSONObj obj = BSON(ChangelogType::changeID("host.local-2012-11-21T19:14:10-8") << ChangelogType::server("host.local") << ChangelogType::clientAddr("192.168.0.189:51128") << - ChangelogType::time(1ULL) << + ChangelogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangelogType::what("split") << ChangelogType::ns("test.test") << ChangelogType::details(BSON("dummy" << "info"))); @@ -64,7 +64,7 @@ namespace { ASSERT_EQUALS(logEntry.getChangeID(), "host.local-2012-11-21T19:14:10-8"); ASSERT_EQUALS(logEntry.getServer(), "host.local"); ASSERT_EQUALS(logEntry.getClientAddr(), "192.168.0.189:51128"); - ASSERT_EQUALS(logEntry.getTime(), 1ULL); + ASSERT_EQUALS(logEntry.getTime(), Date_t::fromMillisSinceEpoch(1)); ASSERT_EQUALS(logEntry.getWhat(), "split"); ASSERT_EQUALS(logEntry.getNS(), "test.test"); ASSERT_EQUALS(logEntry.getDetails(), BSON("dummy" << "info")); @@ -74,7 +74,7 @@ namespace { ChangelogType logEntry; BSONObj obj = BSON(ChangelogType::server("host.local") << ChangelogType::clientAddr("192.168.0.189:51128") << - ChangelogType::time(1ULL) << + ChangelogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangelogType::what("split") << ChangelogType::ns("test.test") << ChangelogType::details(BSON("dummy" << "info"))); @@ -88,7 +88,7 @@ namespace { ChangelogType logEntry; BSONObj obj = BSON(ChangelogType::changeID("host.local-2012-11-21T19:14:10-8") << ChangelogType::clientAddr("192.168.0.189:51128") << - ChangelogType::time(1ULL) << + ChangelogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangelogType::what("split") << ChangelogType::ns("test.test") << ChangelogType::details(BSON("dummy" << "info"))); @@ -102,7 +102,7 @@ namespace { ChangelogType logEntry; BSONObj obj = BSON(ChangelogType::changeID("host.local-2012-11-21T19:14:10-8") << ChangelogType::server("host.local") << - ChangelogType::time(1ULL) << + ChangelogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangelogType::what("split") << ChangelogType::ns("test.test") << ChangelogType::details(BSON("dummy" << "info"))); @@ -131,7 +131,7 @@ namespace { BSONObj obj = BSON(ChangelogType::changeID("host.local-2012-11-21T19:14:10-8") << ChangelogType::server("host.local") << ChangelogType::clientAddr("192.168.0.189:51128") << - ChangelogType::time(1ULL) << + ChangelogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangelogType::ns("test.test") << ChangelogType::details(BSON("dummy" << "info"))); string errMsg; @@ -145,7 +145,7 @@ namespace { BSONObj obj = BSON(ChangelogType::changeID("host.local-2012-11-21T19:14:10-8") << ChangelogType::server("host.local") << ChangelogType::clientAddr("192.168.0.189:51128") << - ChangelogType::time(1ULL) << + ChangelogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangelogType::what("split") << ChangelogType::details(BSON("dummy" << "info"))); string errMsg; @@ -159,7 +159,7 @@ namespace { BSONObj obj = BSON(ChangelogType::changeID("host.local-2012-11-21T19:14:10-8") << ChangelogType::server("host.local") << ChangelogType::clientAddr("192.168.0.189:51128") << - ChangelogType::time(1ULL) << + ChangelogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangelogType::what("split") << ChangelogType::ns("test.test")); string errMsg; diff --git a/src/mongo/s/catalog/type_chunk_test.cpp b/src/mongo/s/catalog/type_chunk_test.cpp index db86f9fe809..35d9f578d5f 100644 --- a/src/mongo/s/catalog/type_chunk_test.cpp +++ b/src/mongo/s/catalog/type_chunk_test.cpp @@ -43,7 +43,7 @@ namespace { TEST(ChunkType, MissingRequiredFields) { ChunkType chunk; - BSONArray version = BSON_ARRAY(Date_t(1) << OID::gen()); + BSONArray version = BSON_ARRAY(Date_t::fromMillisSinceEpoch(1) << OID::gen()); BSONObj objModNS = BSON(ChunkType::name("test.mycol-a_MinKey") << ChunkType::min(BSON("a" << 10 << "b" << 10)) << @@ -78,7 +78,7 @@ namespace { } TEST(ChunkType, DifferentNumberOfColumns) { - BSONArray version = BSON_ARRAY(Date_t(1) << OID::gen()); + BSONArray version = BSON_ARRAY(Date_t::fromMillisSinceEpoch(1) << OID::gen()); BSONObj obj = BSON(ChunkType::name("test.mycol-a_MinKey") << ChunkType::ns("test.mycol") << ChunkType::min(BSON("a" << 10 << "b" << 10)) << @@ -91,7 +91,7 @@ namespace { } TEST(ChunkType, DifferentColumns) { - BSONArray version = BSON_ARRAY(Date_t(1) << OID::gen()); + BSONArray version = BSON_ARRAY(Date_t::fromMillisSinceEpoch(1) << OID::gen()); BSONObj obj = BSON(ChunkType::name("test.mycol-a_MinKey") << ChunkType::ns("test.mycol") << ChunkType::min(BSON("a" << 10)) << @@ -104,7 +104,7 @@ namespace { } TEST(ChunkType, NotAscending) { - BSONArray version = BSON_ARRAY(Date_t(1) << OID::gen()); + BSONArray version = BSON_ARRAY(Date_t::fromMillisSinceEpoch(1) << OID::gen()); BSONObj obj = BSON(ChunkType::name("test.mycol-a_MinKey") << ChunkType::ns("test.mycol") << ChunkType::min(BSON("a" << 20)) << @@ -119,7 +119,7 @@ namespace { TEST(ChunkType, NewFormatVersion) { ChunkType chunk; OID epoch = OID::gen(); - BSONArray version = BSON_ARRAY(Date_t(1) << epoch); + BSONArray version = BSON_ARRAY(Date_t::fromMillisSinceEpoch(1) << epoch); BSONObj obj = BSON(ChunkType::name("test.mycol-a_MinKey") << ChunkType::ns("test.mycol") << ChunkType::min(BSON("a" << 10)) << @@ -148,7 +148,7 @@ namespace { ChunkType::ns("test.mycol") << ChunkType::min(BSON("a" << 10)) << ChunkType::max(BSON("a" << 20)) << - ChunkType::DEPRECATED_lastmod(Date_t(1)) << + ChunkType::DEPRECATED_lastmod(Date_t::fromMillisSinceEpoch(1)) << ChunkType::DEPRECATED_epoch(epoch) << ChunkType::shard("shard0001")); StatusWith chunkRes = ChunkType::fromBSON(obj); diff --git a/src/mongo/s/catalog/type_collection.cpp b/src/mongo/s/catalog/type_collection.cpp index 05f7aa1d808..fb121942615 100644 --- a/src/mongo/s/catalog/type_collection.cpp +++ b/src/mongo/s/catalog/type_collection.cpp @@ -161,7 +161,7 @@ namespace mongo { return Status(ErrorCodes::BadValue, "invalid epoch"); } - if (!_updatedAt.get()) { + if (Date_t() == _updatedAt.get()) { return Status(ErrorCodes::BadValue, "invalid updated at timestamp"); } @@ -183,7 +183,7 @@ namespace mongo { builder.append(fullNs.name(), _fullNs->toString()); } builder.append(epoch.name(), _epoch.get_value_or(OID())); - builder.append(updatedAt.name(), _updatedAt.get_value_or(0)); + builder.append(updatedAt.name(), _updatedAt.get_value_or(Date_t())); // These fields are optional, so do not include them in the metadata for the purposes of // consuming less space on the config servers. diff --git a/src/mongo/s/catalog/type_collection_test.cpp b/src/mongo/s/catalog/type_collection_test.cpp index 1b6f113570a..3d538b51a2f 100644 --- a/src/mongo/s/catalog/type_collection_test.cpp +++ b/src/mongo/s/catalog/type_collection_test.cpp @@ -47,18 +47,18 @@ namespace { TEST(CollectionType, Basic) { const OID oid = OID::gen(); StatusWith status = CollectionType::fromBSON( - BSON(CollectionType::fullNs("db.coll") << - CollectionType::epoch(oid) << - CollectionType::updatedAt(1ULL) << - CollectionType::keyPattern(BSON("a" << 1)) << - CollectionType::unique(true))); + BSON(CollectionType::fullNs("db.coll") << + CollectionType::epoch(oid) << + CollectionType::updatedAt(Date_t::fromMillisSinceEpoch(1)) << + CollectionType::keyPattern(BSON("a" << 1)) << + CollectionType::unique(true))); ASSERT_TRUE(status.isOK()); CollectionType coll = status.getValue(); ASSERT_TRUE(coll.validate().isOK()); ASSERT(coll.getNs() == NamespaceString{"db.coll"}); ASSERT_EQUALS(coll.getEpoch(), oid); - ASSERT_EQUALS(coll.getUpdatedAt(), 1ULL); + ASSERT_EQUALS(coll.getUpdatedAt(), Date_t::fromMillisSinceEpoch(1)); ASSERT_EQUALS(coll.getKeyPattern(), BSON("a" << 1)); ASSERT_EQUALS(coll.getUnique(), true); ASSERT_EQUALS(coll.getAllowBalance(), true); @@ -68,11 +68,11 @@ namespace { TEST(CollectionType, InvalidCollectionNamespace) { const OID oid = OID::gen(); StatusWith result = CollectionType::fromBSON( - BSON(CollectionType::fullNs("foo\\bar.coll") << - CollectionType::epoch(oid) << - CollectionType::updatedAt(1ULL) << - CollectionType::keyPattern(BSON("a" << 1)) << - CollectionType::unique(true))); + BSON(CollectionType::fullNs("foo\\bar.coll") << + CollectionType::epoch(oid) << + CollectionType::updatedAt(Date_t::fromMillisSinceEpoch(1)) << + CollectionType::keyPattern(BSON("a" << 1)) << + CollectionType::unique(true))); ASSERT_TRUE(result.isOK()); CollectionType collType = result.getValue(); ASSERT_FALSE(collType.validate().isOK()); @@ -81,11 +81,11 @@ namespace { TEST(CollectionType, BadType) { const OID oid = OID::gen(); StatusWith status = CollectionType::fromBSON( - BSON(CollectionType::fullNs() << 1 << - CollectionType::epoch(oid) << - CollectionType::updatedAt(1ULL) << - CollectionType::keyPattern(BSON("a" << 1)) << - CollectionType::unique(true))); + BSON(CollectionType::fullNs() << 1 << + CollectionType::epoch(oid) << + CollectionType::updatedAt(Date_t::fromMillisSinceEpoch(1)) << + CollectionType::keyPattern(BSON("a" << 1)) << + CollectionType::unique(true))); ASSERT_FALSE(status.isOK()); } diff --git a/src/mongo/s/chunk_version.h b/src/mongo/s/chunk_version.h index 258097ec9cf..41b9e03bae2 100644 --- a/src/mongo/s/chunk_version.h +++ b/src/mongo/s/chunk_version.h @@ -78,7 +78,7 @@ namespace mongo { static ChunkVersion IGNORED() { ChunkVersion version = ChunkVersion(); - version._epoch.init( 0, true ); // ignored OID is zero time, max machineId/inc + version._epoch.init(Date_t(), true); // ignored OID is zero time, max machineId/inc return version; } diff --git a/src/mongo/s/client/multi_host_query.cpp b/src/mongo/s/client/multi_host_query.cpp index b3b5727ee6c..294cfce2afd 100644 --- a/src/mongo/s/client/multi_host_query.cpp +++ b/src/mongo/s/client/multi_host_query.cpp @@ -181,7 +181,7 @@ namespace mongo { int timeoutMillis) { Date_t nowMillis = _systemEnv->currentTimeMillis(); - Date_t timeoutAtMillis = nowMillis + timeoutMillis; + Date_t timeoutAtMillis = nowMillis + Milliseconds(timeoutMillis); // Send out all queries scheduleQuery(hosts, query, timeoutAtMillis); @@ -228,8 +228,7 @@ namespace mongo { break; } - _nextResultCV.timed_wait(lk, - boost::posix_time::milliseconds(timeoutAtMillis - nowMillis)); + _nextResultCV.wait_for(lk, timeoutAtMillis - nowMillis); } dassert( !nextResult.isOK() || nextResult.getValue() ); diff --git a/src/mongo/s/client/multi_host_query_test.cpp b/src/mongo/s/client/multi_host_query_test.cpp index 384d08f815e..230825eba30 100644 --- a/src/mongo/s/client/multi_host_query_test.cpp +++ b/src/mongo/s/client/multi_host_query_test.cpp @@ -245,7 +245,7 @@ namespace { } Date_t currentTimeMillis() { - return _mockTimeMillis; + return Date_t::fromMillisSinceEpoch(_mockTimeMillis); } void doBlockingQuerySwallowResult(const ConnectionString& host, @@ -762,7 +762,7 @@ namespace { delete result.getValue(); // Make sure we get the next result - result = queryOp.waitForNextResult(4000); + result = queryOp.waitForNextResult(Date_t::fromMillisSinceEpoch(4000)); ASSERT_EQUALS(result.getStatus().code(), ErrorCodes::InternalError); } diff --git a/src/mongo/s/collection_metadata_test.cpp b/src/mongo/s/collection_metadata_test.cpp index 1eac51b271d..2f5f19210a7 100644 --- a/src/mongo/s/collection_metadata_test.cpp +++ b/src/mongo/s/collection_metadata_test.cpp @@ -69,7 +69,7 @@ namespace { collType.setNs(NamespaceString{"test.foo"}); collType.setKeyPattern( BSON("a" << 1) ); collType.setUnique( false ); - collType.setUpdatedAt( 1ULL ); + collType.setUpdatedAt( Date_t::fromMillisSinceEpoch(1) ); collType.setEpoch( epoch ); ASSERT_OK(collType.validate()); @@ -477,7 +477,7 @@ namespace { collType.setNs(NamespaceString{"test.foo"}); collType.setKeyPattern(BSON("a" << 1)); collType.setUnique(false); - collType.setUpdatedAt(1ULL); + collType.setUpdatedAt(Date_t::fromMillisSinceEpoch(1)); collType.setEpoch(epoch); _dummyConfig->insert(CollectionType::ConfigNS, collType.toBSON()); @@ -485,7 +485,8 @@ namespace { ChunkType::ns("test.foo") << ChunkType::min(BSON("a" << 10)) << ChunkType::max(BSON("a" << 20)) << - ChunkType::DEPRECATED_lastmod(chunkVersion.toLong()) << + ChunkType::DEPRECATED_lastmod( + Date_t::fromMillisSinceEpoch(chunkVersion.toLong())) << ChunkType::DEPRECATED_epoch(epoch) << ChunkType::shard("shard0000")); _dummyConfig->insert( ChunkType::ConfigNS, fooSingle ); @@ -824,15 +825,17 @@ namespace { collType.setNs(NamespaceString{"test.foo"}); collType.setKeyPattern(BSON("a" << 1)); collType.setUnique(false); - collType.setUpdatedAt(1ULL); + collType.setUpdatedAt(Date_t::fromMillisSinceEpoch(1)); collType.setEpoch(epoch); _dummyConfig->insert(CollectionType::ConfigNS, collType.toBSON()); - BSONObj fooSingle = BSON(ChunkType::name("test.foo-a_MinKey") << + BSONObj fooSingle = BSON( + ChunkType::name("test.foo-a_MinKey") << ChunkType::ns("test.foo") << ChunkType::min(BSON("a" << MINKEY << "b" << MINKEY)) << ChunkType::max(BSON("a" << MAXKEY << "b" << MAXKEY)) << - ChunkType::DEPRECATED_lastmod(chunkVersion.toLong()) << + ChunkType::DEPRECATED_lastmod(Date_t::fromMillisSinceEpoch( + chunkVersion.toLong())) << ChunkType::DEPRECATED_epoch(epoch) << ChunkType::shard("shard0000")); _dummyConfig->insert( ChunkType::ConfigNS, fooSingle ); @@ -892,25 +895,31 @@ namespace { collType.setNs(NamespaceString{"test.foo"}); collType.setKeyPattern(BSON("a" << 1)); collType.setUnique(false); - collType.setUpdatedAt(1ULL); + collType.setUpdatedAt(Date_t::fromMillisSinceEpoch(1)); collType.setEpoch(epoch); _dummyConfig->insert(CollectionType::ConfigNS, collType.toBSON()); - _dummyConfig->insert( ChunkType::ConfigNS, BSON(ChunkType::name("test.foo-a_10") << - ChunkType::ns("test.foo") << - ChunkType::min(BSON("a" << 10 << "b" << 0)) << - ChunkType::max(BSON("a" << 20 << "b" << 0)) << - ChunkType::DEPRECATED_lastmod(chunkVersion.toLong()) << - ChunkType::DEPRECATED_epoch(epoch) << - ChunkType::shard("shard0000")) ); - - _dummyConfig->insert( ChunkType::ConfigNS, BSON(ChunkType::name("test.foo-a_10") << - ChunkType::ns("test.foo") << - ChunkType::min(BSON("a" << 30 << "b" << 0)) << - ChunkType::max(BSON("a" << 40 << "b" << 0)) << - ChunkType::DEPRECATED_lastmod(chunkVersion.toLong()) << - ChunkType::DEPRECATED_epoch(epoch) << - ChunkType::shard("shard0000")) ); + _dummyConfig->insert( + ChunkType::ConfigNS, + BSON(ChunkType::name("test.foo-a_10") << + ChunkType::ns("test.foo") << + ChunkType::min(BSON("a" << 10 << "b" << 0)) << + ChunkType::max(BSON("a" << 20 << "b" << 0)) << + ChunkType::DEPRECATED_lastmod(Date_t::fromMillisSinceEpoch( + chunkVersion.toLong())) << + ChunkType::DEPRECATED_epoch(epoch) << + ChunkType::shard("shard0000")) ); + + _dummyConfig->insert( + ChunkType::ConfigNS, + BSON(ChunkType::name("test.foo-a_10") << + ChunkType::ns("test.foo") << + ChunkType::min(BSON("a" << 30 << "b" << 0)) << + ChunkType::max(BSON("a" << 40 << "b" << 0)) << + ChunkType::DEPRECATED_lastmod(Date_t::fromMillisSinceEpoch( + chunkVersion.toLong())) << + ChunkType::DEPRECATED_epoch(epoch) << + ChunkType::shard("shard0000")) ); ConnectionString configLoc = ConnectionString(HostAndPort(CONFIG_HOST_PORT)); ASSERT(configLoc.isValid()); @@ -1164,7 +1173,7 @@ namespace { collType.setNs(NamespaceString{"x.y"}); collType.setKeyPattern(BSON("a" << 1)); collType.setUnique(false); - collType.setUpdatedAt(1ULL); + collType.setUpdatedAt(Date_t::fromMillisSinceEpoch(1)); collType.setEpoch(epoch); _dummyConfig->insert(CollectionType::ConfigNS, collType.toBSON()); } @@ -1175,7 +1184,8 @@ namespace { ChunkType::ns("x.y") << ChunkType::min(BSON("a" << MINKEY)) << ChunkType::max(BSON("a" << 10)) << - ChunkType::DEPRECATED_lastmod(version.toLong()) << + ChunkType::DEPRECATED_lastmod( + Date_t::fromMillisSinceEpoch(version.toLong())) << ChunkType::DEPRECATED_epoch(version.epoch()) << ChunkType::shard("shard0000")) ); } @@ -1186,7 +1196,8 @@ namespace { ChunkType::ns("x.y") << ChunkType::min(BSON("a" << 10)) << ChunkType::max(BSON("a" << 20)) << - ChunkType::DEPRECATED_lastmod(version.toLong()) << + ChunkType::DEPRECATED_lastmod( + Date_t::fromMillisSinceEpoch(version.toLong())) << ChunkType::DEPRECATED_epoch(version.epoch()) << ChunkType::shard("shard0000")) ); } @@ -1197,7 +1208,8 @@ namespace { ChunkType::ns("x.y") << ChunkType::min(BSON("a" << 30)) << ChunkType::max(BSON("a" << MAXKEY)) << - ChunkType::DEPRECATED_lastmod(version.toLong()) << + ChunkType::DEPRECATED_lastmod( + Date_t::fromMillisSinceEpoch(version.toLong())) << ChunkType::DEPRECATED_epoch(version.epoch()) << ChunkType::shard("shard0000")) ); } diff --git a/src/mongo/s/config.cpp b/src/mongo/s/config.cpp index f7bdc8fbb5c..a7fde93c451 100644 --- a/src/mongo/s/config.cpp +++ b/src/mongo/s/config.cpp @@ -135,7 +135,9 @@ namespace mongo { if (_cm) { invariant(!_dropped); coll.setEpoch(_cm->getVersion().epoch()); - coll.setUpdatedAt(_cm->getVersion().toLong()); + // TODO(schwerin): The following isn't really a date, but is stored as one in-memory and + // in config.collections, as a historical oddity. + coll.setUpdatedAt(Date_t::fromMillisSinceEpoch(_cm->getVersion().toLong())); coll.setKeyPattern(_cm->getShardKeyPattern().toBSON()); coll.setUnique(_cm->isUnique()); } @@ -143,7 +145,7 @@ namespace mongo { invariant(_dropped); coll.setDropped(true); coll.setEpoch(ChunkVersion::DROPPED().epoch()); - coll.setUpdatedAt(jsTime()); + coll.setUpdatedAt(Date_t::now()); } uassertStatusOK(grid.catalogManager()->updateCollection(ns, coll)); diff --git a/src/mongo/s/metadata_loader_test.cpp b/src/mongo/s/metadata_loader_test.cpp index adfd0d86da5..8f34ec843a5 100644 --- a/src/mongo/s/metadata_loader_test.cpp +++ b/src/mongo/s/metadata_loader_test.cpp @@ -85,7 +85,7 @@ namespace { CollectionType collInfo; collInfo.setNs(NamespaceString{"test.foo"}); collInfo.setKeyPattern(BSON("a" << 1)); - collInfo.setUpdatedAt( 0 ); + collInfo.setUpdatedAt( Date_t() ); collInfo.setEpoch( OID() ); collInfo.setDropped( true ); ASSERT_OK(collInfo.validate()); @@ -159,7 +159,7 @@ namespace { CollectionType collInfo; collInfo.setNs(NamespaceString{"test.foo"}); - collInfo.setUpdatedAt(1ULL); + collInfo.setUpdatedAt(Date_t::fromMillisSinceEpoch(1)); collInfo.setKeyPattern( BSON("a" << 1) ); collInfo.setEpoch( OID::gen() ); ASSERT_OK(collInfo.validate()); @@ -204,7 +204,7 @@ namespace { collType.setNs(NamespaceString{"test.foo"}); collType.setKeyPattern(BSON("a" << 1)); collType.setUnique(false); - collType.setUpdatedAt(1ULL); + collType.setUpdatedAt(Date_t::fromMillisSinceEpoch(1)); collType.setEpoch(epoch); _dummyConfig->insert(CollectionType::ConfigNS, collType.toBSON()); } @@ -247,7 +247,7 @@ namespace { collType.setNs(NamespaceString{"test.foo"}); collType.setKeyPattern( BSON("a" << 1) ); collType.setUnique( false ); - collType.setUpdatedAt( 1ULL ); + collType.setUpdatedAt( Date_t::fromMillisSinceEpoch(1) ); collType.setEpoch( epoch ); ASSERT_OK(collType.validate()); @@ -314,15 +314,17 @@ namespace { collType.setNs(NamespaceString{"test.foo"}); collType.setKeyPattern(BSON("a" << 1)); collType.setUnique(false); - collType.setUpdatedAt(1ULL); + collType.setUpdatedAt(Date_t::fromMillisSinceEpoch(1)); collType.setEpoch(epoch); _dummyConfig->insert(CollectionType::ConfigNS, collType.toBSON()); - BSONObj fooSingle = BSON(ChunkType::name("test.foo-a_MinKey") << + BSONObj fooSingle = BSON( + ChunkType::name("test.foo-a_MinKey") << ChunkType::ns("test.foo") << ChunkType::min(BSON("a" << MINKEY)) << ChunkType::max(BSON("a" << MAXKEY)) << - ChunkType::DEPRECATED_lastmod(_maxCollVersion.toLong()) << + ChunkType::DEPRECATED_lastmod(Date_t::fromMillisSinceEpoch( + _maxCollVersion.toLong())) << ChunkType::DEPRECATED_epoch(epoch) << ChunkType::shard("shard0000")); _dummyConfig->insert( ChunkType::ConfigNS, fooSingle ); @@ -463,7 +465,7 @@ namespace { CollectionType coll; coll.setNs(NamespaceString{ns}); coll.setKeyPattern( BSON( "a" << 1 ) ); - coll.setUpdatedAt( 1ULL ); + coll.setUpdatedAt( Date_t::fromMillisSinceEpoch(1) ); coll.setEpoch( epoch ); ASSERT_OK(coll.validate()); diff --git a/src/mongo/s/type_lockpings.cpp b/src/mongo/s/type_lockpings.cpp index 853a76dd010..47beaea1485 100644 --- a/src/mongo/s/type_lockpings.cpp +++ b/src/mongo/s/type_lockpings.cpp @@ -99,7 +99,7 @@ namespace mongo { _process.clear(); _isProcessSet = false; - _ping = 0ULL; + _ping = Date_t(); _isPingSet = false; } diff --git a/src/mongo/s/type_lockpings_test.cpp b/src/mongo/s/type_lockpings_test.cpp index 402349a5fb8..487a8714e2c 100644 --- a/src/mongo/s/type_lockpings_test.cpp +++ b/src/mongo/s/type_lockpings_test.cpp @@ -39,7 +39,7 @@ namespace { TEST(Validity, MissingFields) { LockpingsType lockPing; - BSONObj objNoProcess = BSON(LockpingsType::ping(time(0))); + BSONObj objNoProcess = BSON(LockpingsType::ping(Date_t::now())); string errMsg; ASSERT(lockPing.parseBSON(objNoProcess, &errMsg)); ASSERT_EQUALS(errMsg, ""); @@ -54,13 +54,13 @@ namespace { TEST(Validity, Valid) { LockpingsType lockPing; BSONObj obj = BSON(LockpingsType::process("host.local:27017:1352918870:16807") << - LockpingsType::ping(1ULL)); + LockpingsType::ping(Date_t::fromMillisSinceEpoch(1))); string errMsg; ASSERT(lockPing.parseBSON(obj, &errMsg)); ASSERT_EQUALS(errMsg, ""); ASSERT_TRUE(lockPing.isValid(NULL)); ASSERT_EQUALS(lockPing.getProcess(), "host.local:27017:1352918870:16807"); - ASSERT_EQUALS(lockPing.getPing(), 1ULL); + ASSERT_EQUALS(lockPing.getPing(), Date_t::fromMillisSinceEpoch(1)); } TEST(Validity, BadType) { diff --git a/src/mongo/s/type_mongos.cpp b/src/mongo/s/type_mongos.cpp index 0ff363cbc86..07009c6a864 100644 --- a/src/mongo/s/type_mongos.cpp +++ b/src/mongo/s/type_mongos.cpp @@ -131,7 +131,7 @@ namespace mongo { _name.clear(); _isNameSet = false; - _ping = 0ULL; + _ping = Date_t(); _isPingSet = false; _up = 0; diff --git a/src/mongo/s/type_mongos_test.cpp b/src/mongo/s/type_mongos_test.cpp index 66eeda86898..1c0ab5be56d 100644 --- a/src/mongo/s/type_mongos_test.cpp +++ b/src/mongo/s/type_mongos_test.cpp @@ -40,7 +40,7 @@ namespace { TEST(Validity, MissingName) { MongosType mongos; string errMsg; - BSONObj obj = BSON(MongosType::ping(1ULL) << + BSONObj obj = BSON(MongosType::ping(Date_t::fromMillisSinceEpoch(1)) << MongosType::up(100) << MongosType::waiting(false) << MongosType::mongoVersion("x.x.x") << @@ -79,7 +79,7 @@ namespace { MongosType mongos; string errMsg; BSONObj obj = BSON(MongosType::name("localhost:27017") << - MongosType::ping(1ULL) << + MongosType::ping(Date_t::fromMillisSinceEpoch(1)) << MongosType::waiting(false) << MongosType::mongoVersion("x.x.x") << MongosType::configVersion(0)); @@ -98,7 +98,7 @@ namespace { MongosType mongos; string errMsg; BSONObj obj = BSON(MongosType::name("localhost:27017") << - MongosType::ping(1ULL) << + MongosType::ping(Date_t::fromMillisSinceEpoch(1)) << MongosType::up(100) << MongosType::mongoVersion("x.x.x") << MongosType::configVersion(0)); @@ -117,7 +117,7 @@ namespace { MongosType mongos; string errMsg; BSONObj obj = BSON(MongosType::name("localhost:27017") << - MongosType::ping(1ULL) << + MongosType::ping(Date_t::fromMillisSinceEpoch(1)) << MongosType::up(100) << MongosType::waiting(false) << MongosType::configVersion(0)); @@ -138,7 +138,7 @@ namespace { MongosType mongos; string errMsg; BSONObj obj = BSON(MongosType::name("localhost:27017") << - MongosType::ping(1ULL) << + MongosType::ping(Date_t::fromMillisSinceEpoch(1)) << MongosType::up(100) << MongosType::waiting(false) << MongosType::mongoVersion("x.x.x")); @@ -158,7 +158,7 @@ namespace { TEST(Validity, Valid) { MongosType mongos; BSONObj obj = BSON(MongosType::name("localhost:27017") << - MongosType::ping(1ULL) << + MongosType::ping(Date_t::fromMillisSinceEpoch(1)) << MongosType::up(100) << MongosType::waiting(false) << MongosType::mongoVersion("x.x.x") << @@ -168,7 +168,7 @@ namespace { ASSERT_EQUALS(errMsg, ""); ASSERT_TRUE(mongos.isValid(NULL)); ASSERT_EQUALS(mongos.getName(), "localhost:27017"); - ASSERT_EQUALS(mongos.getPing(), 1ULL); + ASSERT_EQUALS(mongos.getPing(), Date_t::fromMillisSinceEpoch(1)); ASSERT_EQUALS(mongos.getUp(), 100); ASSERT_EQUALS(mongos.getWaiting(), false); ASSERT_EQUALS(mongos.getMongoVersion(), "x.x.x"); diff --git a/src/mongo/s/version_manager.cpp b/src/mongo/s/version_manager.cpp index 102bd720643..f5437543afb 100644 --- a/src/mongo/s/version_manager.cpp +++ b/src/mongo/s/version_manager.cpp @@ -402,7 +402,7 @@ namespace mongo { } if ( result["reloadConfig"].trueValue() ) { - if( result["version"].timestampTime() == 0 ){ + if( result["version"].timestampTime() == Date_t() ){ warning() << "reloading full configuration for " << conf->name() << ", connection state indicates significant version changes"; diff --git a/src/mongo/s/write_ops/batched_command_response_test.cpp b/src/mongo/s/write_ops/batched_command_response_test.cpp index 3a7a2374770..e97b567e761 100644 --- a/src/mongo/s/write_ops/batched_command_response_test.cpp +++ b/src/mongo/s/write_ops/batched_command_response_test.cpp @@ -71,7 +71,7 @@ namespace { BatchedCommandResponse::errCode(-1) << BatchedCommandResponse::errMessage("this batch didn't work") << BatchedCommandResponse::n(0) << - BatchedCommandResponse::lastOp(Date_t(1)) << + BatchedCommandResponse::lastOp(mongo::Timestamp(1ULL)) << BatchedCommandResponse::writeErrors() << writeErrorsArray << BatchedCommandResponse::writeConcernError() << writeConcernError); diff --git a/src/mongo/scripting/engine.cpp b/src/mongo/scripting/engine.cpp index a3178880ea5..675c8e8600b 100644 --- a/src/mongo/scripting/engine.cpp +++ b/src/mongo/scripting/engine.cpp @@ -109,8 +109,9 @@ namespace { builder.appendNull(fieldName); break; case Date: - // TODO: make signed - builder.appendDate(fieldName, Date_t((unsigned long long)getNumber(scopeName))); + builder.appendDate(fieldName, + Date_t::fromMillisSinceEpoch(static_cast( + getNumber(scopeName)))); break; case Code: builder.appendCode(fieldName, getString(scopeName)); diff --git a/src/mongo/scripting/engine_v8-3.25.cpp b/src/mongo/scripting/engine_v8-3.25.cpp index cd8ff7aceeb..9b2f82fe359 100644 --- a/src/mongo/scripting/engine_v8-3.25.cpp +++ b/src/mongo/scripting/engine_v8-3.25.cpp @@ -1507,7 +1507,7 @@ namespace mongo { case mongo::Object: return mongoToLZV8(elem.embeddedObject(), readOnly); case mongo::Date: - return v8::Date::New(_isolate, (double) ((long long)elem.date().millis)); + return v8::Date::New(_isolate, static_cast(elem.date.toMillisSinceEpoch())); case mongo::Bool: return v8::Boolean::New(_isolate, elem.boolean()); case mongo::EOO: diff --git a/src/mongo/scripting/engine_v8.cpp b/src/mongo/scripting/engine_v8.cpp index 242e39be1a4..50477bbfb99 100644 --- a/src/mongo/scripting/engine_v8.cpp +++ b/src/mongo/scripting/engine_v8.cpp @@ -1435,7 +1435,7 @@ namespace mongo { case mongo::Object: return mongoToLZV8(elem.embeddedObject(), readOnly); case mongo::Date: - return v8::Date::New((double) ((long long)elem.date().millis)); + return v8::Date::New(static_cast(elem.date().toMillisSinceEpoch())); case mongo::Bool: return v8::Boolean::New(elem.boolean()); case mongo::EOO: @@ -1472,7 +1472,7 @@ namespace mongo { case mongo::bsonTimestamp: { v8::TryCatch tryCatch; - argv[0] = v8::Number::New(elem.timestampTime() / 1000); + argv[0] = v8::Number::New(elem.timestampTime().toMillisSinceEpoch() / 1000); argv[1] = v8::Number::New(elem.timestampInc()); v8::Handle ret = TimestampFT()->GetFunction()->NewInstance(2,argv); @@ -1658,7 +1658,7 @@ namespace mongo { } if (value->IsDate()) { long long dateval = (long long)(v8::Date::Cast(*value)->NumberValue()); - b.appendDate(sname, Date_t((unsigned long long) dateval)); + b.appendDate(sname, Date_t::fromMillisSinceEpoch(dateval)); return; } if (value->IsExternal()) diff --git a/src/mongo/unittest/unittest_helpers.h b/src/mongo/unittest/unittest_helpers.h index 97ab7cc1efe..44abea5e8d6 100644 --- a/src/mongo/unittest/unittest_helpers.h +++ b/src/mongo/unittest/unittest_helpers.h @@ -32,7 +32,7 @@ namespace mongo { class Timestamp; - struct Date_t; + class Date_t; // So that you can ASSERT_EQUALS two Timestamps std::ostream& operator<<(std::ostream& s, const Timestamp& ot); diff --git a/src/mongo/util/net/ssl_expiration.cpp b/src/mongo/util/net/ssl_expiration.cpp index 9f1d6ef9676..d05462ce442 100644 --- a/src/mongo/util/net/ssl_expiration.cpp +++ b/src/mongo/util/net/ssl_expiration.cpp @@ -32,14 +32,15 @@ #include #include "mongo/util/log.h" +#include "mongo/util/time_support.h" namespace mongo { - static const unsigned long long dayInMillis = 24 * 60 * 60 * 1000; + static const auto oneDay = stdx::chrono::hours(24); CertificateExpirationMonitor::CertificateExpirationMonitor(Date_t date) : _certExpiration(date) - , _lastCheckTime(Date_t(curTimeMillis64())) { + , _lastCheckTime(Date_t::now()) { } std::string CertificateExpirationMonitor::taskName() const { @@ -47,30 +48,28 @@ namespace mongo { } void CertificateExpirationMonitor::taskDoWork() { - const unsigned long long timeSinceLastCheck = - curTimeMillis64() - _lastCheckTime.millis; + const Milliseconds timeSinceLastCheck = Date_t::now() - _lastCheckTime; - if (timeSinceLastCheck < dayInMillis) + if (timeSinceLastCheck < oneDay) return; - const Date_t now = Date_t(curTimeMillis64()); + const Date_t now = Date_t::now(); _lastCheckTime = now; - if (_certExpiration.millis <= now.millis) { + if (_certExpiration <= now) { // The certificate has expired. warning() << "Server certificate is now invalid. It expired on " - << dateToCtimeString(_certExpiration); + << dateToISOStringUTC(_certExpiration); return; } - const unsigned long long remainingValidMillis = - _certExpiration.millis - now.millis; + const auto remainingValidDuration = _certExpiration - now; - if (remainingValidMillis / dayInMillis <= 30) { + if (remainingValidDuration <= 30 * oneDay) { // The certificate will expire in the next 30 days. warning() << "Server certificate will expire on " - << dateToCtimeString(_certExpiration) << " in " - << (remainingValidMillis / dayInMillis) + << dateToISOStringUTC(_certExpiration) << " in " + << durationCount(remainingValidDuration) / 24 << " days."; } } diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp index 6f9be1a1c03..652807e7e71 100644 --- a/src/mongo/util/net/ssl_manager.cpp +++ b/src/mongo/util/net/ssl_manager.cpp @@ -699,7 +699,7 @@ namespace mongo { "The provided SSL certificate is expired or not yet valid."); } - *serverCertificateExpirationDate = Date_t(notAfterMillis); + *serverCertificateExpirationDate = Date_t::fromMillisSinceEpoch(notAfterMillis); } return true; diff --git a/src/mongo/util/signal_handlers_synchronous.cpp b/src/mongo/util/signal_handlers_synchronous.cpp index e28d2796fd5..e0d69350203 100644 --- a/src/mongo/util/signal_handlers_synchronous.cpp +++ b/src/mongo/util/signal_handlers_synchronous.cpp @@ -114,7 +114,7 @@ namespace { // must hold streamMutex to call void writeMallocFreeStreamToLog() { logger::globalLogDomain()->append( - logger::MessageEventEphemeral(curTimeMillis64(), + logger::MessageEventEphemeral(Date_t::now(), logger::LogSeverity::Severe(), getThreadName(), mallocFreeOStream.str())); diff --git a/src/mongo/util/time_support.cpp b/src/mongo/util/time_support.cpp index 69369582058..f6e44c1e3a3 100644 --- a/src/mongo/util/time_support.cpp +++ b/src/mongo/util/time_support.cpp @@ -41,6 +41,7 @@ #include "mongo/bson/util/builder.h" #include "mongo/platform/cstdint.h" #include "mongo/util/assert_util.h" +#include "mongo/util/mongoutils/str.h" #ifdef _WIN32 #include @@ -64,15 +65,80 @@ timegm(struct tm *const tmp); namespace mongo { +namespace { + template Stream& streamPut(Stream& os, Microseconds us) { + return os << us.count() << "\xce\xbcs"; + } + + template Stream& streamPut(Stream& os, Milliseconds ms) { + return os << ms.count() << "ms"; + } + + template Stream& streamPut(Stream& os, Seconds s) { + return os << s.count() << 's'; + } +} // namespace + + std::ostream& operator<<(std::ostream& os, Microseconds us) { + return streamPut(os, us); + } + + std::ostream& operator<<(std::ostream& os, Milliseconds ms) { + return streamPut(os, ms); + } + std::ostream& operator<<(std::ostream& os, Seconds s) { + return streamPut(os, s); + } + + template + StringBuilderImpl& operator<<(StringBuilderImpl& os, Microseconds us) { + return streamPut(os, us); + } + + template + StringBuilderImpl& operator<<(StringBuilderImpl& os, Milliseconds ms) { + return streamPut(os, ms); + } + + template + StringBuilderImpl& operator<<(StringBuilderImpl& os, Seconds s) { + return streamPut(os, s); + } + + template StringBuilderImpl& operator<<(StringBuilderImpl&, + Microseconds); + template StringBuilderImpl& operator<<(StringBuilderImpl&, + Milliseconds); + template StringBuilderImpl& operator<<(StringBuilderImpl&, + Seconds); + template StringBuilderImpl& operator<<(StringBuilderImpl&, + Microseconds); + template StringBuilderImpl& operator<<(StringBuilderImpl&, + Milliseconds); + template StringBuilderImpl& operator<<(StringBuilderImpl&, + Seconds); + + Date_t Date_t::max() { + return fromMillisSinceEpoch(std::numeric_limits::max()); + } + + Date_t Date_t::now() { + return fromMillisSinceEpoch(curTimeMillis64()); + } + bool Date_t::isFormatable() const { + if (millis < 0) { + return false; + } if (sizeof(time_t) == sizeof(int32_t)) { - return millis < 2147483647000ULL; // "2038-01-19T03:14:07Z" + return millis < 2147483647000LL; // "2038-01-19T03:14:07Z" } else { - return millis < 32535215999000ULL; // "3000-12-31T23:59:59Z" + return millis < 32535215999000LL; // "3000-12-31T23:59:59Z" } } + // jsTime_virtual_skew is just for testing. a test command manipulates it. long long jsTime_virtual_skew = 0; boost::thread_specific_ptr jsTime_virtual_thread_skew; @@ -690,7 +756,11 @@ namespace { resultMillis += (tzAdjSecs * 1000); - return StatusWith(resultMillis); + if (resultMillis > static_cast(std::numeric_limits::max())) { + return {ErrorCodes::BadValue, + str::stream() << dateString << " is too far in the future"}; + } + return Date_t::fromMillisSinceEpoch(static_cast(resultMillis)); } #undef MONGO_ISO_DATE_FMT_NO_TZ @@ -709,9 +779,10 @@ namespace { } time_t Date_t::toTimeT() const { - verify((long long)millis >= 0); // TODO when millis is signed, delete - verify(((long long)millis/1000) < (std::numeric_limits::max)()); - return millis / 1000; + const auto secs = millis / 1000; + verify(secs >= std::numeric_limits::min()); + verify(secs <= std::numeric_limits::max()); + return secs; } boost::gregorian::date currentDate() { @@ -848,7 +919,11 @@ namespace { } /** Date_t is milliseconds since epoch */ - Date_t jsTime(); + Date_t jsTime() { + return Date_t::now() + + Milliseconds(getJSTimeVirtualThreadSkew()) + + Milliseconds(getJSTimeVirtualSkew()); + } /** warning this will wrap */ unsigned curTimeMicros(); @@ -860,12 +935,6 @@ namespace { boost::xtime_get(&xt, MONGO_BOOST_TIME_UTC); return ((unsigned long long)xt.sec) * 1000 + xt.nsec / 1000000; } - Date_t jsTime() { - boost::xtime xt; - boost::xtime_get(&xt, MONGO_BOOST_TIME_UTC); - unsigned long long t = xt.nsec / 1000000; - return ((unsigned long long) xt.sec * 1000) + t + getJSTimeVirtualSkew() + getJSTimeVirtualThreadSkew(); - } static unsigned long long getFiletime() { FILETIME ft; @@ -975,12 +1044,7 @@ namespace { gettimeofday(&tv, NULL); return ((unsigned long long)tv.tv_sec) * 1000 + tv.tv_usec / 1000; } - Date_t jsTime() { - timeval tv; - gettimeofday(&tv, NULL); - unsigned long long t = tv.tv_usec / 1000; - return ((unsigned long long) tv.tv_sec * 1000) + t + getJSTimeVirtualSkew() + getJSTimeVirtualThreadSkew(); - } + unsigned long long curTimeMicros64() { timeval tv; gettimeofday(&tv, NULL); diff --git a/src/mongo/util/time_support.h b/src/mongo/util/time_support.h index 81db17cbd76..d8f04c293c3 100644 --- a/src/mongo/util/time_support.h +++ b/src/mongo/util/time_support.h @@ -37,30 +37,131 @@ #include #include "mongo/base/status_with.h" +#include "mongo/stdx/chrono.h" namespace mongo { - typedef boost::posix_time::milliseconds Milliseconds; - typedef boost::posix_time::seconds Seconds; + template class StringBuilderImpl; + + using Microseconds = stdx::chrono::microseconds; + using Milliseconds = stdx::chrono::milliseconds; + using Seconds = stdx::chrono::seconds; + using Minutes = stdx::chrono::minutes; + using stdx::chrono::duration_cast; void time_t_to_Struct(time_t t, struct tm * buf , bool local = false ); std::string time_t_to_String(time_t t); std::string time_t_to_String_short(time_t t); - struct Date_t { - // TODO: make signed (and look for related TODO's) - unsigned long long millis; + // + // Operators for putting durations to streams. + // + + std::ostream& operator<<(std::ostream& os, Microseconds us); + std::ostream& operator<<(std::ostream& os, Milliseconds ms); + std::ostream& operator<<(std::ostream& os, Seconds s); + + template + StringBuilderImpl& operator<<(StringBuilderImpl& os, Microseconds us); + + template + StringBuilderImpl& operator<<(StringBuilderImpl& os, Milliseconds ms); + + template + StringBuilderImpl& operator<<(StringBuilderImpl& os, Seconds s); + + /** + * Convenience method for reading the count of a duration with specified units. + * + * Use when logging or comparing to integers, to ensure that you're using + * the units you intend. + * + * E.g., log() << durationCount(some duration) << " seconds"; + */ + template long long durationCount(DIn d) { + return duration_cast(d).count(); + } + + class Date_t { + public: + static Date_t max(); + static Date_t now(); + + static Date_t fromMillisSinceEpoch(long long m) { + return Date_t(m); + } + + template + static Date_t fromDurationSinceEpoch(Duration d) { + return fromMillisSinceEpoch(durationCount(d)); + } + Date_t(): millis(0) {} - Date_t(unsigned long long m): millis(m) {} - operator unsigned long long&() { return millis; } - operator const unsigned long long&() const { return millis; } + void toTm (tm *buf); std::string toString() const; time_t toTimeT() const; int64_t asInt64() const { - return static_cast(millis); + return toMillisSinceEpoch(); } + unsigned long long toULL() const { return static_cast(asInt64()); } + Milliseconds toDurationSinceEpoch() const { return Milliseconds(toMillisSinceEpoch()); } + long long toMillisSinceEpoch() const { return static_cast(millis); } bool isFormatable() const; + + template + Date_t& operator+=(Duration d) { + millis += duration_cast(d).count(); + return *this; + } + + template + Date_t& operator-=(Duration d) { + return *this += (-d); + } + + template + Date_t operator+(Duration d) const { + Date_t result = *this; + result += d; + return result; + } + + template + Date_t operator-(Duration d) const { + Date_t result = *this; + result -= d; + return result; + } + + Milliseconds operator-(Date_t other) const { return Milliseconds(millis - other.millis); } + + bool operator==(Date_t other) const { + return toDurationSinceEpoch() == other.toDurationSinceEpoch(); + } + + bool operator!=(Date_t other) const { return !(*this == other); } + + bool operator<(Date_t other) const { + return toDurationSinceEpoch() < other.toDurationSinceEpoch(); + } + + bool operator>(Date_t other) const { + return toDurationSinceEpoch() > other.toDurationSinceEpoch(); + } + + bool operator<=(Date_t other) const { + return !(*this > other); + } + + bool operator>=(Date_t other) const { + return !(*this < other); + } + + private: + Date_t(long long m): millis(m) {} + + long long millis; }; // uses ISO 8601 dates without trailing Z diff --git a/src/mongo/util/time_support_test.cpp b/src/mongo/util/time_support_test.cpp index 0580584c62e..91fd9d2e8a9 100644 --- a/src/mongo/util/time_support_test.cpp +++ b/src/mongo/util/time_support_test.cpp @@ -68,37 +68,37 @@ namespace { TEST(TimeFormatting, DateAsISO8601UTCString) { ASSERT_EQUALS(std::string("1970-01-01T00:00:00.000Z"), - dateToISOStringUTC(Date_t(0))); + dateToISOStringUTC(Date_t())); ASSERT_EQUALS(std::string("1970-06-30T01:06:40.981Z"), - dateToISOStringUTC(Date_t(15556000981ULL))); + dateToISOStringUTC(Date_t::fromMillisSinceEpoch(15556000981LL))); if (!isTimeTSmall) ASSERT_EQUALS(std::string("2058-02-20T18:29:11.100Z"), - dateToISOStringUTC(Date_t(2781455351100ULL))); + dateToISOStringUTC(Date_t::fromMillisSinceEpoch(2781455351100LL))); ASSERT_EQUALS(std::string("2013-02-20T18:29:11.100Z"), - dateToISOStringUTC(Date_t(1361384951100ULL))); + dateToISOStringUTC(Date_t::fromMillisSinceEpoch(1361384951100LL))); } TEST(TimeFormatting, DateAsISO8601LocalString) { ASSERT_EQUALS(std::string("1969-12-31T19:00:00.000-0500"), - dateToISOStringLocal(Date_t(0))); + dateToISOStringLocal(Date_t())); ASSERT_EQUALS(std::string("1970-06-29T21:06:40.981-0400"), - dateToISOStringLocal(Date_t(15556000981ULL))); + dateToISOStringLocal(Date_t::fromMillisSinceEpoch(15556000981LL))); if (!isTimeTSmall) ASSERT_EQUALS(std::string("2058-02-20T13:29:11.100-0500"), - dateToISOStringLocal(Date_t(2781455351100ULL))); + dateToISOStringLocal(Date_t::fromMillisSinceEpoch(2781455351100LL))); ASSERT_EQUALS(std::string("2013-02-20T13:29:11.100-0500"), - dateToISOStringLocal(Date_t(1361384951100ULL))); + dateToISOStringLocal(Date_t::fromMillisSinceEpoch(1361384951100LL))); } TEST(TimeFormatting, DateAsCtimeString) { - ASSERT_EQUALS(std::string("Wed Dec 31 19:00:00.000"), dateToCtimeString(Date_t(0))); + ASSERT_EQUALS(std::string("Wed Dec 31 19:00:00.000"), dateToCtimeString(Date_t())); ASSERT_EQUALS(std::string("Mon Jun 29 21:06:40.981"), - dateToCtimeString(Date_t(15556000981ULL))); + dateToCtimeString(Date_t::fromMillisSinceEpoch(15556000981LL))); if (!isTimeTSmall) ASSERT_EQUALS(std::string("Wed Feb 20 13:29:11.100"), - dateToCtimeString(Date_t(2781455351100ULL))); + dateToCtimeString(Date_t::fromMillisSinceEpoch(2781455351100LL))); ASSERT_EQUALS(std::string("Wed Feb 20 13:29:11.100"), - dateToCtimeString(Date_t(1361384951100ULL))); + dateToCtimeString(Date_t::fromMillisSinceEpoch(1361384951100LL))); } static std::string stringstreamDate(void (*formatter)(std::ostream&, Date_t), Date_t date) { @@ -109,38 +109,48 @@ namespace { TEST(TimeFormatting, DateAsISO8601UTCStream) { ASSERT_EQUALS(std::string("1970-01-01T00:00:00.000Z"), - stringstreamDate(outputDateAsISOStringUTC, Date_t(0))); + stringstreamDate(outputDateAsISOStringUTC, Date_t())); ASSERT_EQUALS(std::string("1970-06-30T01:06:40.981Z"), - stringstreamDate(outputDateAsISOStringUTC, Date_t(15556000981ULL))); + stringstreamDate(outputDateAsISOStringUTC, + Date_t::fromMillisSinceEpoch(15556000981LL))); if (!isTimeTSmall) ASSERT_EQUALS(std::string("2058-02-20T18:29:11.100Z"), - stringstreamDate(outputDateAsISOStringUTC, Date_t(2781455351100ULL))); + stringstreamDate(outputDateAsISOStringUTC, + Date_t::fromMillisSinceEpoch(2781455351100LL))); ASSERT_EQUALS(std::string("2013-02-20T18:29:11.100Z"), - stringstreamDate(outputDateAsISOStringUTC, Date_t(1361384951100ULL))); + stringstreamDate(outputDateAsISOStringUTC, + Date_t::fromMillisSinceEpoch(1361384951100LL))); } TEST(TimeFormatting, DateAsISO8601LocalStream) { ASSERT_EQUALS(std::string("1969-12-31T19:00:00.000-0500"), - stringstreamDate(outputDateAsISOStringLocal, Date_t(0))); + stringstreamDate(outputDateAsISOStringLocal, Date_t())); ASSERT_EQUALS(std::string("1970-06-29T21:06:40.981-0400"), - stringstreamDate(outputDateAsISOStringLocal, Date_t(15556000981ULL))); + stringstreamDate(outputDateAsISOStringLocal, + Date_t::fromMillisSinceEpoch(15556000981LL))); if (!isTimeTSmall) ASSERT_EQUALS(std::string("2058-02-20T13:29:11.100-0500"), - stringstreamDate(outputDateAsISOStringLocal, Date_t(2781455351100ULL))); + stringstreamDate(outputDateAsISOStringLocal, + Date_t::fromMillisSinceEpoch(2781455351100LL))); ASSERT_EQUALS(std::string("2013-02-20T13:29:11.100-0500"), - stringstreamDate(outputDateAsISOStringLocal, Date_t(1361384951100ULL))); + stringstreamDate(outputDateAsISOStringLocal, + Date_t::fromMillisSinceEpoch(1361384951100LL))); } TEST(TimeFormatting, DateAsCtimeStream) { ASSERT_EQUALS(std::string("Wed Dec 31 19:00:00.000"), - stringstreamDate(outputDateAsCtime, Date_t(0))); + stringstreamDate(outputDateAsCtime, + Date_t::fromMillisSinceEpoch(0))); ASSERT_EQUALS(std::string("Mon Jun 29 21:06:40.981"), - stringstreamDate(outputDateAsCtime, Date_t(15556000981ULL))); + stringstreamDate(outputDateAsCtime, + Date_t::fromMillisSinceEpoch(15556000981LL))); if (!isTimeTSmall) ASSERT_EQUALS(std::string("Wed Feb 20 13:29:11.100"), - stringstreamDate(outputDateAsCtime, Date_t(2781455351100ULL))); + stringstreamDate(outputDateAsCtime, + Date_t::fromMillisSinceEpoch(2781455351100LL))); ASSERT_EQUALS(std::string("Wed Feb 20 13:29:11.100"), - stringstreamDate(outputDateAsCtime, Date_t(1361384951100ULL))); + stringstreamDate(outputDateAsCtime, + Date_t::fromMillisSinceEpoch(1361384951100LL))); } TEST(TimeParsing, DateAsISO8601UTC) { @@ -151,45 +161,45 @@ namespace { StatusWith swull = dateFromISOString("1971-02-03T04:05:06.789Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401906789ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401906789LL); swull = dateFromISOString("1971-02-03T04:05:06.78Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401906780ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401906780LL); swull = dateFromISOString("1971-02-03T04:05:06.7Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401906700ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401906700LL); swull = dateFromISOString("1971-02-03T04:05:06Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401906000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401906000LL); swull = dateFromISOString("1971-02-03T04:05Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401900000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401900000LL); swull = dateFromISOString("1970-01-01T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 0ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 0LL); swull = dateFromISOString("1970-06-30T01:06:40.981Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 15556000981ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 15556000981LL); if (!isTimeTSmall) { swull = dateFromISOString("2058-02-20T18:29:11.100Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2781455351100ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2781455351100LL); swull = dateFromISOString("3001-01-01T08:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 32535244800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 32535244800000LL); } swull = dateFromISOString("2013-02-20T18:29:11.100Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1361384951100ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1361384951100LL); } TEST(TimeParsing, DateAsISO8601Local) { @@ -200,79 +210,79 @@ namespace { StatusWith swull = dateFromISOString("1971-02-03T09:16:06.789+0511"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401906789ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401906789LL); swull = dateFromISOString("1971-02-03T09:16:06.78+0511"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401906780ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401906780LL); swull = dateFromISOString("1971-02-03T09:16:06.7+0511"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401906700ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401906700LL); swull = dateFromISOString("1971-02-03T09:16:06+0511"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401906000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401906000LL); swull = dateFromISOString("1971-02-03T09:16+0511"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 34401900000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 34401900000LL); swull = dateFromISOString("1970-01-01T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 0ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 0LL); swull = dateFromISOString("1970-06-30T01:06:40.981Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 15556000981ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 15556000981LL); // Local times not supported //swull = dateFromISOString("1970-01-01T00:00:00.001"); //ASSERT_OK(swull.getStatus()); - //ASSERT_EQUALS(swull.getValue(), 18000001ULL); + //ASSERT_EQUALS(swull.getValue().asInt64(), 18000001LL); //swull = dateFromISOString("1970-01-01T00:00:00.01"); //ASSERT_OK(swull.getStatus()); - //ASSERT_EQUALS(swull.getValue(), 18000010ULL); + //ASSERT_EQUALS(swull.getValue().asInt64(), 18000010LL); //swull = dateFromISOString("1970-01-01T00:00:00.1"); //ASSERT_OK(swull.getStatus()); - //ASSERT_EQUALS(swull.getValue(), 18000100ULL); + //ASSERT_EQUALS(swull.getValue().asInt64(), 18000100LL); //swull = dateFromISOString("1970-01-01T00:00:01"); //ASSERT_OK(swull.getStatus()); - //ASSERT_EQUALS(swull.getValue(), 18001000ULL); + //ASSERT_EQUALS(swull.getValue().asInt64(), 18001000LL); //swull = dateFromISOString("1970-01-01T00:01"); //ASSERT_OK(swull.getStatus()); - //ASSERT_EQUALS(swull.getValue(), 18060000ULL); + //ASSERT_EQUALS(swull.getValue().asInt64(), 18060000LL); swull = dateFromISOString("1970-06-29T21:06:40.981-0400"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 15556000981ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 15556000981LL); if (!isTimeTSmall) { swull = dateFromISOString("2058-02-20T13:29:11.100-0500"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2781455351100ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2781455351100LL); swull = dateFromISOString("3000-12-31T23:59:59Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 32535215999000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 32535215999000LL); } else { swull = dateFromISOString("2038-01-19T03:14:07Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2147483647000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2147483647000LL); } swull = dateFromISOString("2013-02-20T13:29:11.100-0500"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1361384951100ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1361384951100LL); swull = dateFromISOString("2013-02-20T13:29:11.100-0501"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1361385011100ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1361385011100LL); } TEST(TimeParsing, InvalidDates) { @@ -392,426 +402,436 @@ namespace { TEST(TimeParsing, LeapYears) { StatusWith swull = dateFromISOString("1972-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 68169600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 68169600000LL); swull = dateFromISOString("1976-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 194400000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 194400000000LL); swull = dateFromISOString("1980-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 320630400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 320630400000LL); swull = dateFromISOString("1984-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 446860800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 446860800000LL); swull = dateFromISOString("1988-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 573091200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 573091200000LL); swull = dateFromISOString("1992-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 699321600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 699321600000LL); swull = dateFromISOString("1996-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 825552000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 825552000000LL); swull = dateFromISOString("2000-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 951782400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 951782400000LL); swull = dateFromISOString("2004-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1078012800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1078012800000LL); swull = dateFromISOString("2008-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1204243200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1204243200000LL); swull = dateFromISOString("2012-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1330473600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1330473600000LL); swull = dateFromISOString("2016-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1456704000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1456704000000LL); swull = dateFromISOString("2020-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1582934400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1582934400000LL); swull = dateFromISOString("2024-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1709164800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1709164800000LL); swull = dateFromISOString("2028-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1835395200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1835395200000LL); swull = dateFromISOString("2032-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 1961625600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 1961625600000LL); swull = dateFromISOString("2036-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2087856000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2087856000000LL); if (!isTimeTSmall) { swull = dateFromISOString("2040-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2214086400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2214086400000LL); swull = dateFromISOString("2044-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2340316800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2340316800000LL); swull = dateFromISOString("2048-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2466547200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2466547200000LL); swull = dateFromISOString("2052-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2592777600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2592777600000LL); swull = dateFromISOString("2056-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2719008000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2719008000000LL); swull = dateFromISOString("2060-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2845238400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2845238400000LL); swull = dateFromISOString("2064-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 2971468800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 2971468800000LL); swull = dateFromISOString("2068-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 3097699200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 3097699200000LL); swull = dateFromISOString("2072-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 3223929600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 3223929600000LL); swull = dateFromISOString("2076-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 3350160000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 3350160000000LL); swull = dateFromISOString("2080-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 3476390400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 3476390400000LL); swull = dateFromISOString("2084-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 3602620800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 3602620800000LL); swull = dateFromISOString("2088-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 3728851200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 3728851200000LL); swull = dateFromISOString("2092-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 3855081600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 3855081600000LL); swull = dateFromISOString("2096-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 3981312000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 3981312000000LL); swull = dateFromISOString("2104-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 4233686400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 4233686400000LL); swull = dateFromISOString("2108-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 4359916800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 4359916800000LL); swull = dateFromISOString("2112-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 4486147200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 4486147200000LL); swull = dateFromISOString("2116-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 4612377600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 4612377600000LL); swull = dateFromISOString("2120-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 4738608000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 4738608000000LL); swull = dateFromISOString("2124-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 4864838400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 4864838400000LL); swull = dateFromISOString("2128-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 4991068800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 4991068800000LL); swull = dateFromISOString("2132-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 5117299200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 5117299200000LL); swull = dateFromISOString("2136-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 5243529600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 5243529600000LL); swull = dateFromISOString("2140-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 5369760000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 5369760000000LL); swull = dateFromISOString("2144-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 5495990400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 5495990400000LL); swull = dateFromISOString("2148-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 5622220800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 5622220800000LL); swull = dateFromISOString("2152-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 5748451200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 5748451200000LL); swull = dateFromISOString("2156-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 5874681600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 5874681600000LL); swull = dateFromISOString("2160-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 6000912000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 6000912000000LL); swull = dateFromISOString("2164-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 6127142400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 6127142400000LL); swull = dateFromISOString("2168-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 6253372800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 6253372800000LL); swull = dateFromISOString("2172-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 6379603200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 6379603200000LL); swull = dateFromISOString("2176-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 6505833600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 6505833600000LL); swull = dateFromISOString("2180-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 6632064000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 6632064000000LL); swull = dateFromISOString("2184-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 6758294400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 6758294400000LL); swull = dateFromISOString("2188-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 6884524800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 6884524800000LL); swull = dateFromISOString("2192-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 7010755200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 7010755200000LL); swull = dateFromISOString("2196-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 7136985600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 7136985600000LL); swull = dateFromISOString("2204-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 7389360000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 7389360000000LL); swull = dateFromISOString("2208-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 7515590400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 7515590400000LL); swull = dateFromISOString("2212-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 7641820800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 7641820800000LL); swull = dateFromISOString("2216-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 7768051200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 7768051200000LL); swull = dateFromISOString("2220-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 7894281600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 7894281600000LL); swull = dateFromISOString("2224-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 8020512000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 8020512000000LL); swull = dateFromISOString("2228-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 8146742400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 8146742400000LL); swull = dateFromISOString("2232-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 8272972800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 8272972800000LL); swull = dateFromISOString("2236-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 8399203200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 8399203200000LL); swull = dateFromISOString("2240-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 8525433600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 8525433600000LL); swull = dateFromISOString("2244-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 8651664000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 8651664000000LL); swull = dateFromISOString("2248-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 8777894400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 8777894400000LL); swull = dateFromISOString("2252-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 8904124800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 8904124800000LL); swull = dateFromISOString("2256-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 9030355200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 9030355200000LL); swull = dateFromISOString("2260-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 9156585600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 9156585600000LL); swull = dateFromISOString("2264-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 9282816000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 9282816000000LL); swull = dateFromISOString("2268-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 9409046400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 9409046400000LL); swull = dateFromISOString("2272-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 9535276800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 9535276800000LL); swull = dateFromISOString("2276-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 9661507200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 9661507200000LL); swull = dateFromISOString("2280-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 9787737600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 9787737600000LL); swull = dateFromISOString("2284-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 9913968000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 9913968000000LL); swull = dateFromISOString("2288-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 10040198400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 10040198400000LL); swull = dateFromISOString("2292-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 10166428800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 10166428800000LL); swull = dateFromISOString("2296-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 10292659200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 10292659200000LL); swull = dateFromISOString("2304-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 10545033600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 10545033600000LL); swull = dateFromISOString("2308-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 10671264000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 10671264000000LL); swull = dateFromISOString("2312-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 10797494400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 10797494400000LL); swull = dateFromISOString("2316-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 10923724800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 10923724800000LL); swull = dateFromISOString("2320-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 11049955200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 11049955200000LL); swull = dateFromISOString("2324-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 11176185600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 11176185600000LL); swull = dateFromISOString("2328-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 11302416000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 11302416000000LL); swull = dateFromISOString("2332-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 11428646400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 11428646400000LL); swull = dateFromISOString("2336-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 11554876800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 11554876800000LL); swull = dateFromISOString("2340-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 11681107200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 11681107200000LL); swull = dateFromISOString("2344-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 11807337600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 11807337600000LL); swull = dateFromISOString("2348-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 11933568000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 11933568000000LL); swull = dateFromISOString("2352-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 12059798400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 12059798400000LL); swull = dateFromISOString("2356-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 12186028800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 12186028800000LL); swull = dateFromISOString("2360-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 12312259200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 12312259200000LL); swull = dateFromISOString("2364-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 12438489600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 12438489600000LL); swull = dateFromISOString("2368-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 12564720000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 12564720000000LL); swull = dateFromISOString("2372-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 12690950400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 12690950400000LL); swull = dateFromISOString("2376-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 12817180800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 12817180800000LL); swull = dateFromISOString("2380-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 12943411200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 12943411200000LL); swull = dateFromISOString("2384-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 13069641600000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 13069641600000LL); swull = dateFromISOString("2388-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 13195872000000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 13195872000000LL); swull = dateFromISOString("2392-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 13322102400000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 13322102400000LL); swull = dateFromISOString("2396-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 13448332800000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 13448332800000LL); swull = dateFromISOString("2400-02-29T00:00:00.000Z"); ASSERT_OK(swull.getStatus()); - ASSERT_EQUALS(swull.getValue(), 13574563200000ULL); + ASSERT_EQUALS(swull.getValue().asInt64(), 13574563200000LL); } } + TEST(TimeFormatting, DurationFormatting) { + ASSERT_EQUALS("52\xce\xbcs", static_cast(str::stream() << Microseconds(52))); + ASSERT_EQUALS("52ms", static_cast(str::stream() << Milliseconds(52))); + ASSERT_EQUALS("52s", static_cast(str::stream() << Seconds(52))); + + std::ostringstream os; + os << Milliseconds(52) << Microseconds(52) << Seconds(52); + ASSERT_EQUALS("52ms52\xce\xbcs52s", os.str()); + } + } // namespace } // namespace mongo -- cgit v1.2.1