]>
git.proxmox.com Git - ceph.git/blob - 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).
8 #include "utilities/blob_db/blob_log_format.h"
10 #include "util/coding.h"
11 #include "util/crc32c.h"
13 namespace ROCKSDB_NAMESPACE
{
16 void BlobLogHeader::EncodeTo(std::string
* dst
) {
17 assert(dst
!= nullptr);
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
);
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");
37 uint32_t magic_number
;
39 if (!GetFixed32(&src
, &magic_number
) || !GetFixed32(&src
, &version
) ||
40 !GetFixed32(&src
, &column_family_id
)) {
41 return Status::Corruption(
43 "Error decoding magic number, version and column family id");
45 if (magic_number
!= kMagicNumber
) {
46 return Status::Corruption(kErrorMessage
, "Magic number mismatch");
48 if (version
!= kVersion1
) {
49 return Status::Corruption(kErrorMessage
, "Unknown header version");
51 flags
= src
.data()[0];
52 compression
= static_cast<CompressionType
>(src
.data()[1]);
53 has_ttl
= (flags
& 1) == 1;
55 if (!GetFixed64(&src
, &expiration_range
.first
) ||
56 !GetFixed64(&src
, &expiration_range
.second
)) {
57 return Status::Corruption(kErrorMessage
, "Error decoding expiration range");
62 void BlobLogFooter::EncodeTo(std::string
* dst
) {
63 assert(dst
!= nullptr);
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
);
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");
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");
91 if (magic_number
!= kMagicNumber
) {
92 return Status::Corruption(kErrorMessage
, "Magic number mismatch");
95 return Status::Corruption(kErrorMessage
, "CRC mismatch");
100 void BlobLogRecord::EncodeHeaderTo(std::string
* dst
) {
101 assert(dst
!= nullptr);
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
);
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");
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");
130 if (src_crc
!= header_crc
) {
131 return Status::Corruption(kErrorMessage
, "Header CRC mismatch");
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");
147 } // namespace blob_db
148 } // namespace ROCKSDB_NAMESPACE
149 #endif // ROCKSDB_LITE