@@ -27,9 +27,12 @@ namespace cachelib {
27
27
28
28
class SlabAllocator ;
29
29
30
+ template <typename PtrType, typename AllocatorContainer>
31
+ class PtrCompressor ;
32
+
30
33
// This CompressedPtr makes decompression fast by staying away from division and
31
- // modulo arithmetic and doing those during the compression time. We most often
32
- // decompress a CompressedPtr than compress a pointer while creating one. This
34
+ // modulo arithmetic and doing those during the compression time. We most often
35
+ // decompress a CompressedPtr than compress a pointer while creating one. This
33
36
// is used for pointer compression by the memory allocator.
34
37
35
38
// We compress pointers by storing the tier index, slab index and alloc index of
@@ -173,12 +176,14 @@ class CACHELIB_PACKED_ATTR CompressedPtr {
173
176
}
174
177
175
178
friend SlabAllocator;
179
+ template <typename CPtrType, typename AllocatorContainer>
180
+ friend class PtrCompressor ;
176
181
};
177
182
178
183
template <typename PtrType, typename AllocatorT>
179
- class PtrCompressor {
184
+ class SingleTierPtrCompressor {
180
185
public:
181
- explicit PtrCompressor (const AllocatorT& allocator) noexcept
186
+ explicit SingleTierPtrCompressor (const AllocatorT& allocator) noexcept
182
187
: allocator_(allocator) {}
183
188
184
189
const CompressedPtr compress (const PtrType* uncompressed) const {
@@ -190,17 +195,65 @@ class PtrCompressor {
190
195
allocator_.unCompress (compressed, false /* isMultiTiered */ ));
191
196
}
192
197
193
- bool operator ==(const PtrCompressor & rhs) const noexcept {
198
+ bool operator ==(const SingleTierPtrCompressor & rhs) const noexcept {
194
199
return &allocator_ == &rhs.allocator_ ;
195
200
}
196
201
197
- bool operator !=(const PtrCompressor & rhs) const noexcept {
202
+ bool operator !=(const SingleTierPtrCompressor & rhs) const noexcept {
198
203
return !(*this == rhs);
199
204
}
200
205
201
206
private:
202
207
// memory allocator that does the pointer compression.
203
208
const AllocatorT& allocator_;
204
209
};
210
+
211
+ template <typename PtrType, typename AllocatorContainer>
212
+ class PtrCompressor {
213
+ public:
214
+ explicit PtrCompressor (const AllocatorContainer& allocators) noexcept
215
+ : allocators_(allocators) {}
216
+
217
+ const CompressedPtr compress (const PtrType* uncompressed) const {
218
+ if (uncompressed == nullptr )
219
+ return CompressedPtr{};
220
+
221
+ TierId tid;
222
+ for (tid = 0 ; tid < allocators_.size (); tid++) {
223
+ if (allocators_[tid]->isMemoryInAllocator (
224
+ static_cast <const void *>(uncompressed)))
225
+ break ;
226
+ }
227
+
228
+ bool isMultiTiered = allocators_.size () > 1 ;
229
+ auto cptr = allocators_[tid]->compress (uncompressed, isMultiTiered);
230
+ if (isMultiTiered) { // config has multiple tiers
231
+ cptr.setTierId (tid);
232
+ }
233
+ return cptr;
234
+ }
235
+
236
+ PtrType* unCompress (const CompressedPtr compressed) const {
237
+ if (compressed.isNull ()) {
238
+ return nullptr ;
239
+ }
240
+ bool isMultiTiered = allocators_.size () > 1 ;
241
+ auto & allocator = *allocators_[compressed.getTierId (isMultiTiered)];
242
+ return static_cast <PtrType*>(
243
+ allocator.unCompress (compressed, isMultiTiered));
244
+ }
245
+
246
+ bool operator ==(const PtrCompressor& rhs) const noexcept {
247
+ return &allocators_ == &rhs.allocators_ ;
248
+ }
249
+
250
+ bool operator !=(const PtrCompressor& rhs) const noexcept {
251
+ return !(*this == rhs);
252
+ }
253
+
254
+ private:
255
+ // memory allocator that does the pointer compression.
256
+ const AllocatorContainer& allocators_;
257
+ };
205
258
} // namespace cachelib
206
259
} // namespace facebook
0 commit comments