/Users/deen/code/yugabyte-db/src/yb/docdb/doc_kv_util.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 | | // Utilities for encoding and decoding key/value pairs that are used in the DocDB code. |
15 | | |
16 | | #ifndef YB_DOCDB_DOC_KV_UTIL_H_ |
17 | | #define YB_DOCDB_DOC_KV_UTIL_H_ |
18 | | |
19 | | #include <string> |
20 | | |
21 | | #include "yb/common/doc_hybrid_time.h" |
22 | | #include "yb/common/hybrid_time.h" |
23 | | |
24 | | #include "yb/gutil/endian.h" |
25 | | |
26 | | #include "yb/util/status_fwd.h" |
27 | | #include "yb/util/kv_util.h" |
28 | | #include "yb/util/monotime.h" |
29 | | #include "yb/util/slice.h" |
30 | | |
31 | | namespace yb { |
32 | | namespace docdb { |
33 | | |
34 | | constexpr int kEncodedKeyStrTerminatorSize = 2; |
35 | | |
36 | | // Checks whether the given RocksDB key belongs to a document identified by the given encoded |
37 | | // document key (a key that has already had zero characters escaped). This is done simply by |
38 | | // checking that the key starts with the encoded document key followed by two zero characters. |
39 | | // This is only used in unit tests as of 08/02/2016. |
40 | | bool KeyBelongsToDocKeyInTest(const rocksdb::Slice &key, const std::string &encoded_doc_key); |
41 | | |
42 | | // Decode a DocHybridTime stored in the end of the given slice. |
43 | | CHECKED_STATUS DecodeHybridTimeFromEndOfKey(const rocksdb::Slice &key, DocHybridTime *dest); |
44 | | |
45 | | // Given a DocDB key stored in RocksDB, validate the DocHybridTime size stored as the |
46 | | // last few bits of the final byte of the key, and ensure that the ValueType byte preceding that |
47 | | // encoded DocHybridTime is ValueType::kHybridTime. |
48 | | CHECKED_STATUS CheckHybridTimeSizeAndValueType( |
49 | | const rocksdb::Slice& key, |
50 | | size_t* ht_byte_size_dest); |
51 | | |
52 | | // Consumes hybrid time from the given slice, decreasing the slice size by the hybrid time size. |
53 | | // Hybrid time is stored in a "key-appropriate" format (bits inverted for reverse sorting). |
54 | | // @param slice The slice holding RocksDB key bytes. |
55 | | // @param hybrid_time Where to store the hybrid time. Undefined in case of failure. |
56 | | yb::Status ConsumeHybridTimeFromKey(rocksdb::Slice* slice, DocHybridTime* hybrid_time); |
57 | | |
58 | | template <class Buffer> |
59 | 21.6M | void AppendUInt16ToKey(uint16_t val, Buffer* dest) { |
60 | 21.6M | char buf[sizeof(uint16_t)]; |
61 | 21.6M | BigEndian::Store16(buf, val); |
62 | 21.6M | dest->append(buf, sizeof(buf)); |
63 | 21.6M | } |
64 | | |
65 | | template <class Buffer> |
66 | 4.20M | void AppendUInt32ToKey(uint32_t val, Buffer* dest) { |
67 | 4.20M | char buf[sizeof(uint32_t)]; |
68 | 4.20M | BigEndian::Store32(buf, val); |
69 | 4.20M | dest->append(buf, sizeof(buf)); |
70 | 4.20M | } |
71 | | |
72 | | template <class Buffer> |
73 | 0 | void AppendUInt64ToKey(uint64_t val, Buffer* dest) { |
74 | 0 | char buf[sizeof(uint64_t)]; |
75 | 0 | BigEndian::Store64(buf, val); |
76 | 0 | dest->append(buf, sizeof(buf)); |
77 | 0 | } Unexecuted instantiation: _ZN2yb5docdb17AppendUInt64ToKeyINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEvyPT_ Unexecuted instantiation: _ZN2yb5docdb17AppendUInt64ToKeyINS_10ByteBufferILm64EEEEEvyPT_ |
78 | | |
79 | | // Encodes the given string by replacing '\x00' with "\x00\x01" and appends it to the given |
80 | | // destination string. |
81 | | void AppendZeroEncodedStrToKey(const std::string &s, KeyBuffer *dest); |
82 | | |
83 | | // Encodes the given string by replacing '\xff' with "\xff\xfe" and appends it to the given |
84 | | // destination string. |
85 | | void AppendComplementZeroEncodedStrToKey(const std::string &s, KeyBuffer *dest); |
86 | | |
87 | | // Appends two zero characters to the given string. We don't add final end-of-string characters in |
88 | | // this function. |
89 | | void TerminateZeroEncodedKeyStr(KeyBuffer *dest); |
90 | | |
91 | | // Appends two '\0xff' characters to the given string. We don't add final end-of-string characters |
92 | | // in this function. |
93 | | void TerminateComplementZeroEncodedKeyStr(KeyBuffer *dest); |
94 | | |
95 | 13.5M | inline void ZeroEncodeAndAppendStrToKey(const std::string &s, KeyBuffer *dest) { |
96 | 13.5M | AppendZeroEncodedStrToKey(s, dest); |
97 | 13.5M | TerminateZeroEncodedKeyStr(dest); |
98 | 13.5M | } |
99 | | |
100 | 78.5k | inline void ComplementZeroEncodeAndAppendStrToKey(const std::string &s, KeyBuffer* dest) { |
101 | 78.5k | AppendComplementZeroEncodedStrToKey(s, dest); |
102 | 78.5k | TerminateComplementZeroEncodedKeyStr(dest); |
103 | 78.5k | } |
104 | | |
105 | 0 | inline std::string ZeroEncodeStr(const std::string& s) { |
106 | 0 | KeyBuffer result; |
107 | 0 | ZeroEncodeAndAppendStrToKey(s, &result); |
108 | 0 | return result.ToStringBuffer(); |
109 | 0 | } |
110 | | |
111 | | // Reverses the encoding we use for string fields in a RocksDB key where a zero is represented as |
112 | | // \0x00\0x01 and the string is terminated with \x00\x00. |
113 | | // Input/output: |
114 | | // slice - a slice containing an encoded string, optionally terminated by \x00\x00. A prefix of |
115 | | // this slice is consumed. |
116 | | // Output (undefined in case of an error): |
117 | | // result - the resulting decoded string |
118 | | yb::Status DecodeZeroEncodedStr(rocksdb::Slice* slice, std::string* result); |
119 | | |
120 | | // A version of the above function that ensures the encoding is correct and all characters are |
121 | | // consumed. |
122 | | std::string DecodeZeroEncodedStr(std::string encoded_str); |
123 | | |
124 | | // Reverses the encoding for a string that was encoded with ComplementZeroEncodeAndAppendStrToKey. |
125 | | // In this representation the string termination changes from \x00\x00 to |
126 | | // \xFF\xFF. |
127 | | // Input/output: |
128 | | // slice - a slice containing an encoded string, optionally terminated by \xFF\xFF. A prefix of |
129 | | // this slice is consumed. |
130 | | // Output (undefined in case of an error): |
131 | | // result - the resulting decoded string |
132 | | yb::Status DecodeComplementZeroEncodedStr(rocksdb::Slice* slice, std::string* result); |
133 | | |
134 | | // We try to use up to this number of characters when converting raw bytes to strings for debug |
135 | | // purposes. |
136 | | constexpr int kShortDebugStringLength = 40; |
137 | | |
138 | | // Produces a debug-friendly representation of a sequence of bytes that may contain non-printable |
139 | | // characters. |
140 | | // @return A human-readable representation of the given slice, capped at a fixed short length. |
141 | | std::string ToShortDebugStr(rocksdb::Slice slice); |
142 | | |
143 | 0 | inline std::string ToShortDebugStr(const std::string& raw_str) { |
144 | 0 | return ToShortDebugStr(rocksdb::Slice(raw_str)); |
145 | 0 | } |
146 | | |
147 | | Result<DocHybridTime> DecodeInvertedDocHt(Slice key_slice); |
148 | | |
149 | | constexpr size_t kMaxWordsPerEncodedHybridTimeWithValueType = |
150 | | ((kMaxBytesPerEncodedHybridTime + 1) + sizeof(size_t) - 1) / sizeof(size_t); |
151 | | |
152 | | // Puts inverted encoded doc hybrid time specified by input to buffer. |
153 | | // And returns slice to it. |
154 | | using DocHybridTimeWordBuffer = std::array<size_t, kMaxWordsPerEncodedHybridTimeWithValueType>; |
155 | | Slice InvertEncodedDocHT(const Slice& input, DocHybridTimeWordBuffer* buffer); |
156 | | |
157 | | } // namespace docdb |
158 | | } // namespace yb |
159 | | |
160 | | #endif // YB_DOCDB_DOC_KV_UTIL_H_ |