blob_garbage_meter.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. #include <cassert>
  7. #include <cstdint>
  8. #include <unordered_map>
  9. #include "db/blob/blob_constants.h"
  10. #include "rocksdb/rocksdb_namespace.h"
  11. #include "rocksdb/status.h"
  12. namespace ROCKSDB_NAMESPACE {
  13. class Slice;
  14. // A class that can be used to compute the amount of additional garbage
  15. // generated by a compaction. It parses the keys and blob references in the
  16. // input and output of a compaction, and aggregates the "inflow" and "outflow"
  17. // on a per-blob file basis. The amount of additional garbage for any given blob
  18. // file can then be computed by subtracting the outflow from the inflow.
  19. class BlobGarbageMeter {
  20. public:
  21. // A class to store the number and total size of blobs on a per-blob file
  22. // basis.
  23. class BlobStats {
  24. public:
  25. void Add(uint64_t bytes) {
  26. ++count_;
  27. bytes_ += bytes;
  28. }
  29. void Add(uint64_t count, uint64_t bytes) {
  30. count_ += count;
  31. bytes_ += bytes;
  32. }
  33. uint64_t GetCount() const { return count_; }
  34. uint64_t GetBytes() const { return bytes_; }
  35. private:
  36. uint64_t count_ = 0;
  37. uint64_t bytes_ = 0;
  38. };
  39. // A class to keep track of the "inflow" and the "outflow" and to compute the
  40. // amount of additional garbage for a given blob file.
  41. class BlobInOutFlow {
  42. public:
  43. void AddInFlow(uint64_t bytes) {
  44. in_flow_.Add(bytes);
  45. assert(IsValid());
  46. }
  47. void AddOutFlow(uint64_t bytes) {
  48. out_flow_.Add(bytes);
  49. assert(IsValid());
  50. }
  51. const BlobStats& GetInFlow() const { return in_flow_; }
  52. const BlobStats& GetOutFlow() const { return out_flow_; }
  53. bool IsValid() const {
  54. return in_flow_.GetCount() >= out_flow_.GetCount() &&
  55. in_flow_.GetBytes() >= out_flow_.GetBytes();
  56. }
  57. bool HasGarbage() const {
  58. assert(IsValid());
  59. return in_flow_.GetCount() > out_flow_.GetCount();
  60. }
  61. uint64_t GetGarbageCount() const {
  62. assert(IsValid());
  63. assert(HasGarbage());
  64. return in_flow_.GetCount() - out_flow_.GetCount();
  65. }
  66. uint64_t GetGarbageBytes() const {
  67. assert(IsValid());
  68. assert(HasGarbage());
  69. return in_flow_.GetBytes() - out_flow_.GetBytes();
  70. }
  71. private:
  72. BlobStats in_flow_;
  73. BlobStats out_flow_;
  74. };
  75. Status ProcessInFlow(const Slice& key, const Slice& value);
  76. Status ProcessOutFlow(const Slice& key, const Slice& value);
  77. const std::unordered_map<uint64_t, BlobInOutFlow>& flows() const {
  78. return flows_;
  79. }
  80. private:
  81. static Status Parse(const Slice& key, const Slice& value,
  82. uint64_t* blob_file_number, uint64_t* bytes);
  83. std::unordered_map<uint64_t, BlobInOutFlow> flows_;
  84. };
  85. } // namespace ROCKSDB_NAMESPACE