YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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