From 102e832f218ecdec47d8eebf4e827072075325d7 Mon Sep 17 00:00:00 2001 From: Jason Carey Date: Mon, 11 Jan 2016 17:54:27 -0500 Subject: SERVER-21476 ChunkVersion assumes little endian Alter ChunkVersion to rely on bit arithmetic on a 64 bit unsigned, rather than union type punning, to extract the minor and major versions. This improves portability on big endian systems. --- src/mongo/s/chunk_version.h | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) (limited to 'src/mongo/s/chunk_version.h') diff --git a/src/mongo/s/chunk_version.h b/src/mongo/s/chunk_version.h index 7aa8c4ee138..007e05f7353 100644 --- a/src/mongo/s/chunk_version.h +++ b/src/mongo/s/chunk_version.h @@ -52,10 +52,11 @@ class StatusWith; */ struct ChunkVersion { public: - ChunkVersion() : _minor(0), _major(0), _epoch(OID()) {} + ChunkVersion() : _combined(0), _epoch(OID()) {} ChunkVersion(int major, int minor, const OID& epoch) - : _minor(minor), _major(major), _epoch(epoch) {} + : _combined(static_cast(minor) | (static_cast(major) << 32)), + _epoch(epoch) {} /** * Interprets the specified BSON content as the format for commands, which is in the form: @@ -103,12 +104,11 @@ public: } void incMajor() { - _major++; - _minor = 0; + _combined = static_cast(majorVersion() + 1) << 32; } void incMinor() { - _minor++; + _combined++; } // Note: this shouldn't be used as a substitute for version except in specific cases - @@ -122,11 +122,11 @@ public: } int majorVersion() const { - return _major; + return _combined >> 32; } int minorVersion() const { - return _minor; + return _combined & 0xFFFF; } OID epoch() const { @@ -163,7 +163,7 @@ public: bool isWriteCompatibleWith(const ChunkVersion& otherVersion) const { if (!hasEqualEpoch(otherVersion)) return false; - return otherVersion._major == _major; + return otherVersion.majorVersion() == majorVersion(); } // Is this the same version? @@ -192,10 +192,10 @@ public: if (otherVersion._epoch != _epoch) return false; - if (_major != otherVersion._major) - return _major < otherVersion._major; + if (majorVersion() != otherVersion.majorVersion()) + return majorVersion() < otherVersion.majorVersion(); - return _minor < otherVersion._minor; + return minorVersion() < otherVersion.minorVersion(); } // Is this in the same epoch? @@ -343,21 +343,14 @@ public: std::string toString() const { StringBuilder sb; - sb << _major << "|" << _minor << "||" << _epoch; + sb << majorVersion() << "|" << minorVersion() << "||" << _epoch; return sb.str(); } BSONObj toBSON() const; private: - union { - struct { - int _minor; - int _major; - }; - - uint64_t _combined; - }; + uint64_t _combined; OID _epoch; }; -- cgit v1.2.1