cachelib/allocator/nvmcache/NavyConfig.cpp (175 lines of code) (raw):

/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "cachelib/allocator/nvmcache/NavyConfig.h" #include <stdexcept> #include <string> #include <vector> #include "folly/container/Access.h" namespace facebook { namespace cachelib { namespace navy { const std::string& NavyConfig::getFileName() const { XDCHECK(usesSimpleFile()); return fileName_; } const std::vector<std::string>& NavyConfig::getRaidPaths() const { XDCHECK(usesRaidFiles()); return raidPaths_; } // admission policy settings RandomAPConfig& NavyConfig::enableRandomAdmPolicy() { if (!admissionPolicy_.empty()) { throw std::invalid_argument(folly::sformat( "{} admission policy is already enabled", admissionPolicy_)); } admissionPolicy_ = "random"; return randomAPConfig_; } DynamicRandomAPConfig& NavyConfig::enableDynamicRandomAdmPolicy() { if (!admissionPolicy_.empty()) { throw std::invalid_argument(folly::sformat( "{} admission policy is already enabled", admissionPolicy_)); } admissionPolicy_ = "dynamic_random"; return dynamicRandomAPConfig_; } RandomAPConfig& RandomAPConfig::setAdmProbability(double admProbability) { if (admProbability < 0 || admProbability > 1) { throw std::invalid_argument(folly::sformat( "admission probability should be in the range of [0, 1], but {} is set", admProbability)); } admProbability_ = admProbability; return *this; } // file settings void NavyConfig::setSimpleFile(const std::string& fileName, uint64_t fileSize, bool truncateFile) { if (usesRaidFiles()) { throw std::invalid_argument("already set RAID files"); } fileName_ = fileName; fileSize_ = fileSize; truncateFile_ = truncateFile; } void NavyConfig::setRaidFiles(std::vector<std::string> raidPaths, uint64_t fileSize, bool truncateFile) { if (usesSimpleFile()) { throw std::invalid_argument("already set a simple file"); } if (raidPaths.size() <= 1) { throw std::invalid_argument(folly::sformat( "RAID needs at least two paths, but {} path is set", raidPaths.size())); } raidPaths_ = std::move(raidPaths); fileSize_ = fileSize; truncateFile_ = truncateFile; } BlockCacheConfig& BlockCacheConfig::enableHitsBasedReinsertion( uint8_t hitsThreshold) { reinsertionConfig_.enableHitsBased(hitsThreshold); return *this; } BlockCacheConfig& BlockCacheConfig::enablePctBasedReinsertion( unsigned int pctThreshold) { reinsertionConfig_.enablePctBased(pctThreshold); return *this; } BlockCacheConfig& BlockCacheConfig::enableCustomReinsertion( std::shared_ptr<BlockCacheReinsertionPolicy> policy) { reinsertionConfig_.enableCustom(policy); return *this; } BlockCacheConfig& BlockCacheConfig::setCleanRegions( uint32_t cleanRegions) noexcept { cleanRegions_ = cleanRegions; // Increasing number of in-mem buffers is a short-term mitigation // to avoid reinsertion failure when all buffers in clean regions // are pending flush and the reclaim job is running before flushing complete // (see T93961857, T93959811) numInMemBuffers_ = 2 * cleanRegions; return *this; } // BigHash settings BigHashConfig& BigHashConfig::setSizePctAndMaxItemSize( unsigned int sizePct, uint64_t smallItemMaxSize) { if (sizePct > 100) { throw std::invalid_argument(folly::sformat( "to enable BigHash, BigHash size pct should be in the range of [0, 100]" ", but {} is set", sizePct)); } if (sizePct == 0) { XLOG(INFO) << "BigHash is not configured"; } sizePct_ = sizePct; smallItemMaxSize_ = smallItemMaxSize; return *this; } // job scheduler settings void NavyConfig::setNavyReqOrderingShards(uint64_t navyReqOrderingShards) { if (navyReqOrderingShards == 0) { throw std::invalid_argument( "Navy request ordering shards should always be non-zero"); } navyReqOrderingShards_ = navyReqOrderingShards; } std::map<std::string, std::string> NavyConfig::serialize() const { auto configMap = std::map<std::string, std::string>(); // admission policy settings configMap["navyConfig::admissionPolicy"] = getAdmissionPolicy(); configMap["navyConfig::admissionProbability"] = folly::to<std::string>(randomAPConfig_.getAdmProbability()); configMap["navyConfig::admissionWriteRate"] = folly::to<std::string>(dynamicRandomAPConfig_.getAdmWriteRate()); configMap["navyConfig::maxWriteRate"] = folly::to<std::string>(dynamicRandomAPConfig_.getMaxWriteRate()); configMap["navyConfig::admissionSuffixLen"] = folly::to<std::string>(dynamicRandomAPConfig_.getAdmSuffixLength()); configMap["navyConfig::admissionProbBaseSize"] = folly::to<std::string>(dynamicRandomAPConfig_.getAdmProbBaseSize()); configMap["navyConfig::admissionProbFactorLowerBound"] = folly::to<std::string>(dynamicRandomAPConfig_.getProbFactorLowerBound()); configMap["navyConfig::admissionProbFactorUpperBound"] = folly::to<std::string>(dynamicRandomAPConfig_.getProbFactorUpperBound()); // device settings configMap["navyConfig::blockSize"] = folly::to<std::string>(blockSize_); configMap["navyConfig::fileName"] = fileName_; configMap["navyConfig::raidPaths"] = folly::join(",", raidPaths_); configMap["navyConfig::deviceMetadataSize"] = std::to_string(deviceMetadataSize_); configMap["navyConfig::fileSize"] = folly::to<std::string>(fileSize_); configMap["navyConfig::truncateFile"] = truncateFile_ ? "true" : "false"; configMap["navyConfig::deviceMaxWriteSize"] = folly::to<std::string>(deviceMaxWriteSize_); // BlockCache settings configMap["navyConfig::blockCacheLru"] = blockCacheConfig_.isLruEnabled() ? "true" : "false"; configMap["navyConfig::blockCacheRegionSize"] = folly::to<std::string>(blockCacheConfig_.getRegionSize()); configMap["navyConfig::blockCacheCleanRegions"] = folly::to<std::string>(blockCacheConfig_.getCleanRegions()); configMap["navyConfig::blockCacheReinsertionHitsThreshold"] = folly::to<std::string>( blockCacheConfig_.getReinsertionConfig().getHitsThreshold()); configMap["navyConfig::blockCacheReinsertionPctThreshold"] = folly::to<std::string>( blockCacheConfig_.getReinsertionConfig().getPctThreshold()); configMap["navyConfig::blockCacheNumInMemBuffers"] = folly::to<std::string>(blockCacheConfig_.getNumInMemBuffers()); configMap["navyConfig::blockCacheDataChecksum"] = blockCacheConfig_.getDataChecksum() ? "true" : "false"; configMap["navyConfig::blockCacheSegmentedFifoSegmentRatio"] = folly::join(",", blockCacheConfig_.getSFifoSegmentRatio()); // BigHash settings configMap["navyConfig::bigHashSizePct"] = folly::to<std::string>(bigHashConfig_.getSizePct()); configMap["navyConfig::bigHashBucketSize"] = folly::to<std::string>(bigHashConfig_.getBucketSize()); configMap["navyConfig::bigHashBucketBfSize"] = folly::to<std::string>(bigHashConfig_.getBucketBfSize()); configMap["navyConfig::bigHashSmallItemMaxSize"] = folly::to<std::string>(bigHashConfig_.getSmallItemMaxSize()); // Job scheduler settings configMap["navyConfig::readerThreads"] = folly::to<std::string>(readerThreads_); configMap["navyConfig::writerThreads"] = folly::to<std::string>(writerThreads_); configMap["navyConfig::navyReqOrderingShards"] = folly::to<std::string>(navyReqOrderingShards_); // Other settings configMap["navyConfig::maxConcurrentInserts"] = folly::to<std::string>(maxConcurrentInserts_); configMap["navyConfig::maxParcelMemoryMB"] = folly::to<std::string>(maxParcelMemoryMB_); return configMap; } } // namespace navy } // namespace cachelib } // namespace facebook