summaryrefslogtreecommitdiff
path: root/src/mongo/bson/timestamp.h
diff options
context:
space:
mode:
authorEric Milkie <milkie@10gen.com>2015-04-09 08:02:20 -0400
committerEric Milkie <milkie@10gen.com>2015-04-09 08:02:20 -0400
commit48f14493a3751483b67144897a44ed3297720f8c (patch)
tree596e6a9a7993de99622cd8d17cbc549a5a217704 /src/mongo/bson/timestamp.h
parent04a120d6dc50d6bb1fd5073ea28a6c8ddc07fecd (diff)
downloadmongo-48f14493a3751483b67144897a44ed3297720f8c.tar.gz
Revert "SERVER-15047 Remove undefined behavior from Timestamp"
This reverts commit e87716a9286b6aa6f63a513012e55f6e42f634a2.
Diffstat (limited to 'src/mongo/bson/timestamp.h')
-rw-r--r--src/mongo/bson/timestamp.h128
1 files changed, 54 insertions, 74 deletions
diff --git a/src/mongo/bson/timestamp.h b/src/mongo/bson/timestamp.h
index c18fb85bb07..b223b5deb50 100644
--- a/src/mongo/bson/timestamp.h
+++ b/src/mongo/bson/timestamp.h
@@ -27,74 +27,57 @@
#pragma once
-#include <type_traits>
-
-#include "mongo/base/data_cursor.h"
#include "mongo/base/data_view.h"
-#include "mongo/platform/cstdint.h"
#include "mongo/bson/util/builder.h"
-#include "mongo/platform/endian.h"
#include "mongo/util/assert_util.h"
namespace mongo {
- class StringData;
- /**
- * Timestamp: A combination of current second plus an ordinal value, held together in a
- * single 64-bit integer, stored in memory as little endian, regardless of local endianness.
+ /* Timestamp: A combination of current second plus an ordinal value.
*/
+#pragma pack(4)
class Timestamp {
- public:
-
- Timestamp() = default;
+ unsigned i; // ordinal comes first so we can do a single 64 bit compare on little endian
+ unsigned secs;
+ public:
+ unsigned getSecs() const {
+ return secs;
+ }
+ unsigned getInc() const {
+ return i;
+ }
- explicit Timestamp(Date_t date) {
- _data = endian::nativeToLittle(date.millis);
- dassert(static_cast<int>(getSecs()) >= 0);
+ Timestamp(Date_t date) {
+ reinterpret_cast<unsigned long long&>(*this) = date.millis;
+ dassert( (int)secs >= 0 );
}
- Timestamp(unsigned secs, unsigned inc) {
- DataCursor(reinterpret_cast<char*>(&_data))
- .writeLEAndAdvance<uint32_t>(inc)
- .writeLE<uint32_t>(secs);
+ 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 getSecs() const {
- static_assert(sizeof(unsigned) == sizeof(uint32_t), "unsigned must be uint32");
- return ConstDataCursor(reinterpret_cast<const char*>(&_data))
- .skip<uint32_t>()
- .readLE<uint32_t>();
- }
-
- unsigned getInc() const {
- static_assert(sizeof(unsigned) == sizeof(uint32_t), "unsigned must be uint32");
- return ConstDataCursor(reinterpret_cast<const char*>(&_data))
- .readLE<uint32_t>();
- }
-
unsigned long long asULL() const {
- return endian::littleToNative(_data);
+ return reinterpret_cast<const unsigned long long*>(&i)[0];
}
-
long long asLL() const {
- const unsigned long long val = endian::littleToNative(_data);
- return static_cast<long long>(val);
+ return reinterpret_cast<const long long*>(&i)[0];
}
- bool isNull() const {
- return getSecs() == 0;
- }
-
- // 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;
-
- // Set the value of this Timestamp to match that of the pointed to bytes. The
- // return value points to the first byte not consumed by the read operation.
- const void* readFrom(const void* bytes);
+ bool isNull() const { return secs == 0; }
std::string toStringLong() const;
@@ -102,35 +85,32 @@ namespace mongo {
std::string toString() const;
- private:
- uint64_t _data = 0;
- };
-
- inline bool operator==(const Timestamp& lhs, const Timestamp& rhs) {
- return (lhs.getInc() == rhs.getInc()) && (lhs.getSecs() == rhs.getSecs());
- }
-
- inline bool operator!=(const Timestamp& lhs, const Timestamp& rhs) {
- return !(lhs == rhs);
- }
-
- inline bool operator<(const Timestamp& lhs, const Timestamp& rhs) {
- if ( lhs.getSecs() != rhs.getSecs() ) {
- return lhs.getSecs() < rhs.getSecs();
+ bool operator==(const Timestamp& r) const {
+ return i == r.i && secs == r.secs;
+ }
+ bool operator!=(const Timestamp& r) const {
+ return !(*this == r);
+ }
+ bool operator<(const Timestamp& r) const {
+ if ( secs != r.secs )
+ return secs < r.secs;
+ return i < r.i;
+ }
+ bool operator<=(const Timestamp& r) const {
+ return *this < r || *this == r;
+ }
+ bool operator>(const Timestamp& r) const {
+ return !(*this <= r);
+ }
+ bool operator>=(const Timestamp& r) const {
+ return !(*this < r);
}
- return lhs.getInc() < rhs.getInc();
- }
-
- inline bool operator<=(const Timestamp& lhs, const Timestamp& rhs) {
- return (lhs < rhs) || (lhs == rhs);
- }
- inline bool operator>(const Timestamp& lhs, const Timestamp& rhs) {
- return !(lhs <= rhs);
- }
+ // 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;
- inline bool operator>=(const Timestamp& lhs, const Timestamp& rhs) {
- return !(lhs < rhs);
- }
+ };
+#pragma pack()
} // namespace mongo