forked from facebook/CacheLib
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathCache.h
304 lines (252 loc) · 11.2 KB
/
Cache.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <gtest/gtest_prod.h>
#include <mutex>
#include <unordered_map>
#include "cachelib/allocator/CacheDetails.h"
#include "cachelib/allocator/CacheStats.h"
#include "cachelib/allocator/ICompactCache.h"
#include "cachelib/allocator/memory/MemoryAllocator.h"
#include "cachelib/common/Hash.h"
namespace facebook {
namespace cachelib {
class PoolResizer;
class PoolRebalancer;
class PoolOptimizer;
class MemoryMonitor;
// Forward declaration.
class RebalanceStrategy;
class PoolOptimizeStrategy;
class MarginalHitsOptimizeStrategy;
class AllocatorConfigExporter;
namespace tests {
struct SimplePoolOptimizeStrategy;
}
// The mode in which the cache was accessed. This can be used by containers
// to differentiate between the access modes and do appropriate action.
enum class AccessMode { kRead, kWrite };
// used by RemoveCB, indicating if the removal from the MMContainer was an
// eviction or not.
enum class RemoveContext { kEviction, kNormal };
// used by ItemDestructor, indicating how the item is destructed
enum class DestructorContext {
// item was in dram and evicted from dram. it could have
// been present in nvm as well.
kEvictedFromRAM,
// item was only in nvm and evicted from nvm
kEvictedFromNVM,
// item was present in dram and removed by user calling
// remove()/insertOrReplace, or removed due to expired.
// it could have been present in nvm as well.
kRemovedFromRAM,
// item was present only in nvm and removed by user calling
// remove()/insertOrReplace.
kRemovedFromNVM
};
// A base class of cache exposing members and status agnostic of template type.
class CacheBase {
public:
CacheBase() = default;
virtual ~CacheBase() = default;
// Movable but not copyable
CacheBase(const CacheBase&) = delete;
CacheBase& operator=(const CacheBase&) = delete;
CacheBase(CacheBase&&) = default;
CacheBase& operator=(CacheBase&&) = default;
// TODO: come up with some reasonable number
static constexpr unsigned kMaxTiers = 2;
// Get a string referring to the cache name for this cache
virtual const std::string getCacheName() const = 0;
// Returns true for ObjectCacheBase, false for CacheAllocator.
virtual bool isObjectCache() const = 0;
// Get the reference to a memory pool, for stats purposes
// uses the top most memory tier by default
//
// @param poolId The pool id to query
virtual const MemoryPool& getPool(PoolId poolId) const = 0;
// Get Pool specific stats (regular pools). This includes stats from the
// Memory Pool and also the cache.
//
// @param poolId the pool id
virtual PoolStats getPoolStats(PoolId poolId) const = 0;
virtual AllocationClassBaseStat getAllocationClassStats(
TierId, PoolId pid, ClassId cid) const = 0;
// @param poolId the pool id
virtual AllSlabReleaseEvents getAllSlabReleaseEvents(PoolId poolId) const = 0;
// This can be expensive so it is not part of PoolStats
//
// @param pid pool id
// @param slabProjectionLength number of slabs worth of items to visit to
// estimate the projected age. If 0, returns
// tail age for projection age.
//
// @return PoolEvictionAgeStats see CacheStats.h
virtual PoolEvictionAgeStats getPoolEvictionAgeStats(
PoolId pid, unsigned int slabProjectionLength) const = 0;
// @return a map of <stat name -> stat value> representation for all the nvm
// cache stats. This is useful for our monitoring to directly upload them.
virtual std::unordered_map<std::string, double> getNvmCacheStatsMap()
const = 0;
// @return a map of <stat name -> stat value> representation for all the event
// tracker stats. If no event tracker exists, this will be empty
virtual std::unordered_map<std::string, uint64_t> getEventTrackerStatsMap()
const = 0;
// @return the Cache metadata
virtual CacheMetadata getCacheMetadata() const noexcept = 0;
// @return cache's memory usage stats
virtual CacheMemoryStats getCacheMemoryStats() const = 0;
// @return the overall cache stats
virtual GlobalCacheStats getGlobalCacheStats() const = 0;
// @return the slab release stats.
virtual SlabReleaseStats getSlabReleaseStats() const = 0;
// Set rebalancing strategy
//
// @param pid Pool id of the pool to set this strategy on.
// @param strategy The strategy
void setRebalanceStrategy(PoolId pid,
std::shared_ptr<RebalanceStrategy> strategy);
// @param pid The pool id.
//
// @return The rebalancing strategy of the specifid pool.
std::shared_ptr<RebalanceStrategy> getRebalanceStrategy(PoolId pid) const;
// Set resizing strategy
//
// @param pid Pool id of the pool to set this strategy on.
// @param strategy The strategy
void setResizeStrategy(PoolId pid,
std::shared_ptr<RebalanceStrategy> strategy);
// @param pid The pool id.
//
// @return The resizing strategy of the specifid pool.
std::shared_ptr<RebalanceStrategy> getResizeStrategy(PoolId pid) const;
// Set optimizing strategy
//
// @param pid Pool id of the pool to set this strategy on.
// @param strategy The strategy
void setPoolOptimizeStrategy(std::shared_ptr<PoolOptimizeStrategy> strategy);
// @param pid The pool id.
//
// @return The optimizing strategy of the specifid pool.
std::shared_ptr<PoolOptimizeStrategy> getPoolOptimizeStrategy() const;
// return the list of currently active pools that are oversized
virtual std::set<PoolId> getRegularPoolIdsForResize() const = 0;
// return a list of all valid pool ids.
virtual std::set<PoolId> getPoolIds() const = 0;
// returns a list of pools excluding compact cache pools
virtual std::set<PoolId> getRegularPoolIds() const = 0;
// returns a list of pools created for ccache.
virtual std::set<PoolId> getCCachePoolIds() const = 0;
// return whether a pool participates in auto-resizing
virtual bool autoResizeEnabledForPool(PoolId) const = 0;
// return the virtual interface of an attached compact cache for a particular
// pool id
virtual const ICompactCache& getCompactCache(PoolId pid) const = 0;
// return object cache stats
virtual void getObjectCacheCounters(
std::function<void(folly::StringPiece, uint64_t)>) const {}
protected:
// move bytes from one pool to another. The source pool should be at least
// _bytes_ in size.
//
//
// @param src the pool to be sized down and giving the memory.
// @param dest the pool receiving the memory.
// @param bytes the number of bytes to move from src to dest.
// @param true if the resize succeeded. false if src does does not have
// correct size to do the transfer.
// @throw std::invalid_argument if src or dest is invalid pool
virtual bool resizePools(PoolId /* src */,
PoolId /* dest */,
size_t /* bytes */) = 0;
// resize all of the attached and disabled compact caches
virtual void resizeCompactCaches() = 0;
// serialize cache allocator config for exporting to Scuba
virtual std::map<std::string, std::string> serializeConfigParams() const = 0;
// Releases a slab from a pool into its corresponding memory pool
// or back to the slab allocator, depending on SlabReleaseMode.
// SlabReleaseMode::kRebalance -> back to the pool
// SlabReleaseMode::kResize -> back to the slab allocator
//
// @param pid Pool that will make make one slab available
// @param cid Class that will release a slab back to its pool
// or slab allocator
// @param mode the mode for slab release (rebalance/resize)
// @param hint hint referring to the slab. this can be an allocation
// that the user knows to exist in the slab. If this is
// nullptr, a random slab is selected from the pool and
// allocation class.
//
// @throw std::invalid_argument if the hint is invalid or if the pid or cid
// is invalid.
virtual void releaseSlab(PoolId pid,
ClassId cid,
SlabReleaseMode mode,
const void* hint = nullptr) = 0;
// update the number of slabs to be advised
virtual void updateNumSlabsToAdvise(int32_t numSlabsToAdvise) = 0;
// calculate the number of slabs to be advised/reclaimed in each pool
virtual PoolAdviseReclaimData calcNumSlabsToAdviseReclaim() = 0;
// Releasing a slab from this allocation class id and pool id. The release
// could be for a pool resizing or allocation class rebalancing.
//
// All active allocations will be evicted in the process.
//
// This function will be blocked until a slab is freed
//
// @param pid Pool that will make one slab available
// @param victim Class that will release a slab back to its pool
// or slab allocator or a receiver if defined
// @param receiver Class that will receive
// @param mode the mode for slab release (rebalance/resize)
// the user knows to exist in the slab. If this is nullptr,
// a random slab is selected from the pool and allocation
// class.
// @param hint hint referring to the slab. this can be an allocation
// that the user knows to exist in the slab. If this is
// nullptr, a random slab is selected from the pool and
// allocation class.
//
// @throw std::invalid_argument if the hint is invalid or if the pid or cid
// is invalid.
virtual void releaseSlab(PoolId pid,
ClassId victim,
ClassId receiver,
SlabReleaseMode mode,
const void* hint = nullptr) = 0;
// Reclaim slabs from the slab allocator that were advised away using
// releaseSlab in SlabReleaseMode::kAdvise mode.
//
// @param pid The pool for which to recliam slabs
// @param numSlabs The number of slabs to reclaim for the pool
// @return The number of slabs that were actually reclaimed (<= numSlabs)
virtual unsigned int reclaimSlabs(PoolId id, size_t numSlabs) = 0;
// Protect 'poolRebalanceStragtegies_' and `poolResizeStrategies_`
// and `poolOptimizeStrategy_`
mutable std::mutex lock_;
std::unordered_map<PoolId, std::shared_ptr<RebalanceStrategy>>
poolRebalanceStrategies_;
std::unordered_map<PoolId, std::shared_ptr<RebalanceStrategy>>
poolResizeStrategies_;
std::shared_ptr<PoolOptimizeStrategy> poolOptimizeStrategy_;
friend PoolResizer;
friend PoolRebalancer;
friend PoolOptimizer;
friend MemoryMonitor;
friend AllocatorConfigExporter;
};
} // namespace cachelib
} // namespace facebook