blob_file_addition.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. #include "db/blob/blob_file_addition.h"
  6. #include <ostream>
  7. #include <sstream>
  8. #include "logging/event_logger.h"
  9. #include "rocksdb/slice.h"
  10. #include "rocksdb/status.h"
  11. #include "test_util/sync_point.h"
  12. #include "util/coding.h"
  13. namespace ROCKSDB_NAMESPACE {
  14. // Tags for custom fields. Note that these get persisted in the manifest,
  15. // so existing tags should not be modified.
  16. enum BlobFileAddition::CustomFieldTags : uint32_t {
  17. kEndMarker,
  18. // Add forward compatible fields here
  19. /////////////////////////////////////////////////////////////////////
  20. kForwardIncompatibleMask = 1 << 6,
  21. // Add forward incompatible fields here
  22. };
  23. void BlobFileAddition::EncodeTo(std::string* output) const {
  24. PutVarint64(output, blob_file_number_);
  25. PutVarint64(output, total_blob_count_);
  26. PutVarint64(output, total_blob_bytes_);
  27. PutLengthPrefixedSlice(output, checksum_method_);
  28. PutLengthPrefixedSlice(output, checksum_value_);
  29. // Encode any custom fields here. The format to use is a Varint32 tag (see
  30. // CustomFieldTags above) followed by a length prefixed slice. Unknown custom
  31. // fields will be ignored during decoding unless they're in the forward
  32. // incompatible range.
  33. TEST_SYNC_POINT_CALLBACK("BlobFileAddition::EncodeTo::CustomFields", output);
  34. PutVarint32(output, kEndMarker);
  35. }
  36. Status BlobFileAddition::DecodeFrom(Slice* input) {
  37. constexpr char class_name[] = "BlobFileAddition";
  38. if (!GetVarint64(input, &blob_file_number_)) {
  39. return Status::Corruption(class_name, "Error decoding blob file number");
  40. }
  41. if (!GetVarint64(input, &total_blob_count_)) {
  42. return Status::Corruption(class_name, "Error decoding total blob count");
  43. }
  44. if (!GetVarint64(input, &total_blob_bytes_)) {
  45. return Status::Corruption(class_name, "Error decoding total blob bytes");
  46. }
  47. Slice checksum_method;
  48. if (!GetLengthPrefixedSlice(input, &checksum_method)) {
  49. return Status::Corruption(class_name, "Error decoding checksum method");
  50. }
  51. checksum_method_ = checksum_method.ToString();
  52. Slice checksum_value;
  53. if (!GetLengthPrefixedSlice(input, &checksum_value)) {
  54. return Status::Corruption(class_name, "Error decoding checksum value");
  55. }
  56. checksum_value_ = checksum_value.ToString();
  57. while (true) {
  58. uint32_t custom_field_tag = 0;
  59. if (!GetVarint32(input, &custom_field_tag)) {
  60. return Status::Corruption(class_name, "Error decoding custom field tag");
  61. }
  62. if (custom_field_tag == kEndMarker) {
  63. break;
  64. }
  65. if (custom_field_tag & kForwardIncompatibleMask) {
  66. return Status::Corruption(
  67. class_name, "Forward incompatible custom field encountered");
  68. }
  69. Slice custom_field_value;
  70. if (!GetLengthPrefixedSlice(input, &custom_field_value)) {
  71. return Status::Corruption(class_name,
  72. "Error decoding custom field value");
  73. }
  74. }
  75. return Status::OK();
  76. }
  77. std::string BlobFileAddition::DebugString() const {
  78. std::ostringstream oss;
  79. oss << *this;
  80. return oss.str();
  81. }
  82. std::string BlobFileAddition::DebugJSON() const {
  83. JSONWriter jw;
  84. jw << *this;
  85. jw.EndObject();
  86. return jw.Get();
  87. }
  88. bool operator==(const BlobFileAddition& lhs, const BlobFileAddition& rhs) {
  89. return lhs.GetBlobFileNumber() == rhs.GetBlobFileNumber() &&
  90. lhs.GetTotalBlobCount() == rhs.GetTotalBlobCount() &&
  91. lhs.GetTotalBlobBytes() == rhs.GetTotalBlobBytes() &&
  92. lhs.GetChecksumMethod() == rhs.GetChecksumMethod() &&
  93. lhs.GetChecksumValue() == rhs.GetChecksumValue();
  94. }
  95. bool operator!=(const BlobFileAddition& lhs, const BlobFileAddition& rhs) {
  96. return !(lhs == rhs);
  97. }
  98. std::ostream& operator<<(std::ostream& os,
  99. const BlobFileAddition& blob_file_addition) {
  100. os << "blob_file_number: " << blob_file_addition.GetBlobFileNumber()
  101. << " total_blob_count: " << blob_file_addition.GetTotalBlobCount()
  102. << " total_blob_bytes: " << blob_file_addition.GetTotalBlobBytes()
  103. << " checksum_method: " << blob_file_addition.GetChecksumMethod()
  104. << " checksum_value: "
  105. << Slice(blob_file_addition.GetChecksumValue()).ToString(/* hex */ true);
  106. return os;
  107. }
  108. JSONWriter& operator<<(JSONWriter& jw,
  109. const BlobFileAddition& blob_file_addition) {
  110. jw << "BlobFileNumber" << blob_file_addition.GetBlobFileNumber()
  111. << "TotalBlobCount" << blob_file_addition.GetTotalBlobCount()
  112. << "TotalBlobBytes" << blob_file_addition.GetTotalBlobBytes()
  113. << "ChecksumMethod" << blob_file_addition.GetChecksumMethod()
  114. << "ChecksumValue"
  115. << Slice(blob_file_addition.GetChecksumValue()).ToString(/* hex */ true);
  116. return jw;
  117. }
  118. } // namespace ROCKSDB_NAMESPACE