]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | // This source code is licensed under both the GPLv2 (found in the | |
3 | // COPYING file in the root directory) and Apache 2.0 License | |
4 | // (found in the LICENSE.Apache file in the root directory). | |
5 | #pragma once | |
6 | #ifndef ROCKSDB_LITE | |
7 | ||
f67539c2 TL |
8 | #include <sstream> |
9 | #include <string> | |
10 | ||
11fdf7f2 TL |
11 | #include "rocksdb/options.h" |
12 | #include "util/coding.h" | |
13 | #include "util/string_util.h" | |
14 | ||
f67539c2 | 15 | namespace ROCKSDB_NAMESPACE { |
11fdf7f2 TL |
16 | |
17 | // BlobIndex is a pointer to the blob and metadata of the blob. The index is | |
18 | // stored in base DB as ValueType::kTypeBlobIndex. | |
19 | // There are three types of blob index: | |
20 | // | |
21 | // kInlinedTTL: | |
22 | // +------+------------+---------------+ | |
23 | // | type | expiration | value | | |
24 | // +------+------------+---------------+ | |
25 | // | char | varint64 | variable size | | |
26 | // +------+------------+---------------+ | |
27 | // | |
28 | // kBlob: | |
29 | // +------+-------------+----------+----------+-------------+ | |
30 | // | type | file number | offset | size | compression | | |
31 | // +------+-------------+----------+----------+-------------+ | |
32 | // | char | varint64 | varint64 | varint64 | char | | |
33 | // +------+-------------+----------+----------+-------------+ | |
34 | // | |
35 | // kBlobTTL: | |
36 | // +------+------------+-------------+----------+----------+-------------+ | |
37 | // | type | expiration | file number | offset | size | compression | | |
38 | // +------+------------+-------------+----------+----------+-------------+ | |
39 | // | char | varint64 | varint64 | varint64 | varint64 | char | | |
40 | // +------+------------+-------------+----------+----------+-------------+ | |
41 | // | |
42 | // There isn't a kInlined (without TTL) type since we can store it as a plain | |
43 | // value (i.e. ValueType::kTypeValue). | |
44 | class BlobIndex { | |
45 | public: | |
46 | enum class Type : unsigned char { | |
47 | kInlinedTTL = 0, | |
48 | kBlob = 1, | |
49 | kBlobTTL = 2, | |
50 | kUnknown = 3, | |
51 | }; | |
52 | ||
53 | BlobIndex() : type_(Type::kUnknown) {} | |
54 | ||
55 | bool IsInlined() const { return type_ == Type::kInlinedTTL; } | |
56 | ||
57 | bool HasTTL() const { | |
58 | return type_ == Type::kInlinedTTL || type_ == Type::kBlobTTL; | |
59 | } | |
60 | ||
61 | uint64_t expiration() const { | |
62 | assert(HasTTL()); | |
63 | return expiration_; | |
64 | } | |
65 | ||
66 | const Slice& value() const { | |
67 | assert(IsInlined()); | |
68 | return value_; | |
69 | } | |
70 | ||
71 | uint64_t file_number() const { | |
72 | assert(!IsInlined()); | |
73 | return file_number_; | |
74 | } | |
75 | ||
76 | uint64_t offset() const { | |
77 | assert(!IsInlined()); | |
78 | return offset_; | |
79 | } | |
80 | ||
81 | uint64_t size() const { | |
82 | assert(!IsInlined()); | |
83 | return size_; | |
84 | } | |
85 | ||
86 | Status DecodeFrom(Slice slice) { | |
87 | static const std::string kErrorMessage = "Error while decoding blob index"; | |
88 | assert(slice.size() > 0); | |
89 | type_ = static_cast<Type>(*slice.data()); | |
90 | if (type_ >= Type::kUnknown) { | |
91 | return Status::Corruption( | |
92 | kErrorMessage, | |
93 | "Unknown blob index type: " + ToString(static_cast<char>(type_))); | |
94 | } | |
95 | slice = Slice(slice.data() + 1, slice.size() - 1); | |
96 | if (HasTTL()) { | |
97 | if (!GetVarint64(&slice, &expiration_)) { | |
98 | return Status::Corruption(kErrorMessage, "Corrupted expiration"); | |
99 | } | |
100 | } | |
101 | if (IsInlined()) { | |
102 | value_ = slice; | |
103 | } else { | |
104 | if (GetVarint64(&slice, &file_number_) && GetVarint64(&slice, &offset_) && | |
105 | GetVarint64(&slice, &size_) && slice.size() == 1) { | |
106 | compression_ = static_cast<CompressionType>(*slice.data()); | |
107 | } else { | |
108 | return Status::Corruption(kErrorMessage, "Corrupted blob offset"); | |
109 | } | |
110 | } | |
111 | return Status::OK(); | |
112 | } | |
113 | ||
f67539c2 TL |
114 | std::string DebugString(bool output_hex) const { |
115 | std::ostringstream oss; | |
116 | ||
117 | if (IsInlined()) { | |
118 | oss << "[inlined blob] value:" << value_.ToString(output_hex); | |
119 | } else { | |
120 | oss << "[blob ref] file:" << file_number_ << " offset:" << offset_ | |
121 | << " size:" << size_; | |
122 | } | |
123 | ||
124 | if (HasTTL()) { | |
125 | oss << " exp:" << expiration_; | |
126 | } | |
127 | ||
128 | return oss.str(); | |
129 | } | |
130 | ||
11fdf7f2 TL |
131 | static void EncodeInlinedTTL(std::string* dst, uint64_t expiration, |
132 | const Slice& value) { | |
133 | assert(dst != nullptr); | |
134 | dst->clear(); | |
135 | dst->reserve(1 + kMaxVarint64Length + value.size()); | |
136 | dst->push_back(static_cast<char>(Type::kInlinedTTL)); | |
137 | PutVarint64(dst, expiration); | |
138 | dst->append(value.data(), value.size()); | |
139 | } | |
140 | ||
141 | static void EncodeBlob(std::string* dst, uint64_t file_number, | |
142 | uint64_t offset, uint64_t size, | |
143 | CompressionType compression) { | |
144 | assert(dst != nullptr); | |
145 | dst->clear(); | |
146 | dst->reserve(kMaxVarint64Length * 3 + 2); | |
147 | dst->push_back(static_cast<char>(Type::kBlob)); | |
148 | PutVarint64(dst, file_number); | |
149 | PutVarint64(dst, offset); | |
150 | PutVarint64(dst, size); | |
151 | dst->push_back(static_cast<char>(compression)); | |
152 | } | |
153 | ||
154 | static void EncodeBlobTTL(std::string* dst, uint64_t expiration, | |
155 | uint64_t file_number, uint64_t offset, | |
156 | uint64_t size, CompressionType compression) { | |
157 | assert(dst != nullptr); | |
158 | dst->clear(); | |
159 | dst->reserve(kMaxVarint64Length * 4 + 2); | |
160 | dst->push_back(static_cast<char>(Type::kBlobTTL)); | |
161 | PutVarint64(dst, expiration); | |
162 | PutVarint64(dst, file_number); | |
163 | PutVarint64(dst, offset); | |
164 | PutVarint64(dst, size); | |
165 | dst->push_back(static_cast<char>(compression)); | |
166 | } | |
167 | ||
168 | private: | |
169 | Type type_ = Type::kUnknown; | |
170 | uint64_t expiration_ = 0; | |
171 | Slice value_; | |
172 | uint64_t file_number_ = 0; | |
173 | uint64_t offset_ = 0; | |
174 | uint64_t size_ = 0; | |
175 | CompressionType compression_ = kNoCompression; | |
176 | }; | |
177 | ||
f67539c2 | 178 | } // namespace ROCKSDB_NAMESPACE |
11fdf7f2 | 179 | #endif // ROCKSDB_LITE |