@@ -200,10 +200,13 @@ class CacheAllocatorConfig {
200200
201201 // Configures cache memory tiers. Accepts vector of MemoryTierCacheConfig.
202202 // Each vector element describes configuration for a single memory cache tier.
203+ // @throw std::invalid_argument if:
204+ // - the size of configs is 0
205+ // - memory tiers use both size and ratio parameters
203206 CacheAllocatorConfig& configureMemoryTiers (const MemoryTierConfigs& configs);
204207
205- // Return reference to MemoryTierCacheConfigs .
206- const MemoryTierConfigs& getMemoryTierConfigs ();
208+ // Return vector of memory tier configs .
209+ MemoryTierConfigs getMemoryTierConfigs () const ;
207210
208211 // This turns on a background worker that periodically scans through the
209212 // access container and look for expired items and remove them.
@@ -334,7 +337,7 @@ class CacheAllocatorConfig {
334337
335338 const std::string& getCacheName () const noexcept { return cacheName; }
336339
337- size_t getCacheSize () const noexcept { return size; }
340+ size_t getCacheSize () const noexcept ;
338341
339342 bool isUsingPosixShm () const noexcept { return usePosixShm; }
340343
@@ -552,12 +555,16 @@ class CacheAllocatorConfig {
552555 // cache.
553556 uint64_t nvmAdmissionMinTTL{0 };
554557
555- // Configuration for memory tiers.
556- MemoryTierConfigs memoryTierConfigs;
557-
558558 friend CacheT;
559559
560560 private:
561+ void validateMemoryTiersWithSize (const MemoryTierConfigs&, size_t ) const ;
562+
563+ // Configuration for memory tiers.
564+ MemoryTierConfigs memoryTierConfigs{
565+ {MemoryTierCacheConfig::fromShm ().setRatio (1 )}
566+ };
567+
561568 void mergeWithPrefix (
562569 std::map<std::string, std::string>& configMap,
563570 const std::map<std::string, std::string>& configMapToMerge,
@@ -576,6 +583,8 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheName(
576583
577584template <typename T>
578585CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheSize(size_t _size) {
586+ validateMemoryTiersWithSize (this ->memoryTierConfigs , _size);
587+
579588 size = _size;
580589 constexpr size_t maxCacheSizeWithCoredump = 64'424'509'440 ; // 60GB
581590 if (size <= maxCacheSizeWithCoredump) {
@@ -818,68 +827,62 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableItemReaperInBackground(
818827template <typename T>
819828CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::configureMemoryTiers(
820829 const MemoryTierConfigs& config) {
821- memoryTierConfigs = config;
822- size_t sum_ratios = 0 ;
823- size_t sum_sizes = 0 ;
830+ if (! config. size ()) {
831+ throw std::invalid_argument ( " There must be at least one memory tier. " ) ;
832+ }
824833
825- for (auto tier_config: memoryTierConfigs ) {
834+ for (auto tier_config: config ) {
826835 auto tier_size = tier_config.getSize ();
827836 auto tier_ratio = tier_config.getRatio ();
828837 if ((!tier_size and !tier_ratio) || (tier_size and tier_ratio)) {
829838 throw std::invalid_argument (
830839 " For each memory tier either size or ratio must be set." );
831840 }
832- sum_ratios += tier_ratio;
833- sum_sizes += tier_size;
834841 }
835842
836- if (sum_ratios) {
837- if (!getCacheSize ()) {
838- throw std::invalid_argument (
839- " Total cache size must be specified when size ratios are \
840- used to specify memory tier sizes." );
841- } else {
842- if (getCacheSize () < sum_ratios) {
843- throw std::invalid_argument (
844- " Sum of all tier size ratios is greater than total cache size." );
845- }
846- // Convert ratios to sizes
847- sum_sizes = 0 ;
848- size_t partition_size = getCacheSize () / sum_ratios;
849- for (auto & tier_config: memoryTierConfigs) {
850- tier_config.setSize (partition_size * tier_config.getRatio ());
851- sum_sizes += tier_config.getSize ();
852- }
853- if (getCacheSize () != sum_sizes) {
854- // Adjust capacity of the last tier to account for rounding error
855- memoryTierConfigs.back ().setSize (memoryTierConfigs.back ().getSize () + \
856- (getCacheSize () - sum_sizes));
857- sum_sizes = getCacheSize ();
858- }
859- }
860- } else if (sum_sizes) {
861- if (getCacheSize () && sum_sizes != getCacheSize ()) {
862- throw std::invalid_argument (
863- " Sum of tier sizes doesn't match total cache size. \
864- Setting of cache total size is not required when per-tier \
865- sizes are specified - it is calculated as sum of tier sizes." );
866- }
867- } else {
868- throw std::invalid_argument (
869- " Either sum of all memory tiers sizes or sum of all ratios \
870- must be greater than 0." );
871- }
843+ validateMemoryTiersWithSize (config, this ->size );
872844
873- if (sum_sizes && !getCacheSize ()) {
874- setCacheSize (sum_sizes);
875- }
845+ memoryTierConfigs = config;
876846
877847 return *this ;
878848}
879849
880850template <typename T>
881- const typename CacheAllocatorConfig<T>::MemoryTierConfigs& CacheAllocatorConfig<T>::getMemoryTierConfigs() {
882- return memoryTierConfigs;
851+ typename CacheAllocatorConfig<T>::MemoryTierConfigs
852+ CacheAllocatorConfig<T>::getMemoryTierConfigs() const {
853+ MemoryTierConfigs config = memoryTierConfigs;
854+ size_t sum_ratios = 0 ;
855+
856+ for (auto &tier_config: config) {
857+ if (auto *v = std::get_if<PosixSysVSegmentOpts>(&tier_config.shmOpts )) {
858+ v->usePosix = usePosixShm;
859+ }
860+
861+ sum_ratios += tier_config.getRatio ();
862+ }
863+
864+ if (sum_ratios == 0 )
865+ return config;
866+
867+ // if ratios are used, size must be specified
868+ XDCHECK (size);
869+
870+ // Convert ratios to sizes, size must be non-zero
871+ size_t sum_sizes = 0 ;
872+ size_t partition_size = size / sum_ratios;
873+ for (auto & tier_config: config) {
874+ tier_config.setSize (partition_size * tier_config.getRatio ());
875+ tier_config.setRatio (0 );
876+ sum_sizes += tier_config.getSize ();
877+ }
878+
879+ if (size != sum_sizes) {
880+ // Adjust capacity of the last tier to account for rounding error
881+ config.back ().setSize (
882+ config.back ().getSize () + (getCacheSize () - sum_sizes));
883+ }
884+
885+ return config;
883886}
884887
885888template <typename T>
@@ -997,6 +1000,46 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setNvmAdmissionMinTTL(
9971000 return *this ;
9981001}
9991002
1003+ template <typename T>
1004+ size_t CacheAllocatorConfig<T>::getCacheSize() const noexcept {
1005+ if (size)
1006+ return size;
1007+
1008+ size_t sum_sizes = 0 ;
1009+ for (const auto &tier_config : getMemoryTierConfigs ()) {
1010+ sum_sizes += tier_config.getSize ();
1011+ }
1012+
1013+ return sum_sizes;
1014+ }
1015+
1016+ template <typename T>
1017+ void CacheAllocatorConfig<T>::validateMemoryTiersWithSize(
1018+ const MemoryTierConfigs &config, size_t size) const {
1019+ size_t sum_ratios = 0 ;
1020+ size_t sum_sizes = 0 ;
1021+
1022+ for (const auto &tier_config: config) {
1023+ sum_ratios += tier_config.getRatio ();
1024+ sum_sizes += tier_config.getSize ();
1025+ }
1026+
1027+ if (sum_ratios && sum_sizes) {
1028+ throw std::invalid_argument (" Cannot mix ratios and sizes." );
1029+ } else if (sum_sizes) {
1030+ if (size && sum_sizes != size) {
1031+ throw std::invalid_argument (
1032+ " Sum of tier sizes doesn't match total cache size. "
1033+ " Setting of cache total size is not required when per-tier "
1034+ " sizes are specified - it is calculated as sum of tier sizes." );
1035+ }
1036+ } else if (!sum_ratios && !sum_sizes) {
1037+ throw std::invalid_argument (
1038+ " Either sum of all memory tiers sizes or sum of all ratios "
1039+ " must be greater than 0." );
1040+ }
1041+ }
1042+
10001043template <typename T>
10011044const CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::validate() const {
10021045 // we can track tail hits only if MMType is MM2Q
@@ -1018,6 +1061,23 @@ const CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::validate() const {
10181061 size,
10191062 maxCacheSize));
10201063 }
1064+
1065+ size_t sum_ratios = 0 ;
1066+ for (auto tier_config: memoryTierConfigs) {
1067+ sum_ratios += tier_config.getRatio ();
1068+ }
1069+
1070+ if (sum_ratios) {
1071+ if (!size) {
1072+ throw std::invalid_argument (
1073+ " Total cache size must be specified when size ratios are "
1074+ " used to specify memory tier sizes." );
1075+ } else if (size < sum_ratios) {
1076+ throw std::invalid_argument (
1077+ " Sum of all tier size ratios is greater than total cache size." );
1078+ }
1079+ }
1080+
10211081 return *this ;
10221082}
10231083
0 commit comments