@@ -806,7 +806,7 @@ class CacheAllocator : public CacheBase {
806806 // @param config new config for the pool
807807 //
808808 // @throw std::invalid_argument if the poolId is invalid
809- void overridePoolConfig (PoolId pid, const MMConfig& config);
809+ void overridePoolConfig (TierId tid, PoolId pid, const MMConfig& config);
810810
811811 // update an existing pool's rebalance strategy
812812 //
@@ -847,8 +847,9 @@ class CacheAllocator : public CacheBase {
847847 // @return true if the operation succeeded. false if the size of the pool is
848848 // smaller than _bytes_
849849 // @throw std::invalid_argument if the poolId is invalid.
850+ // TODO: should call shrinkPool for specific tier?
850851 bool shrinkPool (PoolId pid, size_t bytes) {
851- return allocator_->shrinkPool (pid, bytes);
852+ return allocator_[ currentTier ()] ->shrinkPool (pid, bytes);
852853 }
853854
854855 // grow an existing pool by _bytes_. This will fail if there is no
@@ -857,8 +858,9 @@ class CacheAllocator : public CacheBase {
857858 // @return true if the pool was grown. false if the necessary number of
858859 // bytes were not available.
859860 // @throw std::invalid_argument if the poolId is invalid.
861+ // TODO: should call growPool for specific tier?
860862 bool growPool (PoolId pid, size_t bytes) {
861- return allocator_->growPool (pid, bytes);
863+ return allocator_[ currentTier ()] ->growPool (pid, bytes);
862864 }
863865
864866 // move bytes from one pool to another. The source pool should be at least
@@ -871,7 +873,7 @@ class CacheAllocator : public CacheBase {
871873 // correct size to do the transfer.
872874 // @throw std::invalid_argument if src or dest is invalid pool
873875 bool resizePools (PoolId src, PoolId dest, size_t bytes) override {
874- return allocator_->resizePools (src, dest, bytes);
876+ return allocator_[ currentTier ()] ->resizePools (src, dest, bytes);
875877 }
876878
877879 // Add a new compact cache with given name and size
@@ -1076,12 +1078,13 @@ class CacheAllocator : public CacheBase {
10761078 // @throw std::invalid_argument if the memory does not belong to this
10771079 // cache allocator
10781080 AllocInfo getAllocInfo (const void * memory) const {
1079- return allocator_->getAllocInfo (memory);
1081+ return allocator_[ getTierId (memory)] ->getAllocInfo (memory);
10801082 }
10811083
10821084 // return the ids for the set of existing pools in this cache.
10831085 std::set<PoolId> getPoolIds () const override final {
1084- return allocator_->getPoolIds ();
1086+ // all tiers have the same pool ids. TODO: deduplicate
1087+ return allocator_[0 ]->getPoolIds ();
10851088 }
10861089
10871090 // return a list of pool ids that are backing compact caches. This includes
@@ -1093,27 +1096,28 @@ class CacheAllocator : public CacheBase {
10931096
10941097 // return the pool with speicified id.
10951098 const MemoryPool& getPool (PoolId pid) const override final {
1096- return allocator_->getPool (pid);
1099+ return allocator_[ currentTier ()] ->getPool (pid);
10971100 }
10981101
10991102 // calculate the number of slabs to be advised/reclaimed in each pool
11001103 PoolAdviseReclaimData calcNumSlabsToAdviseReclaim () override final {
11011104 auto regularPoolIds = getRegularPoolIds ();
1102- return allocator_->calcNumSlabsToAdviseReclaim (regularPoolIds);
1105+ return allocator_[ currentTier ()] ->calcNumSlabsToAdviseReclaim (regularPoolIds);
11031106 }
11041107
11051108 // update number of slabs to advise in the cache
11061109 void updateNumSlabsToAdvise (int32_t numSlabsToAdvise) override final {
1107- allocator_->updateNumSlabsToAdvise (numSlabsToAdvise);
1110+ allocator_[ currentTier ()] ->updateNumSlabsToAdvise (numSlabsToAdvise);
11081111 }
11091112
11101113 // returns a valid PoolId corresponding to the name or kInvalidPoolId if the
11111114 // name is not a recognized pool
11121115 PoolId getPoolId (folly::StringPiece name) const noexcept ;
11131116
11141117 // returns the pool's name by its poolId.
1115- std::string getPoolName (PoolId poolId) const override {
1116- return allocator_->getPoolName (poolId);
1118+ std::string getPoolName (PoolId poolId) const {
1119+ // all tiers have the same pool names.
1120+ return allocator_[0 ]->getPoolName (poolId);
11171121 }
11181122
11191123 // get stats related to all kinds of slab release events.
@@ -1390,19 +1394,27 @@ class CacheAllocator : public CacheBase {
13901394
13911395 using MMContainerPtr = std::unique_ptr<MMContainer>;
13921396 using MMContainers =
1393- std::array<std::array<MMContainerPtr, MemoryAllocator::kMaxClasses >,
1394- MemoryPoolManager::kMaxPools >;
1397+ std::vector<std:: array<std::array<MMContainerPtr, MemoryAllocator::kMaxClasses >,
1398+ MemoryPoolManager::kMaxPools >> ;
13951399
13961400 void createMMContainers (const PoolId pid, MMConfig config);
13971401
1402+ TierId getTierId (const Item& item) const ;
1403+ TierId getTierId (const void * ptr) const ;
1404+
13981405 // acquire the MMContainer corresponding to the the Item's class and pool.
13991406 //
14001407 // @return pointer to the MMContainer.
14011408 // @throw std::invalid_argument if the Item does not point to a valid
14021409 // allocation from the memory allocator.
14031410 MMContainer& getMMContainer (const Item& item) const noexcept ;
14041411
1405- MMContainer& getMMContainer (PoolId pid, ClassId cid) const noexcept ;
1412+ MMContainer& getMMContainer (TierId tid, PoolId pid, ClassId cid) const noexcept ;
1413+
1414+ // Get stats of the specified pid and cid.
1415+ // If such mmcontainer is not valid (pool id or cid out of bound)
1416+ // or the mmcontainer is not initialized, return an empty stat.
1417+ MMContainerStat getMMContainerStat (TierId tid, PoolId pid, ClassId cid) const noexcept ;
14061418
14071419 // create a new cache allocation. The allocation can be initialized
14081420 // appropriately and made accessible through insert or insertOrReplace.
@@ -1434,6 +1446,17 @@ class CacheAllocator : public CacheBase {
14341446 uint32_t creationTime,
14351447 uint32_t expiryTime);
14361448
1449+ // create a new cache allocation on specific memory tier.
1450+ // For description see allocateInternal.
1451+ //
1452+ // @param tid id a memory tier
1453+ WriteHandle allocateInternalTier (TierId tid,
1454+ PoolId id,
1455+ Key key,
1456+ uint32_t size,
1457+ uint32_t creationTime,
1458+ uint32_t expiryTime);
1459+
14371460 // Allocate a chained item
14381461 //
14391462 // The resulting chained item does not have a parent item and
@@ -1519,6 +1542,15 @@ class CacheAllocator : public CacheBase {
15191542 // not exist.
15201543 FOLLY_ALWAYS_INLINE WriteHandle findFastImpl (Key key, AccessMode mode);
15211544
1545+ // Moves a regular item to a different memory tier.
1546+ //
1547+ // @param oldItem Reference to the item being moved
1548+ // @param newItemHdl Reference to the handle of the new item being moved into
1549+ //
1550+ // @return true If the move was completed, and the containers were updated
1551+ // successfully.
1552+ bool moveRegularItemOnEviction (Item& oldItem, WriteHandle& newItemHdl);
1553+
15221554 // Moves a regular item to a different slab. This should only be used during
15231555 // slab release after the item's exclusive bit has been set. The user supplied
15241556 // callback is responsible for copying the contents and fixing the semantics
@@ -1670,7 +1702,7 @@ class CacheAllocator : public CacheBase {
16701702 // @param pid the id of the pool to look for evictions inside
16711703 // @param cid the id of the class to look for evictions inside
16721704 // @return An evicted item or nullptr if there is no suitable candidate.
1673- Item* findEviction (PoolId pid, ClassId cid);
1705+ Item* findEviction (TierId tid, PoolId pid, ClassId cid);
16741706
16751707 using EvictionIterator = typename MMContainer::LockedIterator;
16761708
@@ -1686,7 +1718,7 @@ class CacheAllocator : public CacheBase {
16861718 const typename Item::PtrCompressor& compressor);
16871719
16881720 unsigned int reclaimSlabs (PoolId id, size_t numSlabs) final {
1689- return allocator_->reclaimSlabsAndGrow (id, numSlabs);
1721+ return allocator_[ currentTier ()] ->reclaimSlabsAndGrow (id, numSlabs);
16901722 }
16911723
16921724 FOLLY_ALWAYS_INLINE EventTracker* getEventTracker () const {
@@ -1745,7 +1777,7 @@ class CacheAllocator : public CacheBase {
17451777 const void * hint = nullptr ) final ;
17461778
17471779 // @param releaseContext slab release context
1748- void releaseSlabImpl (const SlabReleaseContext& releaseContext);
1780+ void releaseSlabImpl (TierId tid, const SlabReleaseContext& releaseContext);
17491781
17501782 // @return true when successfully marked as moving,
17511783 // fasle when this item has already been freed
@@ -1807,7 +1839,7 @@ class CacheAllocator : public CacheBase {
18071839 // primitives. So we consciously exempt ourselves here from TSAN data race
18081840 // detection.
18091841 folly::annotate_ignore_thread_sanitizer_guard g (__FILE__, __LINE__);
1810- auto slabsSkipped = allocator_->forEachAllocation (std::forward<Fn>(f));
1842+ auto slabsSkipped = allocator_[ currentTier ()] ->forEachAllocation (std::forward<Fn>(f));
18111843 stats ().numReaperSkippedSlabs .add (slabsSkipped);
18121844 }
18131845
@@ -1851,10 +1883,10 @@ class CacheAllocator : public CacheBase {
18511883 std::unique_ptr<T>& worker,
18521884 std::chrono::seconds timeout = std::chrono::seconds{0 });
18531885
1854- ShmSegmentOpts createShmCacheOpts ();
1855- std::unique_ptr<MemoryAllocator> createNewMemoryAllocator ();
1856- std::unique_ptr<MemoryAllocator> restoreMemoryAllocator ();
1857- std::unique_ptr<CCacheManager> restoreCCacheManager ();
1886+ ShmSegmentOpts createShmCacheOpts (TierId tid );
1887+ std::unique_ptr<MemoryAllocator> createNewMemoryAllocator (TierId tid );
1888+ std::unique_ptr<MemoryAllocator> restoreMemoryAllocator (TierId tid );
1889+ std::unique_ptr<CCacheManager> restoreCCacheManager (TierId tid );
18581890
18591891 PoolIds filterCompactCachePools (const PoolIds& poolIds) const ;
18601892
@@ -1874,7 +1906,7 @@ class CacheAllocator : public CacheBase {
18741906 }
18751907
18761908 typename Item::PtrCompressor createPtrCompressor () const {
1877- return allocator_->createPtrCompressor <Item>();
1909+ return allocator_[ 0 /* TODO */ ] ->createPtrCompressor <Item>();
18781910 }
18791911
18801912 // helper utility to throttle and optionally log.
@@ -1897,9 +1929,14 @@ class CacheAllocator : public CacheBase {
18971929
18981930 // @param type the type of initialization
18991931 // @return nullptr if the type is invalid
1900- // @return pointer to memory allocator
1932+ // @return vector of pointers to memory allocator
19011933 // @throw std::runtime_error if type is invalid
1902- std::unique_ptr<MemoryAllocator> initAllocator (InitMemType type);
1934+ std::vector<std::unique_ptr<MemoryAllocator>> initAllocator (InitMemType type);
1935+
1936+ std::vector<std::unique_ptr<MemoryAllocator>> createPrivateAllocator ();
1937+ std::vector<std::unique_ptr<MemoryAllocator>> createAllocators ();
1938+ std::vector<std::unique_ptr<MemoryAllocator>> restoreAllocators ();
1939+
19031940 // @param type the type of initialization
19041941 // @return nullptr if the type is invalid
19051942 // @return pointer to access container
@@ -1957,6 +1994,17 @@ class CacheAllocator : public CacheBase {
19571994
19581995 // BEGIN private members
19591996
1997+ TierId currentTier () const {
1998+ // TODO: every function which calls this method should be refactored.
1999+ // We should go case by case and either make such function work on
2000+ // all tiers or expose separate parameter to describe the tier ID.
2001+ return 0 ;
2002+ }
2003+
2004+ unsigned getNumTiers () const {
2005+ return memoryTierConfigs.size ();
2006+ }
2007+
19602008 // Whether the memory allocator for this cache allocator was created on shared
19612009 // memory. The hash table, chained item hash table etc is also created on
19622010 // shared memory except for temporary shared memory mode when they're created
@@ -1984,9 +2032,10 @@ class CacheAllocator : public CacheBase {
19842032 const MMConfig mmConfig_{};
19852033
19862034 // the memory allocator for allocating out of the available memory.
1987- std::unique_ptr<MemoryAllocator> allocator_;
2035+ std::vector<std:: unique_ptr<MemoryAllocator> > allocator_;
19882036
19892037 // compact cache allocator manager
2038+ // TODO: per tier?
19902039 std::unique_ptr<CCacheManager> compactCacheManager_;
19912040
19922041 // compact cache instances reside here when user "add" or "attach" compact
0 commit comments