@@ -200,10 +200,13 @@ class CacheAllocatorConfig {
200
200
201
201
// Configures cache memory tiers. Accepts vector of MemoryTierCacheConfig.
202
202
// 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
203
206
CacheAllocatorConfig& configureMemoryTiers (const MemoryTierConfigs& configs);
204
207
205
- // Return reference to MemoryTierCacheConfigs .
206
- const MemoryTierConfigs& getMemoryTierConfigs ();
208
+ // Return vector of memory tier configs .
209
+ MemoryTierConfigs getMemoryTierConfigs () const ;
207
210
208
211
// This turns on a background worker that periodically scans through the
209
212
// access container and look for expired items and remove them.
@@ -334,7 +337,7 @@ class CacheAllocatorConfig {
334
337
335
338
const std::string& getCacheName () const noexcept { return cacheName; }
336
339
337
- size_t getCacheSize () const noexcept { return size; }
340
+ size_t getCacheSize () const noexcept ;
338
341
339
342
bool isUsingPosixShm () const noexcept { return usePosixShm; }
340
343
@@ -552,12 +555,16 @@ class CacheAllocatorConfig {
552
555
// cache.
553
556
uint64_t nvmAdmissionMinTTL{0 };
554
557
555
- // Configuration for memory tiers.
556
- MemoryTierConfigs memoryTierConfigs;
557
-
558
558
friend CacheT;
559
559
560
560
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
+
561
568
void mergeWithPrefix (
562
569
std::map<std::string, std::string>& configMap,
563
570
const std::map<std::string, std::string>& configMapToMerge,
@@ -576,6 +583,8 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheName(
576
583
577
584
template <typename T>
578
585
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheSize(size_t _size) {
586
+ validateMemoryTiersWithSize (this ->memoryTierConfigs , _size);
587
+
579
588
size = _size;
580
589
constexpr size_t maxCacheSizeWithCoredump = 64'424'509'440 ; // 60GB
581
590
if (size <= maxCacheSizeWithCoredump) {
@@ -818,68 +827,62 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableItemReaperInBackground(
818
827
template <typename T>
819
828
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::configureMemoryTiers(
820
829
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
+ }
824
833
825
- for (auto tier_config: memoryTierConfigs ) {
834
+ for (auto tier_config: config ) {
826
835
auto tier_size = tier_config.getSize ();
827
836
auto tier_ratio = tier_config.getRatio ();
828
837
if ((!tier_size and !tier_ratio) || (tier_size and tier_ratio)) {
829
838
throw std::invalid_argument (
830
839
" For each memory tier either size or ratio must be set." );
831
840
}
832
- sum_ratios += tier_ratio;
833
- sum_sizes += tier_size;
834
841
}
835
842
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 );
872
844
873
- if (sum_sizes && !getCacheSize ()) {
874
- setCacheSize (sum_sizes);
875
- }
845
+ memoryTierConfigs = config;
876
846
877
847
return *this ;
878
848
}
879
849
880
850
template <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;
883
886
}
884
887
885
888
template <typename T>
@@ -997,6 +1000,46 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setNvmAdmissionMinTTL(
997
1000
return *this ;
998
1001
}
999
1002
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
+
1000
1043
template <typename T>
1001
1044
const CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::validate() const {
1002
1045
// we can track tail hits only if MMType is MM2Q
@@ -1018,6 +1061,23 @@ const CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::validate() const {
1018
1061
size,
1019
1062
maxCacheSize));
1020
1063
}
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
+
1021
1081
return *this ;
1022
1082
}
1023
1083
0 commit comments