|
MongoDB
2.0.3
|
00001 // optime.h - OpTime class 00002 00003 /* Copyright 2009 10gen Inc. 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #pragma once 00019 00020 #include "../db/concurrency.h" 00021 00022 namespace mongo { 00023 void exitCleanly( ExitCode code ); 00024 00025 struct ClockSkewException : public DBException { 00026 ClockSkewException() : DBException( "clock skew exception" , 20001 ) {} 00027 }; 00028 00029 /* replsets used to use RSOpTime. 00030 M/S uses OpTime. 00031 But this is useable from both. 00032 */ 00033 typedef unsigned long long ReplTime; 00034 00035 /* Operation sequence #. A combination of current second plus an ordinal value. 00036 */ 00037 #pragma pack(4) 00038 class OpTime { 00039 unsigned i; // ordinal comes first so we can do a single 64 bit compare on little endian 00040 unsigned secs; 00041 static OpTime last; 00042 static OpTime skewed(); 00043 public: 00044 static void setLast(const Date_t &date) { 00045 last = OpTime(date); 00046 } 00047 unsigned getSecs() const { 00048 return secs; 00049 } 00050 unsigned getInc() const { 00051 return i; 00052 } 00053 OpTime(Date_t date) { 00054 reinterpret_cast<unsigned long long&>(*this) = date.millis; 00055 dassert( (int)secs >= 0 ); 00056 } 00057 OpTime(ReplTime x) { 00058 reinterpret_cast<unsigned long long&>(*this) = x; 00059 dassert( (int)secs >= 0 ); 00060 } 00061 OpTime(unsigned a, unsigned b) { 00062 secs = a; 00063 i = b; 00064 dassert( (int)secs >= 0 ); 00065 } 00066 OpTime( const OpTime& other ) { 00067 secs = other.secs; 00068 i = other.i; 00069 dassert( (int)secs >= 0 ); 00070 } 00071 OpTime() { 00072 secs = 0; 00073 i = 0; 00074 } 00075 // it isn't generally safe to not be locked for this. so use now(). some tests use this. 00076 static OpTime now_inlock() { 00077 unsigned t = (unsigned) time(0); 00078 if ( last.secs == t ) { 00079 last.i++; 00080 return last; 00081 } 00082 if ( t < last.secs ) { 00083 return skewed(); // separate function to keep out of the hot code path 00084 } 00085 last = OpTime(t, 1); 00086 return last; 00087 } 00088 static OpTime now() { 00089 DEV dbMutex.assertWriteLocked(); 00090 return now_inlock(); 00091 } 00092 00093 /* We store OpTime's in the database as BSON Date datatype -- we needed some sort of 00094 64 bit "container" for these values. While these are not really "Dates", that seems a 00095 better choice for now than say, Number, which is floating point. Note the BinData type 00096 is perhaps the cleanest choice, lacking a true unsigned64 datatype, but BinData has 5 00097 bytes of overhead. 00098 */ 00099 unsigned long long asDate() const { 00100 return reinterpret_cast<const unsigned long long*>(&i)[0]; 00101 } 00102 long long asLL() const { 00103 return reinterpret_cast<const long long*>(&i)[0]; 00104 } 00105 00106 bool isNull() const { return secs == 0; } 00107 00108 string toStringLong() const { 00109 char buf[64]; 00110 time_t_to_String(secs, buf); 00111 stringstream ss; 00112 ss << time_t_to_String_short(secs) << ' '; 00113 ss << hex << secs << ':' << i; 00114 return ss.str(); 00115 } 00116 00117 string toStringPretty() const { 00118 stringstream ss; 00119 ss << time_t_to_String_short(secs) << ':' << hex << i; 00120 return ss.str(); 00121 } 00122 00123 string toString() const { 00124 stringstream ss; 00125 ss << hex << secs << ':' << i; 00126 return ss.str(); 00127 } 00128 00129 bool operator==(const OpTime& r) const { 00130 return i == r.i && secs == r.secs; 00131 } 00132 bool operator!=(const OpTime& r) const { 00133 return !(*this == r); 00134 } 00135 bool operator<(const OpTime& r) const { 00136 if ( secs != r.secs ) 00137 return secs < r.secs; 00138 return i < r.i; 00139 } 00140 bool operator<=(const OpTime& r) const { 00141 return *this < r || *this == r; 00142 } 00143 bool operator>(const OpTime& r) const { 00144 return !(*this <= r); 00145 } 00146 bool operator>=(const OpTime& r) const { 00147 return !(*this < r); 00148 } 00149 }; 00150 #pragma pack() 00151 00152 } // namespace mongo
1.8.0