2525#include  < string> 
2626
2727#include  " cachelib/allocator/Cache.h" 
28+ #include  " cachelib/allocator/MemoryTierCacheConfig.h" 
2829#include  " cachelib/allocator/MM2Q.h" 
2930#include  " cachelib/allocator/MemoryMonitor.h" 
3031#include  " cachelib/allocator/NvmAdmissionPolicy.h" 
@@ -49,6 +50,7 @@ class CacheAllocatorConfig {
4950  using  NvmCacheDeviceEncryptor = typename  CacheT::NvmCacheT::DeviceEncryptor;
5051  using  MoveCb = typename  CacheT::MoveCb;
5152  using  NvmCacheConfig = typename  CacheT::NvmCacheT::Config;
53+   using  MemoryTierConfigs = std::vector<MemoryTierCacheConfig>;
5254  using  Key = typename  CacheT::Key;
5355  using  EventTrackerSharedPtr = std::shared_ptr<typename  CacheT::EventTracker>;
5456  using  Item = typename  CacheT::Item;
@@ -186,14 +188,23 @@ class CacheAllocatorConfig {
186188  //  This allows cache to be persisted across restarts. One example use case is
187189  //  to preserve the cache when releasing a new version of your service. Refer
188190  //  to our user guide for how to set up cache persistence.
191+   //  TODO: get rid of baseAddr or if set make sure all mapping are adjacent?
192+   //  We can also make baseAddr a per-tier configuration
189193  CacheAllocatorConfig& enableCachePersistence (std::string directory,
190194                                               void * baseAddr = nullptr );
191195
192-   //  uses  posix shm segments instead of the default sys-v shm segments. 
193-   //  @throw std::invalid_argument if called without enabling
194-   //  cachePersistence()
196+   //  Uses  posix shm segments instead of the default sys-v shm
197+   //  segments.  @throw std::invalid_argument if called without enabling
198+   //  cachePersistence(). 
195199  CacheAllocatorConfig& usePosixForShm ();
196200
201+   //  Configures cache memory tiers. Accepts vector of MemoryTierCacheConfig.
202+   //  Each vector element describes configuration for a single memory cache tier.
203+   CacheAllocatorConfig& configureMemoryTiers (const  MemoryTierConfigs& configs);
204+ 
205+   //  Return reference to MemoryTierCacheConfigs.
206+   const  MemoryTierConfigs& getMemoryTierConfigs ();
207+ 
197208  //  This turns on a background worker that periodically scans through the
198209  //  access container and look for expired items and remove them.
199210  CacheAllocatorConfig& enableItemReaperInBackground (
@@ -541,6 +552,9 @@ class CacheAllocatorConfig {
541552  //  cache.
542553  uint64_t  nvmAdmissionMinTTL{0 };
543554
555+   //  Configuration for memory tiers.
556+   MemoryTierConfigs memoryTierConfigs;
557+ 
544558  friend  CacheT;
545559
546560 private: 
@@ -801,6 +815,74 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableItemReaperInBackground(
801815  return  *this ;
802816}
803817
818+ template  <typename  T>
819+ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::configureMemoryTiers(
820+       const  MemoryTierConfigs& config) {
821+   memoryTierConfigs = config;
822+   size_t  sum_ratios = 0 ;
823+   size_t  sum_sizes = 0 ;
824+ 
825+   for  (auto  tier_config: memoryTierConfigs) {
826+     auto  tier_size = tier_config.getSize ();
827+     auto  tier_ratio = tier_config.getRatio ();
828+     if  ((!tier_size and  !tier_ratio) || (tier_size and  tier_ratio)) {
829+       throw  std::invalid_argument (
830+         " For each memory tier either size or ratio must be set." 
831+     }
832+     sum_ratios += tier_ratio;
833+     sum_sizes += tier_size;
834+   }
835+ 
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+   }
872+ 
873+   if  (sum_sizes && !getCacheSize ()) {
874+     setCacheSize (sum_sizes);
875+   }
876+ 
877+   return  *this ;
878+ }
879+ 
880+ // const std::vector<MemoryTierCacheConfig>& CacheAllocatorConfig<T>::getMemoryTierConfigs() {
881+ template  <typename  T>
882+ const  typename  CacheAllocatorConfig<T>::MemoryTierConfigs& CacheAllocatorConfig<T>::getMemoryTierConfigs() {
883+   return  memoryTierConfigs;
884+ }
885+ 
804886template  <typename  T>
805887CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::disableCacheEviction() {
806888  disableEviction = true ;
@@ -970,7 +1052,7 @@ std::map<std::string, std::string> CacheAllocatorConfig<T>::serialize() const {
9701052
9711053  configMap[" size" std::to_string (size);
9721054  configMap[" cacheDir" 
973-   configMap[" posixShm" usePosixShm  ? " set" " empty" 
1055+   configMap[" posixShm" isUsingPosixShm ()  ? " set" " empty" 
9741056
9751057  configMap[" defaultAllocSizes" " " 
9761058  //  Stringify std::set
0 commit comments