SequoiaDB
 All Classes Namespaces Files Functions Macros Pages
optime.h
1 // optime.h - OpTime class
2 
3 /* Copyright 2009 10gen Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 #include "misc.h"
20 namespace bson {
21 
22  /* replsets use RSOpTime.
23  M/S uses OpTime.
24  But this is useable from both.
25  */
26  typedef unsigned long long ReplTime;
27 
28  /* Operation sequence #. A combination of current second plus an ordinal
29  value.
30  */
31 #pragma pack(4)
32  class OpTime {
33  unsigned i;
34  signed secs;
35  static OpTime last;
36  public:
37  static void setLast(const Date_t &date) {
38  last = OpTime(date);
39  }
40  signed getSecs() const {
41  return secs;
42  }
43  OpTime(Date_t date) {
44  reinterpret_cast<long long&>(*this) = date.millis;
45  }
46  OpTime(ReplTime x) {
47  reinterpret_cast<unsigned long long&>(*this) = x;
48  }
55  OpTime(signed a, unsigned b) {
56  secs = a;
57  i = b;
58  }
59  OpTime() {
60  secs = 0;
61  i = 0;
62  }
63  static OpTime now() {
64  signed t = (signed) time(0);
65  if ( t < last.secs ) {
66  // bool toLog = false;
67  // ONCE toLog = true;
68  // RARELY toLog = true;
69  // if ( last.i & 0x80000000 )
70  // toLog = true;
71  // if ( toLog )
72  // log() << "clock skew detected prev: " << last.secs
73  // << " now: " << t << " trying to handle..." << endl;
74  // if ( last.i & 0x80000000 ) {
75  // log() << "ERROR Large clock skew detected, shutting down"
76  // << endl;
77  // throw ClockSkewException();
78  // }
79  t = last.secs;
80  }
81  if ( last.secs == t ) {
82  last.i++;
83  return last;
84  }
85  last = OpTime(t, 1);
86  return last;
87  }
88 
89  /* We store OpTime's in the database as BSON Date datatype -- we needed
90  some sort of 64 bit "container" for these values. While these are
91  not really "Dates", that seems a better choice for now than say,
92  Number, which is floating point. Note the BinData type is perhaps
93  the cleanest choice, lacking a true unsigned64 datatype, but BinData
94  has 5 bytes of overhead.
95  */
96  long long asDate() const {
97  long long time = 0 ;
98  memcpy( (char *)&time, &i, sizeof( unsigned ) ) ;
99  memcpy( (char *)&time + sizeof( unsigned ), &secs,
100  sizeof( signed ) ) ;
101  return time ;
102  //return reinterpret_cast<const unsigned long long*>(&i)[0];
103  }
104  long long asLL() const {
105  long long time = 0 ;
106  memcpy( (char *)&time, &i, sizeof( unsigned ) ) ;
107  memcpy( (char *)&time + sizeof( unsigned ), &secs,
108  sizeof( signed ) ) ;
109  return time ;
110  //return reinterpret_cast<const long long*>(&i)[0];
111  }
112 
113  bool isNull() const { return secs == 0; }
114 
115  string toStringLong() const {
116  char buf[64];
117  time_t_to_String(secs, buf);
118  stringstream ss;
119  ss << time_t_to_String_short(secs) << ' ';
120  ss << hex << secs << ':' << i;
121  return ss.str();
122  }
123 
124  string toStringPretty() const {
125  stringstream ss;
126  ss << time_t_to_String_short(secs) << ':' << hex << i;
127  return ss.str();
128  }
129 
130  string toString() const {
131  stringstream ss;
132  ss << hex << secs << ':' << i;
133  return ss.str();
134  }
135 
136  bool operator==(const OpTime& r) const {
137  return i == r.i && secs == r.secs;
138  }
139  bool operator!=(const OpTime& r) const {
140  return !(*this == r);
141  }
142  bool operator<(const OpTime& r) const {
143  int l_secs = ( int ) secs ;
144  int r_secs = ( int ) r.secs ;
145  if ( l_secs != r_secs )
146  return l_secs < r_secs;
147  return i < r.i;
148  }
149  bool operator<=(const OpTime& r) const {
150  return *this < r || *this == r;
151  }
152  bool operator>(const OpTime& r) const {
153  return !(*this <= r);
154  }
155  bool operator>=(const OpTime& r) const {
156  return !(*this < r);
157  }
158  };
159 #pragma pack()
160 
161 } // namespace mongo