/Users/deen/code/yugabyte-db/src/yb/common/doc_hybrid_time.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_COMMON_DOC_HYBRID_TIME_H |
15 | | #define YB_COMMON_DOC_HYBRID_TIME_H |
16 | | |
17 | | #include <string> |
18 | | |
19 | | #include "yb/common/hybrid_time.h" |
20 | | #include "yb/util/compare_util.h" |
21 | | |
22 | | namespace yb { |
23 | | |
24 | | // This is used to disambiguate between different operations that are done inside the same |
25 | | // single-shard transaction with the same HybridTime. |
26 | | using IntraTxnWriteId = uint32_t; |
27 | | |
28 | | constexpr IntraTxnWriteId kMinWriteId = 0; |
29 | | constexpr IntraTxnWriteId kDefaultWriteId = kMinWriteId; |
30 | | constexpr IntraTxnWriteId kMaxWriteId = std::numeric_limits<IntraTxnWriteId>::max(); |
31 | | |
32 | | // An aggressive upper bound on the length of a DocDB-encoded hybrid time with a write id. |
33 | | // This could happen in the degenerate case when all three VarInts in encoded representation of a |
34 | | // DocHybridTime take 10 bytes (the maximum length for a VarInt-encoded int64_t). |
35 | | constexpr size_t kMaxBytesPerEncodedHybridTime = 30; |
36 | | |
37 | | // This is a point in time before any YugaByte clusters are in production that has a round enough |
38 | | // decimal representation when expressed as microseconds since the UNIX epoch. |
39 | | // CHANGING THIS VALUE MAY INVALIDATE PERSISTENT DATA. This corresponds to approximately |
40 | | // Fri, 14 Jul 2017 02:40:00 UTC. We subtract this from the microsecond component of HybridTime |
41 | | // before serializing it as a VarInt to keep the serialized representation small. |
42 | | // |
43 | | // We have chosen not to make this configurable, because it would be very easy to shoot yourself in |
44 | | // the foot by specifying the wrong value of this on one server, which will shift all timestamps |
45 | | // and create unpredictable behavior. Instead, to save space, we can implement domain-specific |
46 | | // compression of blocks in RocksDB to only store physical time deltas within the block relative |
47 | | // to some per-block reference value. |
48 | | constexpr HybridTimeRepr kYugaByteMicrosecondEpoch = 1500000000ul * 1000000; |
49 | | |
50 | | class DocHybridTime { |
51 | | public: |
52 | | static const DocHybridTime kInvalid; |
53 | | static const DocHybridTime kMin; |
54 | | static const DocHybridTime kMax; |
55 | | |
56 | 3.75G | DocHybridTime() {} |
57 | | explicit DocHybridTime(HybridTime hybrid_time) |
58 | 3.85M | : hybrid_time_(hybrid_time) { |
59 | 3.85M | } |
60 | | |
61 | | DocHybridTime(HybridTime hybrid_time, IntraTxnWriteId write_id) |
62 | 405M | : hybrid_time_(hybrid_time), write_id_(write_id) { |
63 | 405M | } |
64 | | |
65 | | DocHybridTime( |
66 | | MicrosTime micros, LogicalTimeComponent logical, IntraTxnWriteId write_id) |
67 | | : hybrid_time_(micros, logical), write_id_(write_id) { |
68 | | } |
69 | | |
70 | 2.98G | HybridTime hybrid_time() const { return hybrid_time_; } |
71 | 1 | IntraTxnWriteId write_id() const { return write_id_; } |
72 | | |
73 | | // Returns pointer to byte after last used byte. |
74 | | char* EncodedInDocDbFormat(char* dest) const; |
75 | | |
76 | | template <class Buffer> |
77 | 11.2M | void AppendEncodedInDocDbFormat(Buffer* dest) const { |
78 | 11.2M | char buf[kMaxBytesPerEncodedHybridTime]; |
79 | 11.2M | dest->append(buf, EncodedInDocDbFormat(buf)); |
80 | 11.2M | } void yb::DocHybridTime::AppendEncodedInDocDbFormat<yb::ByteBuffer<64ul> >(yb::ByteBuffer<64ul>*) const Line | Count | Source | 77 | 11.2M | void AppendEncodedInDocDbFormat(Buffer* dest) const { | 78 | 11.2M | char buf[kMaxBytesPerEncodedHybridTime]; | 79 | 11.2M | dest->append(buf, EncodedInDocDbFormat(buf)); | 80 | 11.2M | } |
void yb::DocHybridTime::AppendEncodedInDocDbFormat<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) const Line | Count | Source | 77 | 1.00k | void AppendEncodedInDocDbFormat(Buffer* dest) const { | 78 | 1.00k | char buf[kMaxBytesPerEncodedHybridTime]; | 79 | 1.00k | dest->append(buf, EncodedInDocDbFormat(buf)); | 80 | 1.00k | } |
|
81 | | |
82 | 62.3M | std::string EncodedInDocDbFormat() const { |
83 | 62.3M | char buf[kMaxBytesPerEncodedHybridTime]; |
84 | 62.3M | return std::string(buf, EncodedInDocDbFormat(buf)); |
85 | 62.3M | } |
86 | | |
87 | | // Decodes a DocHybridTime out of the given slice into this object (modifies the slice). |
88 | | static Result<DocHybridTime> DecodeFrom(Slice *slice); |
89 | | |
90 | | static Result<DocHybridTime> FullyDecodeFrom(const Slice& encoded); |
91 | | static Result<DocHybridTime> DecodeFromEnd(Slice encoded_key_with_ht); |
92 | | |
93 | | // Decodes doc ht from end of slice, and removes corresponding bytes from provided slice. |
94 | | static Result<DocHybridTime> DecodeFromEnd(Slice* encoded_key_with_ht); |
95 | | |
96 | 1.04G | bool operator==(const DocHybridTime& other) const { |
97 | 1.04G | return hybrid_time_ == other.hybrid_time_ && write_id_ == other.write_id_286M ; |
98 | 1.04G | } |
99 | | |
100 | 1.52G | bool operator<(const DocHybridTime& other) const { return CompareTo(other) < 0; } |
101 | 6.07M | bool operator>(const DocHybridTime& other) const { return CompareTo(other) > 0; } |
102 | 6.14M | bool operator<=(const DocHybridTime& other) const { return CompareTo(other) <= 0; } |
103 | 7 | bool operator>=(const DocHybridTime& other) const { return CompareTo(other) >= 0; } |
104 | 111M | bool operator!=(const DocHybridTime& other) const { return !(*this == other); } |
105 | | |
106 | 1.53G | int CompareTo(const DocHybridTime& other) const { |
107 | 1.53G | const auto ht_cmp = hybrid_time_.CompareTo(other.hybrid_time_); |
108 | 1.53G | if (ht_cmp != 0) { |
109 | 822M | return ht_cmp; |
110 | 822M | } |
111 | 711M | return util::CompareUsingLessThan(write_id_, other.write_id_); |
112 | 1.53G | } |
113 | | |
114 | | std::string ToString() const; |
115 | | |
116 | | // Stores the encoded size of the DocHybridTime from the end of the given DocDB-encoded |
117 | | // key in *encoded_ht_size, and verifies that it is within the allowed limits. |
118 | | static CHECKED_STATUS CheckAndGetEncodedSize(const Slice& encoded_key, size_t* encoded_ht_size); |
119 | | |
120 | 255M | bool is_valid() const { return hybrid_time_.is_valid(); } |
121 | | |
122 | | static std::string DebugSliceToString(Slice input); |
123 | | |
124 | | private: |
125 | | HybridTime hybrid_time_; |
126 | | |
127 | | IntraTxnWriteId write_id_ = kDefaultWriteId; |
128 | | |
129 | | // Verifies that the given size of an encoded DocHybridTime (encoded_ht_size) is at least |
130 | | // 1 and is strictly less than the size of the whole key (encoded_key_size). The latter strict |
131 | | // inequality is because we must also leave room for a ValueType::kHybridTime. In practice, |
132 | | // the preceding DocKey will also take a non-zero number of bytes. |
133 | | static CHECKED_STATUS CheckEncodedSize(size_t encoded_ht_size, size_t encoded_key_size); |
134 | | |
135 | | // Retrieves the size of the encode DocHybridTime from the end of the given DocDB-encoded |
136 | | // RocksDB key. There is no error checking here. This returns 0 if the slice is empty. |
137 | | static int GetEncodedSize(const Slice& encoded_key); |
138 | | }; |
139 | | |
140 | 0 | inline std::ostream& operator<<(std::ostream& os, const DocHybridTime& ht) { |
141 | 0 | return os << ht.ToString(); |
142 | 0 | } |
143 | | |
144 | | } // namespace yb |
145 | | |
146 | | #endif // YB_COMMON_DOC_HYBRID_TIME_H |