/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 | | // Given a DocDB key stored in RocksDB, validate the DocHybridTime size stored as the |
43 | | // last few bits of the final byte of the key, and ensure that the ValueType byte preceding that |
44 | | // encoded DocHybridTime is ValueType::kHybridTime. |
45 | | CHECKED_STATUS CheckHybridTimeSizeAndValueType( |
46 | | const rocksdb::Slice& key, |
47 | | size_t* ht_byte_size_dest); |
48 | | |
49 | | template <class Buffer> |
50 | 47.4M | void AppendUInt16ToKey(uint16_t val, Buffer* dest) { |
51 | 47.4M | char buf[sizeof(uint16_t)]; |
52 | 47.4M | BigEndian::Store16(buf, val); |
53 | 47.4M | dest->append(buf, sizeof(buf)); |
54 | 47.4M | } |
55 | | |
56 | | template <class Buffer> |
57 | 17.1M | void AppendUInt32ToKey(uint32_t val, Buffer* dest) { |
58 | 17.1M | char buf[sizeof(uint32_t)]; |
59 | 17.1M | BigEndian::Store32(buf, val); |
60 | 17.1M | dest->append(buf, sizeof(buf)); |
61 | 17.1M | } |
62 | | |
63 | | template <class Buffer> |
64 | 2.05k | void AppendUInt64ToKey(uint64_t val, Buffer* dest) { |
65 | 2.05k | char buf[sizeof(uint64_t)]; |
66 | 2.05k | BigEndian::Store64(buf, val); |
67 | 2.05k | dest->append(buf, sizeof(buf)); |
68 | 2.05k | } |
69 | | |
70 | | // Encodes the given string by replacing '\x00' with "\x00\x01" and appends it to the given |
71 | | // destination string. |
72 | | void AppendZeroEncodedStrToKey(const std::string &s, KeyBuffer *dest); |
73 | | |
74 | | // Encodes the given string by replacing '\xff' with "\xff\xfe" and appends it to the given |
75 | | // destination string. |
76 | | void AppendComplementZeroEncodedStrToKey(const std::string &s, KeyBuffer *dest); |
77 | | |
78 | | // Appends two zero characters to the given string. We don't add final end-of-string characters in |
79 | | // this function. |
80 | | void TerminateZeroEncodedKeyStr(KeyBuffer *dest); |
81 | | |
82 | | // Appends two '\0xff' characters to the given string. We don't add final end-of-string characters |
83 | | // in this function. |
84 | | void TerminateComplementZeroEncodedKeyStr(KeyBuffer *dest); |
85 | | |
86 | 39.2M | inline void ZeroEncodeAndAppendStrToKey(const std::string &s, KeyBuffer *dest) { |
87 | 39.2M | AppendZeroEncodedStrToKey(s, dest); |
88 | 39.2M | TerminateZeroEncodedKeyStr(dest); |
89 | 39.2M | } |
90 | | |
91 | 99.5k | inline void ComplementZeroEncodeAndAppendStrToKey(const std::string &s, KeyBuffer* dest) { |
92 | 99.5k | AppendComplementZeroEncodedStrToKey(s, dest); |
93 | 99.5k | TerminateComplementZeroEncodedKeyStr(dest); |
94 | 99.5k | } |
95 | | |
96 | | inline std::string ZeroEncodeStr(const std::string& s) { |
97 | | KeyBuffer result; |
98 | | ZeroEncodeAndAppendStrToKey(s, &result); |
99 | | return result.ToStringBuffer(); |
100 | | } |
101 | | |
102 | | // Reverses the encoding we use for string fields in a RocksDB key where a zero is represented as |
103 | | // \0x00\0x01 and the string is terminated with \x00\x00. |
104 | | // Input/output: |
105 | | // slice - a slice containing an encoded string, optionally terminated by \x00\x00. A prefix of |
106 | | // this slice is consumed. |
107 | | // Output (undefined in case of an error): |
108 | | // result - the resulting decoded string |
109 | | yb::Status DecodeZeroEncodedStr(rocksdb::Slice* slice, std::string* result); |
110 | | |
111 | | // A version of the above function that ensures the encoding is correct and all characters are |
112 | | // consumed. |
113 | | std::string DecodeZeroEncodedStr(std::string encoded_str); |
114 | | |
115 | | // Reverses the encoding for a string that was encoded with ComplementZeroEncodeAndAppendStrToKey. |
116 | | // In this representation the string termination changes from \x00\x00 to |
117 | | // \xFF\xFF. |
118 | | // Input/output: |
119 | | // slice - a slice containing an encoded string, optionally terminated by \xFF\xFF. A prefix of |
120 | | // this slice is consumed. |
121 | | // Output (undefined in case of an error): |
122 | | // result - the resulting decoded string |
123 | | yb::Status DecodeComplementZeroEncodedStr(rocksdb::Slice* slice, std::string* result); |
124 | | |
125 | | // We try to use up to this number of characters when converting raw bytes to strings for debug |
126 | | // purposes. |
127 | | constexpr int kShortDebugStringLength = 40; |
128 | | |
129 | | // Produces a debug-friendly representation of a sequence of bytes that may contain non-printable |
130 | | // characters. |
131 | | // @return A human-readable representation of the given slice, capped at a fixed short length. |
132 | | std::string ToShortDebugStr(rocksdb::Slice slice); |
133 | | |
134 | 0 | inline std::string ToShortDebugStr(const std::string& raw_str) { |
135 | 0 | return ToShortDebugStr(rocksdb::Slice(raw_str)); |
136 | 0 | } |
137 | | |
138 | | Result<DocHybridTime> DecodeInvertedDocHt(Slice key_slice); |
139 | | |
140 | | constexpr size_t kMaxWordsPerEncodedHybridTimeWithValueType = |
141 | | ((kMaxBytesPerEncodedHybridTime + 1) + sizeof(size_t) - 1) / sizeof(size_t); |
142 | | |
143 | | // Puts inverted encoded doc hybrid time specified by input to buffer. |
144 | | // And returns slice to it. |
145 | | using DocHybridTimeWordBuffer = std::array<size_t, kMaxWordsPerEncodedHybridTimeWithValueType>; |
146 | | Slice InvertEncodedDocHT(const Slice& input, DocHybridTimeWordBuffer* buffer); |
147 | | |
148 | | } // namespace docdb |
149 | | } // namespace yb |
150 | | |
151 | | #endif // YB_DOCDB_DOC_KV_UTIL_H_ |