]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/blob_db/blob_log_format.cc
buildsys: switch source download to quincy
[ceph.git] / ceph / src / rocksdb / utilities / blob_db / blob_log_format.cc
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 //
6 #ifndef ROCKSDB_LITE
7
8 #include "utilities/blob_db/blob_log_format.h"
9
10 #include "util/coding.h"
11 #include "util/crc32c.h"
12
13 namespace ROCKSDB_NAMESPACE {
14 namespace blob_db {
15
16 void BlobLogHeader::EncodeTo(std::string* dst) {
17 assert(dst != nullptr);
18 dst->clear();
19 dst->reserve(BlobLogHeader::kSize);
20 PutFixed32(dst, kMagicNumber);
21 PutFixed32(dst, version);
22 PutFixed32(dst, column_family_id);
23 unsigned char flags = (has_ttl ? 1 : 0);
24 dst->push_back(flags);
25 dst->push_back(compression);
26 PutFixed64(dst, expiration_range.first);
27 PutFixed64(dst, expiration_range.second);
28 }
29
30 Status BlobLogHeader::DecodeFrom(Slice src) {
31 static const std::string kErrorMessage =
32 "Error while decoding blob log header";
33 if (src.size() != BlobLogHeader::kSize) {
34 return Status::Corruption(kErrorMessage,
35 "Unexpected blob file header size");
36 }
37 uint32_t magic_number;
38 unsigned char flags;
39 if (!GetFixed32(&src, &magic_number) || !GetFixed32(&src, &version) ||
40 !GetFixed32(&src, &column_family_id)) {
41 return Status::Corruption(
42 kErrorMessage,
43 "Error decoding magic number, version and column family id");
44 }
45 if (magic_number != kMagicNumber) {
46 return Status::Corruption(kErrorMessage, "Magic number mismatch");
47 }
48 if (version != kVersion1) {
49 return Status::Corruption(kErrorMessage, "Unknown header version");
50 }
51 flags = src.data()[0];
52 compression = static_cast<CompressionType>(src.data()[1]);
53 has_ttl = (flags & 1) == 1;
54 src.remove_prefix(2);
55 if (!GetFixed64(&src, &expiration_range.first) ||
56 !GetFixed64(&src, &expiration_range.second)) {
57 return Status::Corruption(kErrorMessage, "Error decoding expiration range");
58 }
59 return Status::OK();
60 }
61
62 void BlobLogFooter::EncodeTo(std::string* dst) {
63 assert(dst != nullptr);
64 dst->clear();
65 dst->reserve(BlobLogFooter::kSize);
66 PutFixed32(dst, kMagicNumber);
67 PutFixed64(dst, blob_count);
68 PutFixed64(dst, expiration_range.first);
69 PutFixed64(dst, expiration_range.second);
70 crc = crc32c::Value(dst->c_str(), dst->size());
71 crc = crc32c::Mask(crc);
72 PutFixed32(dst, crc);
73 }
74
75 Status BlobLogFooter::DecodeFrom(Slice src) {
76 static const std::string kErrorMessage =
77 "Error while decoding blob log footer";
78 if (src.size() != BlobLogFooter::kSize) {
79 return Status::Corruption(kErrorMessage,
80 "Unexpected blob file footer size");
81 }
82 uint32_t src_crc = 0;
83 src_crc = crc32c::Value(src.data(), BlobLogFooter::kSize - sizeof(uint32_t));
84 src_crc = crc32c::Mask(src_crc);
85 uint32_t magic_number = 0;
86 if (!GetFixed32(&src, &magic_number) || !GetFixed64(&src, &blob_count) ||
87 !GetFixed64(&src, &expiration_range.first) ||
88 !GetFixed64(&src, &expiration_range.second) || !GetFixed32(&src, &crc)) {
89 return Status::Corruption(kErrorMessage, "Error decoding content");
90 }
91 if (magic_number != kMagicNumber) {
92 return Status::Corruption(kErrorMessage, "Magic number mismatch");
93 }
94 if (src_crc != crc) {
95 return Status::Corruption(kErrorMessage, "CRC mismatch");
96 }
97 return Status::OK();
98 }
99
100 void BlobLogRecord::EncodeHeaderTo(std::string* dst) {
101 assert(dst != nullptr);
102 dst->clear();
103 dst->reserve(BlobLogRecord::kHeaderSize + key.size() + value.size());
104 PutFixed64(dst, key.size());
105 PutFixed64(dst, value.size());
106 PutFixed64(dst, expiration);
107 header_crc = crc32c::Value(dst->c_str(), dst->size());
108 header_crc = crc32c::Mask(header_crc);
109 PutFixed32(dst, header_crc);
110 blob_crc = crc32c::Value(key.data(), key.size());
111 blob_crc = crc32c::Extend(blob_crc, value.data(), value.size());
112 blob_crc = crc32c::Mask(blob_crc);
113 PutFixed32(dst, blob_crc);
114 }
115
116 Status BlobLogRecord::DecodeHeaderFrom(Slice src) {
117 static const std::string kErrorMessage = "Error while decoding blob record";
118 if (src.size() != BlobLogRecord::kHeaderSize) {
119 return Status::Corruption(kErrorMessage,
120 "Unexpected blob record header size");
121 }
122 uint32_t src_crc = 0;
123 src_crc = crc32c::Value(src.data(), BlobLogRecord::kHeaderSize - 8);
124 src_crc = crc32c::Mask(src_crc);
125 if (!GetFixed64(&src, &key_size) || !GetFixed64(&src, &value_size) ||
126 !GetFixed64(&src, &expiration) || !GetFixed32(&src, &header_crc) ||
127 !GetFixed32(&src, &blob_crc)) {
128 return Status::Corruption(kErrorMessage, "Error decoding content");
129 }
130 if (src_crc != header_crc) {
131 return Status::Corruption(kErrorMessage, "Header CRC mismatch");
132 }
133 return Status::OK();
134 }
135
136 Status BlobLogRecord::CheckBlobCRC() const {
137 uint32_t expected_crc = 0;
138 expected_crc = crc32c::Value(key.data(), key.size());
139 expected_crc = crc32c::Extend(expected_crc, value.data(), value.size());
140 expected_crc = crc32c::Mask(expected_crc);
141 if (expected_crc != blob_crc) {
142 return Status::Corruption("Blob CRC mismatch");
143 }
144 return Status::OK();
145 }
146
147 } // namespace blob_db
148 } // namespace ROCKSDB_NAMESPACE
149 #endif // ROCKSDB_LITE