]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db/blob_index.h
buildsys: switch source download to quincy
[ceph.git] / ceph / src / rocksdb / db / 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
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 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
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