@@ -27,9 +27,12 @@ namespace cachelib {
2727
2828class SlabAllocator ;
2929
30+ template <typename PtrType, typename AllocatorContainer>
31+ class PtrCompressor ;
32+
3033// 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
3336// is used for pointer compression by the memory allocator.
3437
3538// We compress pointers by storing the tier index, slab index and alloc index of
@@ -173,12 +176,14 @@ class CACHELIB_PACKED_ATTR CompressedPtr {
173176 }
174177
175178 friend SlabAllocator;
179+ template <typename CPtrType, typename AllocatorContainer>
180+ friend class PtrCompressor ;
176181};
177182
178183template <typename PtrType, typename AllocatorT>
179- class PtrCompressor {
184+ class SingleTierPtrCompressor {
180185 public:
181- explicit PtrCompressor (const AllocatorT& allocator) noexcept
186+ explicit SingleTierPtrCompressor (const AllocatorT& allocator) noexcept
182187 : allocator_(allocator) {}
183188
184189 const CompressedPtr compress (const PtrType* uncompressed) const {
@@ -190,17 +195,65 @@ class PtrCompressor {
190195 allocator_.unCompress (compressed, false /* isMultiTiered */ ));
191196 }
192197
193- bool operator ==(const PtrCompressor & rhs) const noexcept {
198+ bool operator ==(const SingleTierPtrCompressor & rhs) const noexcept {
194199 return &allocator_ == &rhs.allocator_ ;
195200 }
196201
197- bool operator !=(const PtrCompressor & rhs) const noexcept {
202+ bool operator !=(const SingleTierPtrCompressor & rhs) const noexcept {
198203 return !(*this == rhs);
199204 }
200205
201206 private:
202207 // memory allocator that does the pointer compression.
203208 const AllocatorT& allocator_;
204209};
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+ };
205258} // namespace cachelib
206259} // namespace facebook
0 commit comments