compressed_secondary_cache.h 4.2 KB
Newer Older
1 2 3 4 5 6 7
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).

#pragma once

8 9
#include <array>
#include <cstddef>
10 11 12 13 14 15 16 17 18 19 20
#include <memory>

#include "cache/lru_cache.h"
#include "memory/memory_allocator.h"
#include "rocksdb/secondary_cache.h"
#include "rocksdb/slice.h"
#include "rocksdb/status.h"
#include "util/compression.h"

namespace ROCKSDB_NAMESPACE {

21
class CompressedSecondaryCacheResultHandle : public SecondaryCacheResultHandle {
22
 public:
23
  CompressedSecondaryCacheResultHandle(void* value, size_t size)
24
      : value_(value), size_(size) {}
25
  virtual ~CompressedSecondaryCacheResultHandle() override = default;
26

27 28 29 30
  CompressedSecondaryCacheResultHandle(
      const CompressedSecondaryCacheResultHandle&) = delete;
  CompressedSecondaryCacheResultHandle& operator=(
      const CompressedSecondaryCacheResultHandle&) = delete;
31 32 33 34 35 36 37 38 39 40 41 42 43 44

  bool IsReady() override { return true; }

  void Wait() override {}

  void* Value() override { return value_; }

  size_t Size() override { return size_; }

 private:
  void* value_;
  size_t size_;
};

45
// The CompressedSecondaryCache is a concrete implementation of
46 47 48 49 50 51
// rocksdb::SecondaryCache.
//
// Users can also cast a pointer to it and call methods on
// it directly, especially custom methods that may be added
// in the future.  For example -
// std::unique_ptr<rocksdb::SecondaryCache> cache =
52 53
//      NewCompressedSecondaryCache(opts);
// static_cast<CompressedSecondaryCache*>(cache.get())->Erase(key);
54

55
class CompressedSecondaryCache : public SecondaryCache {
56
 public:
57
  CompressedSecondaryCache(
58
      size_t capacity, int num_shard_bits, bool strict_capacity_limit,
59
      double high_pri_pool_ratio,
60 61 62
      std::shared_ptr<MemoryAllocator> memory_allocator = nullptr,
      bool use_adaptive_mutex = kDefaultToAdaptiveMutex,
      CacheMetadataChargePolicy metadata_charge_policy =
63
          kDefaultCacheMetadataChargePolicy,
64 65
      CompressionType compression_type = CompressionType::kLZ4Compression,
      uint32_t compress_format_version = 2);
66
  virtual ~CompressedSecondaryCache() override;
67

68
  const char* Name() const override { return "CompressedSecondaryCache"; }
69 70 71 72 73

  Status Insert(const Slice& key, void* value,
                const Cache::CacheItemHelper* helper) override;

  std::unique_ptr<SecondaryCacheResultHandle> Lookup(
74 75
      const Slice& key, const Cache::CreateCallback& create_cb, bool /*wait*/,
      bool& is_in_sec_cache) override;
76 77 78 79 80 81 82 83

  void Erase(const Slice& key) override;

  void WaitAll(std::vector<SecondaryCacheResultHandle*> /*handles*/) override {}

  std::string GetPrintableOptions() const override;

 private:
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
  friend class CompressedSecondaryCacheTest;
  static constexpr std::array<uint16_t, 33> malloc_bin_sizes_{
      32,   64,   96,   128,  160,  192,  224,   256,   320,   384,   448,
      512,  640,  768,  896,  1024, 1280, 1536,  1792,  2048,  2560,  3072,
      3584, 4096, 5120, 6144, 7168, 8192, 10240, 12288, 14336, 16384, 32768};

  struct CacheValueChunk {
    // TODO try "CacheAllocationPtr next;".
    CacheValueChunk* next;
    size_t size;
    // Beginning of the chunk data (MUST BE THE LAST FIELD IN THIS STRUCT!)
    char data[1];

    void Free() { delete[] reinterpret_cast<char*>(this); }
  };

  // Split value into chunks to better fit into jemalloc bins. The chunks
  // are stored in CacheValueChunk and extra charge is needed for each chunk,
  // so the cache charge is recalculated here.
  CacheValueChunk* SplitValueIntoChunks(const Slice& value,
                                        const CompressionType compression_type,
                                        size_t& charge);

  // After merging chunks, the extra charge for each chunk is removed, so
  // the charge is recalculated.
  CacheAllocationPtr MergeChunksIntoValue(const void* chunks_head,
                                          size_t& charge);

  // An implementation of Cache::DeleterFn.
  static void DeletionCallback(const Slice& /*key*/, void* obj);
114
  std::shared_ptr<Cache> cache_;
115
  CompressedSecondaryCacheOptions cache_options_;
116 117 118
};

}  // namespace ROCKSDB_NAMESPACE