| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- // 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).
- //
- // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file. See the AUTHORS file for names of contributors.
- #include "rocksdb/cache.h"
- #include "cache/lru_cache.h"
- #include "rocksdb/secondary_cache.h"
- #include "rocksdb/utilities/customizable_util.h"
- #include "rocksdb/utilities/options_type.h"
- #include "util/string_util.h"
- namespace ROCKSDB_NAMESPACE {
- const Cache::CacheItemHelper kNoopCacheItemHelper{};
- static std::unordered_map<std::string, OptionTypeInfo>
- lru_cache_options_type_info = {
- {"capacity",
- {offsetof(struct LRUCacheOptions, capacity), OptionType::kSizeT,
- OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
- {"num_shard_bits",
- {offsetof(struct LRUCacheOptions, num_shard_bits), OptionType::kInt,
- OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
- {"strict_capacity_limit",
- {offsetof(struct LRUCacheOptions, strict_capacity_limit),
- OptionType::kBoolean, OptionVerificationType::kNormal,
- OptionTypeFlags::kMutable}},
- {"high_pri_pool_ratio",
- {offsetof(struct LRUCacheOptions, high_pri_pool_ratio),
- OptionType::kDouble, OptionVerificationType::kNormal,
- OptionTypeFlags::kMutable}},
- {"low_pri_pool_ratio",
- {offsetof(struct LRUCacheOptions, low_pri_pool_ratio),
- OptionType::kDouble, OptionVerificationType::kNormal,
- OptionTypeFlags::kMutable}},
- };
- static std::unordered_map<std::string, OptionTypeInfo>
- comp_sec_cache_options_type_info = {
- {"capacity",
- {offsetof(struct CompressedSecondaryCacheOptions, capacity),
- OptionType::kSizeT, OptionVerificationType::kNormal,
- OptionTypeFlags::kMutable}},
- {"num_shard_bits",
- {offsetof(struct CompressedSecondaryCacheOptions, num_shard_bits),
- OptionType::kInt, OptionVerificationType::kNormal,
- OptionTypeFlags::kMutable}},
- {"compression_type",
- {offsetof(struct CompressedSecondaryCacheOptions, compression_type),
- OptionType::kCompressionType, OptionVerificationType::kNormal,
- OptionTypeFlags::kMutable}},
- {"compress_format_version",
- {offsetof(struct CompressedSecondaryCacheOptions,
- compress_format_version),
- OptionType::kUInt32T, OptionVerificationType::kNormal,
- OptionTypeFlags::kMutable}},
- {"enable_custom_split_merge",
- {offsetof(struct CompressedSecondaryCacheOptions,
- enable_custom_split_merge),
- OptionType::kBoolean, OptionVerificationType::kNormal,
- OptionTypeFlags::kMutable}},
- };
- namespace {
- static void NoopDelete(Cache::ObjectPtr /*obj*/,
- MemoryAllocator* /*allocator*/) {
- assert(false);
- }
- static size_t SliceSize(Cache::ObjectPtr obj) {
- return static_cast<Slice*>(obj)->size();
- }
- static Status SliceSaveTo(Cache::ObjectPtr from_obj, size_t from_offset,
- size_t length, char* out) {
- const Slice& slice = *static_cast<Slice*>(from_obj);
- std::memcpy(out, slice.data() + from_offset, length);
- return Status::OK();
- }
- static Status NoopCreate(const Slice& /*data*/, CompressionType /*type*/,
- CacheTier /*source*/, Cache::CreateContext* /*ctx*/,
- MemoryAllocator* /*allocator*/,
- Cache::ObjectPtr* /*out_obj*/,
- size_t* /*out_charge*/) {
- assert(false);
- return Status::NotSupported();
- }
- static Cache::CacheItemHelper kBasicCacheItemHelper(CacheEntryRole::kMisc,
- &NoopDelete);
- } // namespace
- const Cache::CacheItemHelper kSliceCacheItemHelper{
- CacheEntryRole::kMisc, &NoopDelete, &SliceSize,
- &SliceSaveTo, &NoopCreate, &kBasicCacheItemHelper,
- };
- Status SecondaryCache::CreateFromString(
- const ConfigOptions& config_options, const std::string& value,
- std::shared_ptr<SecondaryCache>* result) {
- if (value.find("compressed_secondary_cache://") == 0) {
- std::string args = value;
- args.erase(0, std::strlen("compressed_secondary_cache://"));
- Status status;
- std::shared_ptr<SecondaryCache> sec_cache;
- CompressedSecondaryCacheOptions sec_cache_opts;
- status = OptionTypeInfo::ParseStruct(config_options, "",
- &comp_sec_cache_options_type_info, "",
- args, &sec_cache_opts);
- if (status.ok()) {
- sec_cache = NewCompressedSecondaryCache(sec_cache_opts);
- }
- if (status.ok()) {
- result->swap(sec_cache);
- }
- return status;
- } else {
- return LoadSharedObject<SecondaryCache>(config_options, value, result);
- }
- }
- Status Cache::CreateFromString(const ConfigOptions& config_options,
- const std::string& value,
- std::shared_ptr<Cache>* result) {
- Status status;
- std::shared_ptr<Cache> cache;
- if (StartsWith(value, "null")) {
- cache = nullptr;
- } else if (value.find("://") == std::string::npos) {
- if (value.find('=') == std::string::npos) {
- cache = NewLRUCache(ParseSizeT(value));
- } else {
- LRUCacheOptions cache_opts;
- status = OptionTypeInfo::ParseStruct(config_options, "",
- &lru_cache_options_type_info, "",
- value, &cache_opts);
- if (status.ok()) {
- cache = NewLRUCache(cache_opts);
- }
- }
- if (status.ok()) {
- result->swap(cache);
- }
- } else {
- status = LoadSharedObject<Cache>(config_options, value, result);
- }
- return status;
- }
- bool Cache::AsyncLookupHandle::IsReady() {
- return pending_handle == nullptr || pending_handle->IsReady();
- }
- bool Cache::AsyncLookupHandle::IsPending() { return pending_handle != nullptr; }
- Cache::Handle* Cache::AsyncLookupHandle::Result() {
- assert(!IsPending());
- return result_handle;
- }
- void Cache::StartAsyncLookup(AsyncLookupHandle& async_handle) {
- async_handle.found_dummy_entry = false; // in case re-used
- assert(!async_handle.IsPending());
- async_handle.result_handle =
- Lookup(async_handle.key, async_handle.helper, async_handle.create_context,
- async_handle.priority, async_handle.stats);
- }
- Cache::Handle* Cache::Wait(AsyncLookupHandle& async_handle) {
- WaitAll(&async_handle, 1);
- return async_handle.Result();
- }
- void Cache::WaitAll(AsyncLookupHandle* async_handles, size_t count) {
- for (size_t i = 0; i < count; ++i) {
- if (async_handles[i].IsPending()) {
- // If a pending handle gets here, it should be marked at "to be handled
- // by a caller" by that caller erasing the pending_cache on it.
- assert(async_handles[i].pending_cache == nullptr);
- }
- }
- }
- void Cache::SetEvictionCallback(EvictionCallback&& fn) {
- // Overwriting non-empty with non-empty could indicate a bug
- assert(!eviction_callback_ || !fn);
- eviction_callback_ = std::move(fn);
- }
- } // namespace ROCKSDB_NAMESPACE
|