blob_source.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (c) Meta Platforms, Inc. and affiliates.
  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 <cinttypes>
  7. #include <memory>
  8. #include "cache/cache_key.h"
  9. #include "cache/typed_cache.h"
  10. #include "db/blob/blob_contents.h"
  11. #include "db/blob/blob_file_cache.h"
  12. #include "db/blob/blob_read_request.h"
  13. #include "rocksdb/cache.h"
  14. #include "rocksdb/rocksdb_namespace.h"
  15. #include "table/block_based/cachable_entry.h"
  16. #include "util/autovector.h"
  17. namespace ROCKSDB_NAMESPACE {
  18. struct ImmutableOptions;
  19. struct MutableCFOptions;
  20. class Status;
  21. class FilePrefetchBuffer;
  22. class Slice;
  23. // BlobSource is a class that provides universal access to blobs, regardless of
  24. // whether they are in the blob cache, secondary cache, or (remote) storage.
  25. // Depending on user settings, it always fetch blobs from multi-tier cache and
  26. // storage with minimal cost.
  27. class BlobSource {
  28. public:
  29. // NOTE: db_id, db_session_id, and blob_file_cache are saved by reference or
  30. // pointer.
  31. BlobSource(const ImmutableOptions& immutable_options,
  32. const MutableCFOptions& mutable_cf_options,
  33. const std::string& db_id, const std::string& db_session_id,
  34. BlobFileCache* blob_file_cache);
  35. BlobSource(const BlobSource&) = delete;
  36. BlobSource& operator=(const BlobSource&) = delete;
  37. ~BlobSource();
  38. // Read a blob from the underlying cache or one blob file.
  39. //
  40. // If successful, returns ok and sets "*value" to the newly retrieved
  41. // uncompressed blob. If there was an error while fetching the blob, sets
  42. // "*value" to empty and returns a non-ok status.
  43. //
  44. // Note: For consistency, whether the blob is found in the cache or on disk,
  45. // sets "*bytes_read" to the size of on-disk (possibly compressed) blob
  46. // record.
  47. Status GetBlob(const ReadOptions& read_options, const Slice& user_key,
  48. uint64_t file_number, uint64_t offset, uint64_t file_size,
  49. uint64_t value_size, CompressionType compression_type,
  50. FilePrefetchBuffer* prefetch_buffer, PinnableSlice* value,
  51. uint64_t* bytes_read);
  52. // Read multiple blobs from the underlying cache or blob file(s).
  53. //
  54. // If successful, returns ok and sets "result" in the elements of "blob_reqs"
  55. // to the newly retrieved uncompressed blobs. If there was an error while
  56. // fetching one of blobs, sets its "result" to empty and sets its
  57. // corresponding "status" to a non-ok status.
  58. //
  59. // Note:
  60. // - The main difference between this function and MultiGetBlobFromOneFile is
  61. // that this function can read multiple blobs from multiple blob files.
  62. //
  63. // - For consistency, whether the blob is found in the cache or on disk, sets
  64. // "*bytes_read" to the total size of on-disk (possibly compressed) blob
  65. // records.
  66. void MultiGetBlob(const ReadOptions& read_options,
  67. autovector<BlobFileReadRequests>& blob_reqs,
  68. uint64_t* bytes_read);
  69. // Read multiple blobs from the underlying cache or one blob file.
  70. //
  71. // If successful, returns ok and sets "result" in the elements of "blob_reqs"
  72. // to the newly retrieved uncompressed blobs. If there was an error while
  73. // fetching one of blobs, sets its "result" to empty and sets its
  74. // corresponding "status" to a non-ok status.
  75. //
  76. // Note:
  77. // - The main difference between this function and MultiGetBlob is that this
  78. // function is only used for the case where the demanded blobs are stored in
  79. // one blob file. MultiGetBlob will call this function multiple times if the
  80. // demanded blobs are stored in multiple blob files.
  81. //
  82. // - For consistency, whether the blob is found in the cache or on disk, sets
  83. // "*bytes_read" to the total size of on-disk (possibly compressed) blob
  84. // records.
  85. void MultiGetBlobFromOneFile(const ReadOptions& read_options,
  86. uint64_t file_number, uint64_t file_size,
  87. autovector<BlobReadRequest>& blob_reqs,
  88. uint64_t* bytes_read);
  89. inline Status GetBlobFileReader(
  90. const ReadOptions& read_options, uint64_t blob_file_number,
  91. CacheHandleGuard<BlobFileReader>* blob_file_reader) {
  92. return blob_file_cache_->GetBlobFileReader(read_options, blob_file_number,
  93. blob_file_reader);
  94. }
  95. inline Cache* GetBlobCache() const { return blob_cache_.get(); }
  96. bool TEST_BlobInCache(uint64_t file_number, uint64_t file_size,
  97. uint64_t offset, size_t* charge = nullptr) const;
  98. // For TypedSharedCacheInterface
  99. void Create(BlobContents** out, const char* buf, size_t size,
  100. MemoryAllocator* alloc);
  101. using SharedCacheInterface =
  102. FullTypedSharedCacheInterface<BlobContents, BlobContentsCreator>;
  103. using TypedHandle = SharedCacheInterface::TypedHandle;
  104. private:
  105. Status GetBlobFromCache(const Slice& cache_key,
  106. CacheHandleGuard<BlobContents>* cached_blob) const;
  107. Status PutBlobIntoCache(const Slice& cache_key,
  108. std::unique_ptr<BlobContents>* blob,
  109. CacheHandleGuard<BlobContents>* cached_blob) const;
  110. static void PinCachedBlob(CacheHandleGuard<BlobContents>* cached_blob,
  111. PinnableSlice* value);
  112. static void PinOwnedBlob(std::unique_ptr<BlobContents>* owned_blob,
  113. PinnableSlice* value);
  114. TypedHandle* GetEntryFromCache(const Slice& key) const;
  115. Status InsertEntryIntoCache(const Slice& key, BlobContents* value,
  116. TypedHandle** cache_handle,
  117. Cache::Priority priority) const;
  118. inline CacheKey GetCacheKey(uint64_t file_number, uint64_t /*file_size*/,
  119. uint64_t offset) const {
  120. OffsetableCacheKey base_cache_key(db_id_, db_session_id_, file_number);
  121. return base_cache_key.WithOffset(offset);
  122. }
  123. const std::string& db_id_;
  124. const std::string& db_session_id_;
  125. Statistics* statistics_;
  126. // A cache to store blob file reader.
  127. BlobFileCache* blob_file_cache_;
  128. // A cache to store uncompressed blobs.
  129. mutable SharedCacheInterface blob_cache_;
  130. // The control option of how the cache tiers will be used. Currently rocksdb
  131. // support block/blob cache (volatile tier) and secondary cache (this tier
  132. // isn't strictly speaking a non-volatile tier since the compressed cache in
  133. // this tier is in volatile memory).
  134. const CacheTier lowest_used_cache_tier_;
  135. };
  136. } // namespace ROCKSDB_NAMESPACE