]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db/blob/blob_index.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / db / blob / blob_index.h
CommitLineData
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
11fdf7f2 6
f67539c2
TL
7#include <sstream>
8#include <string>
9
20effc67 10#include "rocksdb/compression_type.h"
11fdf7f2 11#include "util/coding.h"
20effc67 12#include "util/compression.h"
11fdf7f2
TL
13#include "util/string_util.h"
14
f67539c2 15namespace 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).
44class 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
1e59de90
TL
55 BlobIndex(const BlobIndex&) = default;
56 BlobIndex& operator=(const BlobIndex&) = default;
57
11fdf7f2
TL
58 bool IsInlined() const { return type_ == Type::kInlinedTTL; }
59
60 bool HasTTL() const {
61 return type_ == Type::kInlinedTTL || type_ == Type::kBlobTTL;
62 }
63
64 uint64_t expiration() const {
65 assert(HasTTL());
66 return expiration_;
67 }
68
69 const Slice& value() const {
70 assert(IsInlined());
71 return value_;
72 }
73
74 uint64_t file_number() const {
75 assert(!IsInlined());
76 return file_number_;
77 }
78
79 uint64_t offset() const {
80 assert(!IsInlined());
81 return offset_;
82 }
83
84 uint64_t size() const {
85 assert(!IsInlined());
86 return size_;
87 }
88
20effc67
TL
89 CompressionType compression() const {
90 assert(!IsInlined());
91 return compression_;
92 }
93
11fdf7f2 94 Status DecodeFrom(Slice slice) {
1e59de90 95 const char* kErrorMessage = "Error while decoding blob index";
11fdf7f2
TL
96 assert(slice.size() > 0);
97 type_ = static_cast<Type>(*slice.data());
98 if (type_ >= Type::kUnknown) {
1e59de90
TL
99 return Status::Corruption(kErrorMessage,
100 "Unknown blob index type: " +
101 std::to_string(static_cast<char>(type_)));
11fdf7f2
TL
102 }
103 slice = Slice(slice.data() + 1, slice.size() - 1);
104 if (HasTTL()) {
105 if (!GetVarint64(&slice, &expiration_)) {
106 return Status::Corruption(kErrorMessage, "Corrupted expiration");
107 }
108 }
109 if (IsInlined()) {
110 value_ = slice;
111 } else {
112 if (GetVarint64(&slice, &file_number_) && GetVarint64(&slice, &offset_) &&
113 GetVarint64(&slice, &size_) && slice.size() == 1) {
114 compression_ = static_cast<CompressionType>(*slice.data());
115 } else {
116 return Status::Corruption(kErrorMessage, "Corrupted blob offset");
117 }
118 }
119 return Status::OK();
120 }
121
f67539c2
TL
122 std::string DebugString(bool output_hex) const {
123 std::ostringstream oss;
124
125 if (IsInlined()) {
126 oss << "[inlined blob] value:" << value_.ToString(output_hex);
127 } else {
128 oss << "[blob ref] file:" << file_number_ << " offset:" << offset_
20effc67
TL
129 << " size:" << size_
130 << " compression: " << CompressionTypeToString(compression_);
f67539c2
TL
131 }
132
133 if (HasTTL()) {
134 oss << " exp:" << expiration_;
135 }
136
137 return oss.str();
138 }
139
11fdf7f2
TL
140 static void EncodeInlinedTTL(std::string* dst, uint64_t expiration,
141 const Slice& value) {
142 assert(dst != nullptr);
143 dst->clear();
144 dst->reserve(1 + kMaxVarint64Length + value.size());
145 dst->push_back(static_cast<char>(Type::kInlinedTTL));
146 PutVarint64(dst, expiration);
147 dst->append(value.data(), value.size());
148 }
149
150 static void EncodeBlob(std::string* dst, uint64_t file_number,
151 uint64_t offset, uint64_t size,
152 CompressionType compression) {
153 assert(dst != nullptr);
154 dst->clear();
155 dst->reserve(kMaxVarint64Length * 3 + 2);
156 dst->push_back(static_cast<char>(Type::kBlob));
157 PutVarint64(dst, file_number);
158 PutVarint64(dst, offset);
159 PutVarint64(dst, size);
160 dst->push_back(static_cast<char>(compression));
161 }
162
163 static void EncodeBlobTTL(std::string* dst, uint64_t expiration,
164 uint64_t file_number, uint64_t offset,
165 uint64_t size, CompressionType compression) {
166 assert(dst != nullptr);
167 dst->clear();
168 dst->reserve(kMaxVarint64Length * 4 + 2);
169 dst->push_back(static_cast<char>(Type::kBlobTTL));
170 PutVarint64(dst, expiration);
171 PutVarint64(dst, file_number);
172 PutVarint64(dst, offset);
173 PutVarint64(dst, size);
174 dst->push_back(static_cast<char>(compression));
175 }
176
177 private:
178 Type type_ = Type::kUnknown;
179 uint64_t expiration_ = 0;
180 Slice value_;
181 uint64_t file_number_ = 0;
182 uint64_t offset_ = 0;
183 uint64_t size_ = 0;
184 CompressionType compression_ = kNoCompression;
185};
186
f67539c2 187} // namespace ROCKSDB_NAMESPACE