2727#include " cachelib/allocator/Cache.h"
2828#include " cachelib/allocator/MM2Q.h"
2929#include " cachelib/allocator/MemoryMonitor.h"
30+ #include " cachelib/allocator/MemoryTierCacheConfig.h"
3031#include " cachelib/allocator/NvmAdmissionPolicy.h"
3132#include " cachelib/allocator/PoolOptimizeStrategy.h"
3233#include " cachelib/allocator/RebalanceStrategy.h"
@@ -50,6 +51,7 @@ class CacheAllocatorConfig {
5051 using NvmCacheDeviceEncryptor = typename CacheT::NvmCacheT::DeviceEncryptor;
5152 using MoveCb = typename CacheT::MoveCb;
5253 using NvmCacheConfig = typename CacheT::NvmCacheT::Config;
54+ using MemoryTierConfigs = std::vector<MemoryTierCacheConfig>;
5355 using Key = typename CacheT::Key;
5456 using EventTrackerSharedPtr = std::shared_ptr<typename CacheT::EventTracker>;
5557 using Item = typename CacheT::Item;
@@ -199,6 +201,25 @@ class CacheAllocatorConfig {
199201 // cachePersistence()
200202 CacheAllocatorConfig& usePosixForShm ();
201203
204+ // Configures cache memory tiers. Accepts vector of MemoryTierCacheConfig.
205+ // Each vector element describes configuration for a single memory cache tier.
206+ // Tiers can be set up as ratios of total cache size or have their sizes
207+ // explicitly specified. If ratios are used, then total cache size must be set
208+ // before this method is called; if sizes are explicitly specified, then
209+ // their sum sizes must match the total cache size if it's previously set; if
210+ // the total size has not been set then this method will set it as a sum of
211+ // all tier sizes
212+ CacheAllocatorConfig& configureMemoryTiers (const MemoryTierConfigs& configs);
213+
214+ // Sets total cache size and configures cache memory tiers. This method
215+ // can be used when configuring cache memory tears whose sizes are specified
216+ // via ratios of total cache size.
217+ CacheAllocatorConfig& configureMemoryTiers (size_t totalCacheSize,
218+ const MemoryTierConfigs& configs);
219+
220+ // Return reference to MemoryTierCacheConfigs.
221+ const MemoryTierConfigs& getMemoryTierConfigs ();
222+
202223 // This turns on a background worker that periodically scans through the
203224 // access container and look for expired items and remove them.
204225 CacheAllocatorConfig& enableItemReaperInBackground (
@@ -575,6 +596,12 @@ class CacheAllocatorConfig {
575596 friend CacheT;
576597
577598 private:
599+ CacheAllocatorConfig& setCacheSizeImpl (size_t _size);
600+
601+ // Configuration for memory tiers.
602+ MemoryTierConfigs memoryTierConfigs{
603+ {MemoryTierCacheConfig::fromShm ().setRatio (1 )}};
604+
578605 void mergeWithPrefix (
579606 std::map<std::string, std::string>& configMap,
580607 const std::map<std::string, std::string>& configMapToMerge,
@@ -597,7 +624,8 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheName(
597624}
598625
599626template <typename T>
600- CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheSize(size_t _size) {
627+ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheSizeImpl(
628+ size_t _size) {
601629 size = _size;
602630 constexpr size_t maxCacheSizeWithCoredump = 64'424'509'440 ; // 60GB
603631 if (size <= maxCacheSizeWithCoredump) {
@@ -606,6 +634,18 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheSize(size_t _size) {
606634 return *this ;
607635}
608636
637+ template <typename T>
638+ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheSize(size_t _size) {
639+ if (memoryTierConfigs.size () == 1 ) {
640+ memoryTierConfigs[0 ].setSize (size);
641+ } else {
642+ throw std::invalid_argument (
643+ " Cannot set cache size after configuring memory tiers." );
644+ }
645+
646+ return setCacheSizeImpl (_size);
647+ }
648+
609649template <typename T>
610650CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setDefaultAllocSizes(
611651 std::set<uint32_t > allocSizes) {
@@ -844,6 +884,95 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableItemReaperInBackground(
844884 return *this ;
845885}
846886
887+ template <typename T>
888+ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::configureMemoryTiers(
889+ size_t totalCacheSize, const MemoryTierConfigs& config) {
890+ setCacheSizeImpl (totalCacheSize);
891+ if (!getCacheSize ()) {
892+ throw std::invalid_argument (" Total cache size must be greater than 0." );
893+ }
894+
895+ return configureMemoryTiers (config);
896+ }
897+
898+ template <typename T>
899+ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::configureMemoryTiers(
900+ const MemoryTierConfigs& config) {
901+ if (config.size () != 1 ) {
902+ throw std::invalid_argument (
903+ " Only single memory tier is currently supported." );
904+ }
905+ memoryTierConfigs = config;
906+ size_t sumRatios = 0 ;
907+ size_t sumSizes = 0 ;
908+
909+ for (const auto & tierConfig : memoryTierConfigs) {
910+ auto tierSize = tierConfig.getSize ();
911+ auto tierRatio = tierConfig.getRatio ();
912+ if ((sumRatios && tierSize) || (sumSizes && tierRatio)) {
913+ throw std::invalid_argument (
914+ " For each memory tier either size or ratio must be set." );
915+ }
916+ sumRatios += tierRatio;
917+ sumSizes += tierSize;
918+ }
919+
920+ if (!getCacheSize ()) {
921+ if (sumRatios) {
922+ throw std::invalid_argument (
923+ " Total cache size must be specified when size ratios are "
924+ " used to specify memory tier sizes." );
925+ } else if (sumSizes) {
926+ setCacheSizeImpl (sumSizes);
927+ }
928+ }
929+
930+ if (sumRatios) {
931+ if (!getCacheSize ()) {
932+ throw std::invalid_argument (
933+ " Total cache size must be specified when size ratios are "
934+ " used to specify memory tier sizes." );
935+ } else {
936+ if (getCacheSize () < sumRatios) {
937+ throw std::invalid_argument (
938+ " Sum of all tier size ratios is greater than total cache size." );
939+ }
940+ // Convert ratios to sizes
941+ sumSizes = 0 ;
942+ size_t partitionSize = getCacheSize () / sumRatios;
943+ for (auto & tierConfig : memoryTierConfigs) {
944+ tierConfig.setSize (partitionSize * tierConfig.getRatio ());
945+ sumSizes += tierConfig.getSize ();
946+ }
947+ if (getCacheSize () != sumSizes) {
948+ // Adjust capacity of the last tier to account for rounding error
949+ memoryTierConfigs.back ().setSize (memoryTierConfigs.back ().getSize () +
950+ (getCacheSize () - sumSizes));
951+ sumSizes = getCacheSize ();
952+ }
953+ }
954+ } else if (sumSizes) {
955+ if (sumSizes != getCacheSize ()) {
956+ throw std::invalid_argument (
957+ " Sum of tier sizes doesn't match total cache size. "
958+ " Setting of cache total size is not required when per-tier "
959+ " sizes are specified - it is calculated as sum of tier sizes." );
960+ }
961+ } else {
962+ throw std::invalid_argument (
963+ " Either sum of all memory tiers sizes or sum of all ratios "
964+ " must be greater than 0." );
965+ }
966+
967+ return *this ;
968+ }
969+
970+ template <typename T>
971+ const typename CacheAllocatorConfig<T>::MemoryTierConfigs&
972+ CacheAllocatorConfig<T>::getMemoryTierConfigs() {
973+ return memoryTierConfigs;
974+ }
975+
847976template <typename T>
848977CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::disableCacheEviction() {
849978 disableEviction = true ;
0 commit comments