2828#include " cachelib/allocator/MemoryTierCacheConfig.h"
2929#include " cachelib/allocator/MM2Q.h"
3030#include " cachelib/allocator/MemoryMonitor.h"
31+ #include " cachelib/allocator/MemoryTierCacheConfig.h"
3132#include " cachelib/allocator/NvmAdmissionPolicy.h"
3233#include " cachelib/allocator/PoolOptimizeStrategy.h"
3334#include " cachelib/allocator/RebalanceStrategy.h"
@@ -205,15 +206,15 @@ class CacheAllocatorConfig {
205206 // cachePersistence().
206207 CacheAllocatorConfig& usePosixForShm ();
207208
208- // Configures cache memory tiers. Accepts vector of MemoryTierCacheConfig.
209- // Each vector element describes configuration for a single memory cache tier .
210- // @throw std::invalid_argument if:
211- // - the size of configs is 0
212- // - memory tiers use both size and ratio parameters
209+ // Configures cache memory tiers. Each tier represents a cache region inside
210+ // byte-addressable memory such as DRAM, Pmem, CXLmem .
211+ // Accepts vector of MemoryTierCacheConfig. Each vector element describes
212+ // configuration for a single memory cache tier. Tier sizes are specified as
213+ // ratios, the number of parts of total cache size each tier would occupy.
213214 CacheAllocatorConfig& configureMemoryTiers (const MemoryTierConfigs& configs);
214215
215- // Return vector of memory tier configs .
216- MemoryTierConfigs getMemoryTierConfigs () const ;
216+ // Return reference to MemoryTierCacheConfigs .
217+ const MemoryTierConfigs& getMemoryTierConfigs () const ;
217218
218219 // This turns on a background worker that periodically scans through the
219220 // access container and look for expired items and remove them.
@@ -352,7 +353,7 @@ class CacheAllocatorConfig {
352353
353354 const std::string& getCacheName () const noexcept { return cacheName; }
354355
355- size_t getCacheSize () const noexcept ;
356+ size_t getCacheSize () const noexcept { return size; }
356357
357358 bool isUsingPosixShm () const noexcept { return usePosixShm; }
358359
@@ -367,13 +368,19 @@ class CacheAllocatorConfig {
367368 bool validateStrategy (
368369 const std::shared_ptr<PoolOptimizeStrategy>& strategy) const ;
369370
371+ // check that memory tier ratios are set properly
372+ const CacheAllocatorConfig& validateMemoryTiers () const ;
373+
370374 // @return a map representation of the configs
371375 std::map<std::string, std::string> serialize () const ;
372376
377+ // The max number of memory cache tiers
378+ inline static const size_t kMaxCacheMemoryTiers = 2 ;
379+
373380 // Cache name for users to indentify their own cache.
374381 std::string cacheName{" " };
375382
376- // Amount of memory for this cache instance
383+ // Amount of memory for this cache instance (sum of all memory tiers' sizes)
377384 size_t size = 1 * 1024 * 1024 * 1024 ;
378385
379386 // Directory for shared memory related metadata
@@ -581,8 +588,6 @@ class CacheAllocatorConfig {
581588 friend CacheT;
582589
583590 private:
584- void validateMemoryTiersWithSize (const MemoryTierConfigs&, size_t ) const ;
585-
586591 // Configuration for memory tiers.
587592 MemoryTierConfigs memoryTierConfigs{
588593 {MemoryTierCacheConfig::fromShm ().setRatio (1 )}
@@ -606,8 +611,6 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheName(
606611
607612template <typename T>
608613CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheSize(size_t _size) {
609- validateMemoryTiersWithSize (this ->memoryTierConfigs , _size);
610-
611614 size = _size;
612615 constexpr size_t maxCacheSizeWithCoredump = 64'424'509'440 ; // 60GB
613616 if (size <= maxCacheSizeWithCoredump) {
@@ -861,57 +864,24 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableItemReaperInBackground(
861864
862865template <typename T>
863866CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::configureMemoryTiers(
864- const MemoryTierConfigs& config) {
865- if (!config.size ()) {
866- throw std::invalid_argument (" There must be at least one memory tier." );
867+ const MemoryTierConfigs& config) {
868+ if (config.size () > kMaxCacheMemoryTiers ) {
869+ throw std::invalid_argument (folly::sformat (
870+ " Too many memory tiers. The number of supported tiers is {}." ,
871+ kMaxCacheMemoryTiers ));
867872 }
868-
869- for (auto tier_config: config) {
870- auto tier_size = tier_config.getSize ();
871- auto tier_ratio = tier_config.getRatio ();
872- if ((!tier_size and !tier_ratio) || (tier_size and tier_ratio)) {
873- throw std::invalid_argument (
874- " For each memory tier either size or ratio must be set." );
875- }
873+ if (!config.size ()) {
874+ throw std::invalid_argument (
875+ " There must be at least one memory tier config." );
876876 }
877-
878- validateMemoryTiersWithSize (config, this ->size );
879-
880877 memoryTierConfigs = config;
881-
882878 return *this ;
883879}
884880
885881template <typename T>
886- typename CacheAllocatorConfig<T>::MemoryTierConfigs
882+ const typename CacheAllocatorConfig<T>::MemoryTierConfigs&
887883CacheAllocatorConfig<T>::getMemoryTierConfigs() const {
888- MemoryTierConfigs config = memoryTierConfigs;
889- size_t sum_ratios = 0 ;
890-
891- for (auto &tier_config: config) {
892- if (auto *v = std::get_if<PosixSysVSegmentOpts>(&tier_config.shmOpts )) {
893- v->usePosix = usePosixShm;
894- }
895-
896- sum_ratios += tier_config.getRatio ();
897- }
898-
899- if (sum_ratios == 0 )
900- return config;
901-
902- // if ratios are used, size must be specified
903- XDCHECK (size);
904-
905- // Convert ratios to sizes, size must be non-zero
906- size_t sum_sizes = 0 ;
907- size_t partition_size = size / sum_ratios;
908- for (auto & tier_config: config) {
909- tier_config.setSize (partition_size * tier_config.getRatio ());
910- tier_config.setRatio (0 );
911- sum_sizes += tier_config.getSize ();
912- }
913-
914- return config;
884+ return memoryTierConfigs;
915885}
916886
917887template <typename T>
@@ -1037,46 +1007,6 @@ CacheAllocatorConfig<T>::setSkipPromoteChildrenWhenParentFailed() {
10371007 return *this ;
10381008}
10391009
1040- template <typename T>
1041- size_t CacheAllocatorConfig<T>::getCacheSize() const noexcept {
1042- if (size)
1043- return size;
1044-
1045- size_t sum_sizes = 0 ;
1046- for (const auto &tier_config : getMemoryTierConfigs ()) {
1047- sum_sizes += tier_config.getSize ();
1048- }
1049-
1050- return sum_sizes;
1051- }
1052-
1053- template <typename T>
1054- void CacheAllocatorConfig<T>::validateMemoryTiersWithSize(
1055- const MemoryTierConfigs &config, size_t size) const {
1056- size_t sum_ratios = 0 ;
1057- size_t sum_sizes = 0 ;
1058-
1059- for (const auto &tier_config: config) {
1060- sum_ratios += tier_config.getRatio ();
1061- sum_sizes += tier_config.getSize ();
1062- }
1063-
1064- if (sum_ratios && sum_sizes) {
1065- throw std::invalid_argument (" Cannot mix ratios and sizes." );
1066- } else if (sum_sizes) {
1067- if (size && sum_sizes != size) {
1068- throw std::invalid_argument (
1069- " Sum of tier sizes doesn't match total cache size. "
1070- " Setting of cache total size is not required when per-tier "
1071- " sizes are specified - it is calculated as sum of tier sizes." );
1072- }
1073- } else if (!sum_ratios && !sum_sizes) {
1074- throw std::invalid_argument (
1075- " Either sum of all memory tiers sizes or sum of all ratios "
1076- " must be greater than 0." );
1077- }
1078- }
1079-
10801010template <typename T>
10811011const CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::validate() const {
10821012 // we can track tail hits only if MMType is MM2Q
@@ -1101,23 +1031,7 @@ const CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::validate() const {
11011031 " It's not allowed to enable both RemoveCB and ItemDestructor." );
11021032 }
11031033
1104- size_t sum_ratios = 0 ;
1105- for (auto tier_config: memoryTierConfigs) {
1106- sum_ratios += tier_config.getRatio ();
1107- }
1108-
1109- if (sum_ratios) {
1110- if (!size) {
1111- throw std::invalid_argument (
1112- " Total cache size must be specified when size ratios are "
1113- " used to specify memory tier sizes." );
1114- } else if (size < sum_ratios) {
1115- throw std::invalid_argument (
1116- " Sum of all tier size ratios is greater than total cache size." );
1117- }
1118- }
1119-
1120- return *this ;
1034+ return validateMemoryTiers ();
11211035}
11221036
11231037template <typename T>
@@ -1144,6 +1058,24 @@ bool CacheAllocatorConfig<T>::validateStrategy(
11441058 (type != PoolOptimizeStrategy::MarginalHits || trackTailHits);
11451059}
11461060
1061+ template <typename T>
1062+ const CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::validateMemoryTiers()
1063+ const {
1064+ size_t parts = 0 ;
1065+ for (const auto & tierConfig : memoryTierConfigs) {
1066+ if (!tierConfig.getRatio ()) {
1067+ throw std::invalid_argument (" Tier ratio must be an integer number >=1." );
1068+ }
1069+ parts += tierConfig.getRatio ();
1070+ }
1071+
1072+ if (parts > size) {
1073+ throw std::invalid_argument (
1074+ " Sum of tier ratios must be less than total cache size." );
1075+ }
1076+ return *this ;
1077+ }
1078+
11471079template <typename T>
11481080std::map<std::string, std::string> CacheAllocatorConfig<T>::serialize() const {
11491081 std::map<std::string, std::string> configMap;
0 commit comments