diff options
Diffstat (limited to 'src/mongo/bson')
22 files changed, 192 insertions, 236 deletions
diff --git a/src/mongo/bson/bson_db.h b/src/mongo/bson/bson_db.h deleted file mode 100644 index 941aea1935c..00000000000 --- a/src/mongo/bson/bson_db.h +++ /dev/null @@ -1,111 +0,0 @@ -/** @file bson_db.h */ - -/* Copyright 2009 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -/* - This file contains the implementation of BSON-related methods that are required - by the MongoDB database server. - - Normally, for standalone BSON usage, you do not want this file - it will tend to - pull in some other files from the MongoDB project. Thus, bson.h (the main file - one would use) does not include this file. -*/ - -#pragma once - -#include "mongo/base/data_view.h" -#include "mongo/bson/optime.h" -#include "mongo/util/time_support.h" - -namespace mongo { - - inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, OpTime optime) { - optime.append(_b, fieldName); - return *this; - } - - inline BSONObjBuilder& BSONObjBuilder::appendTimestamp( StringData fieldName ) { - return append(fieldName, OpTime()); - } - - inline BSONObjBuilder& BSONObjBuilder::appendTimestamp( StringData fieldName, - unsigned long long val ) { - return append(fieldName, OpTime(val)); - } - - inline OpTime BSONElement::_opTime() const { - if( type() == mongo::Date || type() == Timestamp ) - return OpTime(ConstDataView(value()).readLE<unsigned long long>()); - return OpTime(); - } - - inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const DateNowLabeler& id) { - _builder->appendDate(_fieldName, jsTime()); - _fieldName = StringData(); - return *_builder; - } - - inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const NullLabeler& id) { - _builder->appendNull(_fieldName); - _fieldName = StringData(); - return *_builder; - } - - inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const UndefinedLabeler& id) { - _builder->appendUndefined(_fieldName); - _fieldName = StringData(); - return *_builder; - } - - - inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const MinKeyLabeler& id) { - _builder->appendMinKey(_fieldName); - _fieldName = StringData(); - return *_builder; - } - - inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const MaxKeyLabeler& id) { - _builder->appendMaxKey(_fieldName); - _fieldName = StringData(); - return *_builder; - } - - template<class T> inline - BSONObjBuilder& BSONObjBuilderValueStream::operator<<( T value ) { - _builder->append(_fieldName, value); - _fieldName = StringData(); - return *_builder; - } - - template<class T> - BSONObjBuilder& Labeler::operator<<( T value ) { - s_->subobj()->append( l_.l_, value ); - return *s_->_builder; - } - -} diff --git a/src/mongo/bson/bson_validate.cpp b/src/mongo/bson/bson_validate.cpp index 778a8d83018..b2b55bbe9f8 100644 --- a/src/mongo/bson/bson_validate.cpp +++ b/src/mongo/bson/bson_validate.cpp @@ -220,7 +220,7 @@ namespace mongo { case NumberDouble: case NumberLong: - case Timestamp: + case bsonTimestamp: case Date: if ( !buffer->skip( sizeof(int64_t) ) ) return makeError("invalid bson", idElem); diff --git a/src/mongo/bson/bsonelement.cpp b/src/mongo/bson/bsonelement.cpp index 6d3c9ac5c3d..c48e55f4e0a 100644 --- a/src/mongo/bson/bsonelement.cpp +++ b/src/mongo/bson/bsonelement.cpp @@ -264,7 +264,7 @@ namespace mongo { s << "\"" << escape(_asCode()) << "\""; break; - case Timestamp: + case bsonTimestamp: if ( format == TenGen ) { s << "Timestamp( " << ( timestampTime() / 1000 ) << ", " << timestampInc() << " )"; } @@ -461,7 +461,7 @@ namespace mongo { case NumberInt: x = 4; break; - case Timestamp: + case bsonTimestamp: case mongo::Date: case NumberDouble: case NumberLong: @@ -541,7 +541,7 @@ namespace mongo { case NumberInt: x = 4; break; - case Timestamp: + case bsonTimestamp: case mongo::Date: case NumberDouble: case NumberLong: @@ -700,7 +700,7 @@ namespace mongo { } } break; - case Timestamp: + case bsonTimestamp: s << "Timestamp " << timestampTime() << "|" << timestampInc(); break; default: @@ -843,7 +843,7 @@ namespace mongo { return f==0 ? 0 : 1; case Bool: return *l.value() - *r.value(); - case Timestamp: + case bsonTimestamp: // unsigned compare for timestamps - note they are not really dates but (ordinal + time_t) if ( l.date() < r.date() ) return -1; @@ -963,8 +963,8 @@ namespace mongo { boost::hash_combine(hash, elem.boolean()); break; - case mongo::Timestamp: - boost::hash_combine(hash, elem._opTime().asDate()); + case mongo::bsonTimestamp: + boost::hash_combine(hash, elem.timestamp().asULL()); break; case mongo::Date: diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h index b79cc19d0cd..cc5c687f8d7 100644 --- a/src/mongo/bson/bsonelement.h +++ b/src/mongo/bson/bsonelement.h @@ -37,13 +37,14 @@ #include "mongo/base/data_view.h" #include "mongo/bson/bsontypes.h" #include "mongo/bson/oid.h" +#include "mongo/bson/timestamp.h" #include "mongo/platform/cstdint.h" namespace mongo { - class OpTime; class BSONObj; class BSONElement; class BSONObjBuilder; + class Timestamp; typedef BSONElement be; typedef BSONObj bo; @@ -452,6 +453,12 @@ namespace mongo { } } + Timestamp timestamp() const { + if( type() == mongo::Date || type() == bsonTimestamp ) + return Timestamp(ConstDataView(value()).readLE<unsigned long long>()); + return Timestamp(); + } + Date_t timestampTime() const { unsigned long long t = ConstDataView(value() + 4).readLE<unsigned int>(); return t * 1000; @@ -524,7 +531,6 @@ namespace mongo { } std::string _asCode() const; - OpTime _opTime() const; template<typename T> bool coerce( T* out ) const; diff --git a/src/mongo/bson/bsonobj.h b/src/mongo/bson/bsonobj.h index d138658edb6..b8fc7501acf 100644 --- a/src/mongo/bson/bsonobj.h +++ b/src/mongo/bson/bsonobj.h @@ -36,6 +36,9 @@ #include <utility> #include <vector> +#include "mongo/bson/timestamp.h" +#include "mongo/bson/bsontypes.h" +#include "mongo/bson/oid.h" #include "mongo/bson/bsonelement.h" #include "mongo/base/data_view.h" #include "mongo/base/disallow_copying.h" diff --git a/src/mongo/bson/bsonobjbuilder.cpp b/src/mongo/bson/bsonobjbuilder.cpp index ca3ac311527..d0fd2665ff3 100644 --- a/src/mongo/bson/bsonobjbuilder.cpp +++ b/src/mongo/bson/bsonobjbuilder.cpp @@ -33,7 +33,7 @@ #include <boost/lexical_cast.hpp> -#include "mongo/bson/optime.h" +#include "mongo/bson/timestamp.h" #include "mongo/util/log.h" namespace mongo { @@ -56,7 +56,7 @@ namespace mongo { appendBool(fieldName, true); //appendDate( fieldName , numeric_limits<long long>::min() ); return; - case Timestamp: + case bsonTimestamp: appendTimestamp( fieldName , 0 ); return; case Undefined: // shared with EOO appendUndefined( fieldName ); return; @@ -110,8 +110,8 @@ namespace mongo { appendMinForType( fieldName, Object ); return; case Date: appendDate( fieldName , std::numeric_limits<long long>::max() ); return; - case Timestamp: - append( fieldName , OpTime::max() ); return; + case bsonTimestamp: + append( fieldName , Timestamp::max() ); return; case Undefined: // shared with EOO appendUndefined( fieldName ); return; diff --git a/src/mongo/bson/bsonobjbuilder.h b/src/mongo/bson/bsonobjbuilder.h index a679140dae0..2910e7da58a 100644 --- a/src/mongo/bson/bsonobjbuilder.h +++ b/src/mongo/bson/bsonobjbuilder.h @@ -458,16 +458,16 @@ namespace mongo { return *this; } - // Append a Timestamp field -- will be updated to next OpTime on db insert. + // Append a Timestamp field -- will be updated to next server Timestamp BSONObjBuilder& appendTimestamp( StringData fieldName ); BSONObjBuilder& appendTimestamp( StringData fieldName , unsigned long long val ); /** - * To store an OpTime in BSON, use this function. + * To store a Timestamp in BSON, use this function. * This captures both the secs and inc fields. */ - BSONObjBuilder& append(StringData fieldName, OpTime optime); + BSONObjBuilder& append(StringData fieldName, Timestamp timestamp); /* Append an element of the deprecated DBRef type. @@ -905,4 +905,62 @@ namespace mongo { inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e, const BSONObj& f) { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e << f) ); } + inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const DateNowLabeler& id) { + _builder->appendDate(_fieldName, jsTime()); + _fieldName = StringData(); + return *_builder; + } + + inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const NullLabeler& id) { + _builder->appendNull(_fieldName); + _fieldName = StringData(); + return *_builder; + } + + inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const UndefinedLabeler& id) { + _builder->appendUndefined(_fieldName); + _fieldName = StringData(); + return *_builder; + } + + + inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const MinKeyLabeler& id) { + _builder->appendMinKey(_fieldName); + _fieldName = StringData(); + return *_builder; + } + + inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const MaxKeyLabeler& id) { + _builder->appendMaxKey(_fieldName); + _fieldName = StringData(); + return *_builder; + } + + template<class T> inline + BSONObjBuilder& BSONObjBuilderValueStream::operator<<( T value ) { + _builder->append(_fieldName, value); + _fieldName = StringData(); + return *_builder; + } + + template<class T> + BSONObjBuilder& Labeler::operator<<( T value ) { + s_->subobj()->append( l_.l_, value ); + return *s_->_builder; + } + + inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, Timestamp optime) { + optime.append(_b, fieldName); + return *this; + } + + inline BSONObjBuilder& BSONObjBuilder::appendTimestamp( StringData fieldName ) { + return append(fieldName, Timestamp()); + } + + inline BSONObjBuilder& BSONObjBuilder::appendTimestamp( StringData fieldName, + unsigned long long val ) { + return append(fieldName, Timestamp(val)); + } + } diff --git a/src/mongo/bson/bsonobjbuilder_test.cpp b/src/mongo/bson/bsonobjbuilder_test.cpp index f2b44c552f8..d18fb900537 100644 --- a/src/mongo/bson/bsonobjbuilder_test.cpp +++ b/src/mongo/bson/bsonobjbuilder_test.cpp @@ -44,7 +44,6 @@ namespace { using mongo::BSONObj; using mongo::BSONObjBuilder; using mongo::BSONType; - using mongo::OpTime; const long long maxEncodableInt = (1 << 30) - 1; const long long minEncodableInt = -maxEncodableInt; @@ -249,16 +248,16 @@ namespace { ASSERT_EQUALS(o1, o2); } - TEST(BSONObjBuilderTest, AppendMaxTimestampOpTimeConversion) { + TEST(BSONObjBuilderTest, AppendMaxTimestampConversion) { BSONObjBuilder b; - b.appendMaxForType("a", mongo::Timestamp); + b.appendMaxForType("a", mongo::bsonTimestamp); BSONObj o1 = b.obj(); BSONElement e = o1.getField("a"); ASSERT_FALSE(e.eoo()); - OpTime opTime = e._opTime(); - ASSERT_FALSE(opTime.isNull()); + mongo::Timestamp timestamp = e.timestamp(); + ASSERT_FALSE(timestamp.isNull()); } } // unnamed namespace diff --git a/src/mongo/bson/bsontypes.cpp b/src/mongo/bson/bsontypes.cpp index 3f83009ad1f..5fd15364d1d 100644 --- a/src/mongo/bson/bsontypes.cpp +++ b/src/mongo/bson/bsontypes.cpp @@ -94,7 +94,7 @@ namespace mongo { case Symbol: return "Symbol"; case CodeWScope: return "CodeWScope"; case NumberInt: return "NumberInt32"; - case Timestamp: return "Timestamp"; + case bsonTimestamp: return "Timestamp"; case NumberLong: return "NumberLong64"; // JSTypeMax doesn't make sense to turn into a string; overlaps with highest-valued type case MaxKey: return "MaxKey"; diff --git a/src/mongo/bson/bsontypes.h b/src/mongo/bson/bsontypes.h index 449c617f13c..3b7e98fee42 100644 --- a/src/mongo/bson/bsontypes.h +++ b/src/mongo/bson/bsontypes.h @@ -87,8 +87,8 @@ namespace mongo { CodeWScope=15, /** 32 bit signed integer */ NumberInt = 16, - /** Updated to a Date with value next OpTime on insert */ - Timestamp = 17, + /** Two 32 bit signed integers */ + bsonTimestamp = 17, /** 64 bit integer */ NumberLong = 18, /** max type that is not MaxKey */ @@ -150,7 +150,7 @@ namespace mongo { return 40; case mongo::Date: return 45; - case Timestamp: + case bsonTimestamp: return 47; case RegEx: return 50; diff --git a/src/mongo/bson/mutable/const_element-inl.h b/src/mongo/bson/mutable/const_element-inl.h index 5988747a64b..af059fd37a2 100644 --- a/src/mongo/bson/mutable/const_element-inl.h +++ b/src/mongo/bson/mutable/const_element-inl.h @@ -141,7 +141,7 @@ namespace mutablebson { return _basis.getValueInt(); } - inline OpTime ConstElement::getValueTimestamp() const { + inline Timestamp ConstElement::getValueTimestamp() const { return _basis.getValueTimestamp(); } diff --git a/src/mongo/bson/mutable/const_element.h b/src/mongo/bson/mutable/const_element.h index bbeb43ca5cf..c1c5d2f4da7 100644 --- a/src/mongo/bson/mutable/const_element.h +++ b/src/mongo/bson/mutable/const_element.h @@ -82,7 +82,7 @@ namespace mutablebson { inline bool isValueNull() const; inline StringData getValueSymbol() const; inline int32_t getValueInt() const; - inline OpTime getValueTimestamp() const; + inline Timestamp getValueTimestamp() const; inline int64_t getValueLong() const; inline bool isValueMinKey() const; inline bool isValueMaxKey() const; diff --git a/src/mongo/bson/mutable/document.cpp b/src/mongo/bson/mutable/document.cpp index d2223a26500..db7fa0bec5e 100644 --- a/src/mongo/bson/mutable/document.cpp +++ b/src/mongo/bson/mutable/document.cpp @@ -1858,7 +1858,7 @@ namespace mutablebson { return setValue(newValue._repIdx); } - Status Element::setValueTimestamp(const OpTime value) { + Status Element::setValueTimestamp(const Timestamp value) { verify(ok()); Document::Impl& impl = getDocument().getImpl(); const ElementRep& thisRep = impl.getElementRep(_repIdx); @@ -2477,13 +2477,13 @@ namespace mutablebson { return Element(this, impl.insertLeafElement(leafRef, fieldName.size() + 1)); } - Element Document::makeElementTimestamp(StringData fieldName, const OpTime value) { + Element Document::makeElementTimestamp(StringData fieldName, const Timestamp value) { Impl& impl = getImpl(); dassert(impl.doesNotAlias(fieldName)); BSONObjBuilder& builder = impl.leafBuilder(); const int leafRef = builder.len(); - builder.appendTimestamp(fieldName, value.asDate()); + builder.append(fieldName, value); return Element(this, impl.insertLeafElement(leafRef, fieldName.size() + 1)); } diff --git a/src/mongo/bson/mutable/document.h b/src/mongo/bson/mutable/document.h index 293df8638f7..2abfc1ca527 100644 --- a/src/mongo/bson/mutable/document.h +++ b/src/mongo/bson/mutable/document.h @@ -375,8 +375,8 @@ namespace mutablebson { /** Create a new integer Element with the given value and field name. */ Element makeElementInt(StringData fieldName, int32_t value); - /** Create a new timetamp Element with the given value and field name. */ - Element makeElementTimestamp(StringData fieldName, OpTime value); + /** Create a new timestamp Element with the given value and field name. */ + Element makeElementTimestamp(StringData fieldName, Timestamp value); /** Create a new long integer Element with the given value and field name. */ Element makeElementLong(StringData fieldName, int64_t value); diff --git a/src/mongo/bson/mutable/element-inl.h b/src/mongo/bson/mutable/element-inl.h index ca8a5147b42..7e9249a5b15 100644 --- a/src/mongo/bson/mutable/element-inl.h +++ b/src/mongo/bson/mutable/element-inl.h @@ -91,9 +91,9 @@ namespace mutablebson { return getValue()._numberInt(); } - inline OpTime Element::getValueTimestamp() const { - dassert(hasValue() && isType(mongo::Timestamp)); - return getValue()._opTime(); + inline Timestamp Element::getValueTimestamp() const { + dassert(hasValue() && isType(mongo::bsonTimestamp)); + return getValue().timestamp(); } inline int64_t Element::getValueLong() const { diff --git a/src/mongo/bson/mutable/element.cpp b/src/mongo/bson/mutable/element.cpp index 73bdc02af42..407a27c3df7 100644 --- a/src/mongo/bson/mutable/element.cpp +++ b/src/mongo/bson/mutable/element.cpp @@ -129,7 +129,7 @@ namespace mutablebson { return pushBack(getDocument().makeElementInt(fieldName, value)); } - Status Element::appendTimestamp(StringData fieldName, OpTime value) { + Status Element::appendTimestamp(StringData fieldName, Timestamp value) { return pushBack(getDocument().makeElementTimestamp(fieldName, value)); } diff --git a/src/mongo/bson/mutable/element.h b/src/mongo/bson/mutable/element.h index a84c29e92fd..f58771f2513 100644 --- a/src/mongo/bson/mutable/element.h +++ b/src/mongo/bson/mutable/element.h @@ -318,7 +318,7 @@ namespace mutablebson { inline int32_t getValueInt() const; /** Get the value from a timestamp valued Element. */ - inline OpTime getValueTimestamp() const; + inline Timestamp getValueTimestamp() const; /** Get the value from a long valued Element. */ inline int64_t getValueLong() const; @@ -438,7 +438,7 @@ namespace mutablebson { Status setValueInt(int32_t value); /** Set the value of this Element to the given timestamp. */ - Status setValueTimestamp(OpTime value); + Status setValueTimestamp(Timestamp value); /** Set the value of this Element to the given long integer */ Status setValueLong(int64_t value); @@ -562,7 +562,7 @@ namespace mutablebson { Status appendInt(StringData fieldName, int32_t value); /** Append the provided timestamp as a new field with the provided name. */ - Status appendTimestamp(StringData fieldName, OpTime value); + Status appendTimestamp(StringData fieldName, Timestamp value); /** Append the provided long integer as a new field with the provided name. */ Status appendLong(StringData fieldName, int64_t value); diff --git a/src/mongo/bson/mutable/mutable_bson_test.cpp b/src/mongo/bson/mutable/mutable_bson_test.cpp index f2d4b289d3b..47cca65fb30 100644 --- a/src/mongo/bson/mutable/mutable_bson_test.cpp +++ b/src/mongo/bson/mutable/mutable_bson_test.cpp @@ -553,8 +553,8 @@ namespace { t0.setValueLong(12345LL); ASSERT_EQUALS(mongo::NumberLong, t0.getType()); - t0.setValueTimestamp(mongo::OpTime()); - ASSERT_EQUALS(mongo::Timestamp, t0.getType()); + t0.setValueTimestamp(mongo::Timestamp()); + ASSERT_EQUALS(mongo::bsonTimestamp, t0.getType()); t0.setValueDate(12345LL); ASSERT_EQUALS(mongo::Date, t0.getType()); @@ -609,42 +609,42 @@ namespace { TEST(TimestampType, createElement) { mmb::Document doc; - mmb::Element t0 = doc.makeElementTimestamp("t0", mongo::OpTime()); - ASSERT(mongo::OpTime() == t0.getValueTimestamp()); + mmb::Element t0 = doc.makeElementTimestamp("t0", mongo::Timestamp()); + ASSERT(mongo::Timestamp() == t0.getValueTimestamp()); - mmb::Element t1 = doc.makeElementTimestamp("t1", mongo::OpTime(123, 456)); - ASSERT(mongo::OpTime(123, 456) == t1.getValueTimestamp()); + mmb::Element t1 = doc.makeElementTimestamp("t1", mongo::Timestamp(123, 456)); + ASSERT(mongo::Timestamp(123, 456) == t1.getValueTimestamp()); } TEST(TimestampType, setElement) { mmb::Document doc; - mmb::Element t0 = doc.makeElementTimestamp("t0", mongo::OpTime()); - t0.setValueTimestamp(mongo::OpTime(123, 456)); - ASSERT(mongo::OpTime(123, 456) == t0.getValueTimestamp()); + mmb::Element t0 = doc.makeElementTimestamp("t0", mongo::Timestamp()); + t0.setValueTimestamp(mongo::Timestamp(123, 456)); + ASSERT(mongo::Timestamp(123, 456) == t0.getValueTimestamp()); - // Try setting to other types and back to OpTime + // Try setting to other types and back to Timestamp t0.setValueLong(1234567890); ASSERT_EQUALS(1234567890LL, t0.getValueLong()); - t0.setValueTimestamp(mongo::OpTime(789, 321)); - ASSERT(mongo::OpTime(789, 321) == t0.getValueTimestamp()); + t0.setValueTimestamp(mongo::Timestamp(789, 321)); + ASSERT(mongo::Timestamp(789, 321) == t0.getValueTimestamp()); t0.setValueString("foo bar baz"); ASSERT_EQUALS("foo bar baz", t0.getValueString()); - t0.setValueTimestamp(mongo::OpTime(9876, 5432)); - ASSERT(mongo::OpTime(9876, 5432) == t0.getValueTimestamp()); + t0.setValueTimestamp(mongo::Timestamp(9876, 5432)); + ASSERT(mongo::Timestamp(9876, 5432) == t0.getValueTimestamp()); } TEST(TimestampType, appendElement) { mmb::Document doc; mmb::Element t0 = doc.makeElementObject("e0"); - t0.appendTimestamp("a timestamp field", mongo::OpTime(1352151971, 471)); + t0.appendTimestamp("a timestamp field", mongo::Timestamp(1352151971, 471)); mmb::Element it = mmb::findFirstChildNamed(t0, "a timestamp field"); ASSERT_TRUE(it.ok()); - ASSERT(mongo::OpTime(1352151971, 471) == it.getValueTimestamp()); + ASSERT(mongo::Timestamp(1352151971, 471) == it.getValueTimestamp()); } TEST(SafeNumType, createElement) { @@ -2264,11 +2264,11 @@ namespace { TEST(TypeSupport, EncodingEquivalenceTimestamp) { mongo::BSONObjBuilder builder; const char name[] = "thing"; - const mongo::OpTime value1 = mongo::OpTime(mongo::jsTime()); + const mongo::Timestamp value1 = mongo::Timestamp(mongo::jsTime()); builder.append(name, value1); mongo::BSONObj source = builder.done(); const mongo::BSONElement thing = source.firstElement(); - ASSERT_TRUE(thing.type() == mongo::Timestamp); + ASSERT_TRUE(thing.type() == mongo::bsonTimestamp); mmb::Document doc; @@ -2276,7 +2276,7 @@ namespace { ASSERT_OK(doc.root().appendTimestamp(name, value1)); mmb::Element a = doc.root().rightChild(); ASSERT_TRUE(a.ok()); - ASSERT_EQUALS(a.getType(), mongo::Timestamp); + ASSERT_EQUALS(a.getType(), mongo::bsonTimestamp); ASSERT_TRUE(a.hasValue()); ASSERT_TRUE(value1 == mmb::ConstElement(a).getValueTimestamp()); @@ -2284,7 +2284,7 @@ namespace { ASSERT_OK(doc.root().appendElement(thing)); mmb::Element b = doc.root().rightChild(); ASSERT_TRUE(b.ok()); - ASSERT_EQUALS(b.getType(), mongo::Timestamp); + ASSERT_EQUALS(b.getType(), mongo::bsonTimestamp); ASSERT_TRUE(b.hasValue()); // Construct via setValue call. @@ -2292,7 +2292,7 @@ namespace { mmb::Element c = doc.root().rightChild(); ASSERT_TRUE(c.ok()); c.setValueTimestamp(value1); - ASSERT_EQUALS(c.getType(), mongo::Timestamp); + ASSERT_EQUALS(c.getType(), mongo::bsonTimestamp); ASSERT_TRUE(c.hasValue()); // Ensure identity: @@ -2788,7 +2788,7 @@ namespace { } TEST(DocumentInPlace, TimestampLifecycle) { - mongo::BSONObj obj(BSON("x" << mongo::OpTime(mongo::Date_t(1000)))); + mongo::BSONObj obj(BSON("x" << mongo::Timestamp(mongo::Date_t(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::OpTime(mongo::Date_t(20000))); + x.setValueTimestamp(mongo::Timestamp(mongo::Date_t(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::Timestamp)); - ASSERT_TRUE(mongo::OpTime(mongo::Date_t(20000)) == x.getValueTimestamp()); + ASSERT_TRUE(x.isType(mongo::bsonTimestamp)); + ASSERT_TRUE(mongo::Timestamp(mongo::Date_t(20000)) == x.getValueTimestamp()); // TODO: When in-place updates for leaf elements is implemented, add tests here. } diff --git a/src/mongo/bson/optime.cpp b/src/mongo/bson/timestamp.cpp index ff044533a65..cfd43fe8fe2 100644 --- a/src/mongo/bson/optime.cpp +++ b/src/mongo/bson/timestamp.cpp @@ -26,27 +26,49 @@ */ #include "mongo/bson/bsontypes.h" -#include "mongo/bson/optime.h" +#include "mongo/bson/timestamp.h" +#include <ctime> #include <iostream> #include <limits> -#include <ctime> +#include <sstream> #include "mongo/platform/cstdint.h" +#include "mongo/util/time_support.h" namespace mongo { - OpTime OpTime::max() { + Timestamp Timestamp::max() { unsigned int t = static_cast<unsigned int>(std::numeric_limits<int32_t>::max()); unsigned int i = std::numeric_limits<uint32_t>::max(); - return OpTime(t, i); + return Timestamp(t, i); } - void OpTime::append(BufBuilder& builder, const StringData& fieldName) const { + void Timestamp::append(BufBuilder& builder, const StringData& fieldName) const { // No endian conversions needed, since we store in-memory representation // in little endian format, regardless of target endian. - builder.appendNum( static_cast<char>(Timestamp) ); + builder.appendNum( static_cast<char>(bsonTimestamp) ); builder.appendStr( fieldName ); - builder.appendNum( asDate() ); + builder.appendNum( asULL() ); } + + std::string Timestamp::toStringLong() const { + std::stringstream ss; + ss << time_t_to_String_short(secs) << ' '; + ss << std::hex << secs << ':' << i; + return ss.str(); + } + + std::string Timestamp::toStringPretty() const { + std::stringstream ss; + ss << time_t_to_String_short(secs) << ':' << std::hex << i; + return ss.str(); + } + + std::string Timestamp::toString() const { + std::stringstream ss; + ss << std::hex << secs << ':' << i; + return ss.str(); + } + } diff --git a/src/mongo/bson/optime.h b/src/mongo/bson/timestamp.h index bcd6ae3e5a8..b223b5deb50 100644 --- a/src/mongo/bson/optime.h +++ b/src/mongo/bson/timestamp.h @@ -27,24 +27,16 @@ #pragma once -#include <boost/thread/condition.hpp> -#include <sstream> - +#include "mongo/base/data_view.h" #include "mongo/bson/util/builder.h" #include "mongo/util/assert_util.h" -#include "mongo/util/concurrency/mutex.h" -#include "mongo/util/time_support.h" namespace mongo { - struct ClockSkewException : public DBException { - ClockSkewException() : DBException( "clock skew exception" , 20001 ) {} - }; - - /* Operation sequence #. A combination of current second plus an ordinal value. + /* Timestamp: A combination of current second plus an ordinal value. */ #pragma pack(4) - class OpTime { + class Timestamp { unsigned i; // ordinal comes first so we can do a single 64 bit compare on little endian unsigned secs; public: @@ -55,30 +47,30 @@ namespace mongo { return i; } - OpTime(Date_t date) { + Timestamp(Date_t date) { reinterpret_cast<unsigned long long&>(*this) = date.millis; dassert( (int)secs >= 0 ); } - OpTime(unsigned a, unsigned b) { + Timestamp(unsigned a, unsigned b) { secs = a; i = b; dassert( (int)secs >= 0 ); } - OpTime( const OpTime& other ) { + Timestamp( const Timestamp& other ) { secs = other.secs; i = other.i; dassert( (int)secs >= 0 ); } - OpTime() { + Timestamp() { secs = 0; i = 0; } - // Maximum OpTime value. - static OpTime max(); + // Maximum Timestamp value. + static Timestamp max(); - unsigned long long asDate() const { + unsigned long long asULL() const { return reinterpret_cast<const unsigned long long*>(&i)[0]; } long long asLL() const { @@ -87,48 +79,35 @@ namespace mongo { bool isNull() const { return secs == 0; } - std::string toStringLong() const { - std::stringstream ss; - ss << time_t_to_String_short(secs) << ' '; - ss << std::hex << secs << ':' << i; - return ss.str(); - } + std::string toStringLong() const; - std::string toStringPretty() const { - std::stringstream ss; - ss << time_t_to_String_short(secs) << ':' << std::hex << i; - return ss.str(); - } + std::string toStringPretty() const; - std::string toString() const { - std::stringstream ss; - ss << std::hex << secs << ':' << i; - return ss.str(); - } + std::string toString() const; - bool operator==(const OpTime& r) const { + bool operator==(const Timestamp& r) const { return i == r.i && secs == r.secs; } - bool operator!=(const OpTime& r) const { + bool operator!=(const Timestamp& r) const { return !(*this == r); } - bool operator<(const OpTime& r) const { + bool operator<(const Timestamp& r) const { if ( secs != r.secs ) return secs < r.secs; return i < r.i; } - bool operator<=(const OpTime& r) const { + bool operator<=(const Timestamp& r) const { return *this < r || *this == r; } - bool operator>(const OpTime& r) const { + bool operator>(const Timestamp& r) const { return !(*this <= r); } - bool operator>=(const OpTime& r) const { + bool operator>=(const Timestamp& r) const { return !(*this < r); } - // Append the BSON representation of this OpTime to the given BufBuilder with the given - // name. This lives here because OpTime manages its own serialization format. + // 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; }; diff --git a/src/mongo/bson/util/bson_extract.cpp b/src/mongo/bson/util/bson_extract.cpp index 5247c1fea39..ef8f5110568 100644 --- a/src/mongo/bson/util/bson_extract.cpp +++ b/src/mongo/bson/util/bson_extract.cpp @@ -106,14 +106,14 @@ namespace mongo { return Status::OK(); } - Status bsonExtractOpTimeField(const BSONObj& object, + Status bsonExtractTimestampField(const BSONObj& object, StringData fieldName, - OpTime* out) { + Timestamp* out) { BSONElement element; - Status status = bsonExtractTypedField(object, fieldName, Timestamp, &element); + Status status = bsonExtractTypedField(object, fieldName, bsonTimestamp, &element); if (!status.isOK()) return status; - *out = element._opTime(); + *out = element.timestamp(); return Status::OK(); } diff --git a/src/mongo/bson/util/bson_extract.h b/src/mongo/bson/util/bson_extract.h index 7d4217a66bf..4558e18b22d 100644 --- a/src/mongo/bson/util/bson_extract.h +++ b/src/mongo/bson/util/bson_extract.h @@ -39,7 +39,7 @@ namespace mongo { class BSONObj; class BSONElement; class OID; - class OpTime; + class Timestamp; /** * Finds an element named "fieldName" in "object". @@ -103,16 +103,16 @@ namespace mongo { std::string* out); /** - * Finds an OpTime-typed element named "fieldName" in "object" and stores its value in "out". + * Finds an Timestamp-typed element named "fieldName" in "object" and stores its value in "out". * - * Returns Status::OK() and sets *out to the found element's OpTime value on success. Returns + * Returns Status::OK() and sets *out to the found element's Timestamp value on success. Returns * ErrorCodes::NoSuchKey if there are no matches for "fieldName", and ErrorCodes::TypeMismatch - * if the type of the matching element is not OpTime. For return values other than + * if the type of the matching element is not Timestamp. For return values other than * Status::OK(), the resulting value of "*out" is undefined. */ - Status bsonExtractOpTimeField(const BSONObj& object, - StringData fieldName, - OpTime* out); + Status bsonExtractTimestampField(const BSONObj& object, + StringData fieldName, + Timestamp* out); /** * Finds an OID-typed element named "fieldName" in "object" and stores its value in "out". |