bluestore_blob_use_tracker_t::bluestore_blob_use_tracker_t(
const bluestore_blob_use_tracker_t& tracker)
: au_size{tracker.au_size},
- num_au{tracker.num_au},
+ num_au(0),
+ alloc_au(0),
bytes_per_au{nullptr}
{
- if (num_au > 0) {
- allocate();
+ if (tracker.num_au > 0) {
+ allocate(tracker.num_au);
std::copy(tracker.bytes_per_au, tracker.bytes_per_au + num_au, bytes_per_au);
} else {
total_bytes = tracker.total_bytes;
}
clear();
au_size = rhs.au_size;
- num_au = rhs.num_au;
if (rhs.num_au > 0) {
- allocate();
+ allocate( rhs.num_au);
std::copy(rhs.bytes_per_au, rhs.bytes_per_au + num_au, bytes_per_au);
} else {
total_bytes = rhs.total_bytes;
return *this;
}
-void bluestore_blob_use_tracker_t::allocate()
+void bluestore_blob_use_tracker_t::allocate(uint32_t au_count)
{
- ceph_assert(num_au != 0);
- bytes_per_au = new uint32_t[num_au];
+ ceph_assert(au_count != 0);
+ ceph_assert(num_au == 0);
+ ceph_assert(alloc_au == 0);
+ num_au = alloc_au = au_count;
+ bytes_per_au = new uint32_t[alloc_au];
mempool::get_pool(
mempool::pool_index_t(mempool::mempool_bluestore_cache_other)).
- adjust_count(1, sizeof(uint32_t) * num_au);
+ adjust_count(alloc_au, sizeof(uint32_t) * alloc_au);
for (uint32_t i = 0; i < num_au; ++i) {
bytes_per_au[i] = 0;
}
}
+void bluestore_blob_use_tracker_t::release(uint32_t au_count, uint32_t* ptr) {
+ if (au_count) {
+ delete[] ptr;
+ mempool::get_pool(
+ mempool::pool_index_t(mempool::mempool_bluestore_cache_other)).
+ adjust_count(-(int32_t)au_count, -(int32_t)(sizeof(uint32_t) * au_count));
+ }
+}
+
void bluestore_blob_use_tracker_t::init(
uint32_t full_length, uint32_t _au_size) {
ceph_assert(!au_size || is_empty());
uint32_t _num_au = round_up_to(full_length, _au_size) / _au_size;
au_size = _au_size;
if ( _num_au > 1 ) {
- num_au = _num_au;
- allocate();
+ allocate(_num_au);
}
}
// 1) Struct isn't packed hence it's padded. And even if it's packed see 2)
// 2) Mem manager has its own granularity, most probably >= 8 bytes
//
- uint32_t au_size; // Allocation (=tracking) unit size,
- // == 0 if uninitialized
- uint32_t num_au; // Amount of allocation units tracked
- // == 0 if single unit or the whole blob is tracked
+ uint32_t au_size; // Allocation (=tracking) unit size,
+ // == 0 if uninitialized
+ uint32_t num_au; // Amount of allocation units tracked
+ // == 0 if single unit or the whole blob is tracked
+ uint32_t alloc_au; // Amount of allocation units allocated
union {
uint32_t* bytes_per_au;
};
bluestore_blob_use_tracker_t()
- : au_size(0), num_au(0), bytes_per_au(nullptr) {
+ : au_size(0), num_au(0), alloc_au(0), bytes_per_au(nullptr) {
}
bluestore_blob_use_tracker_t(const bluestore_blob_use_tracker_t& tracker);
bluestore_blob_use_tracker_t& operator=(const bluestore_blob_use_tracker_t& rhs);
}
void clear() {
- if (num_au != 0) {
- delete[] bytes_per_au;
- mempool::get_pool(
- mempool::pool_index_t(mempool::mempool_bluestore_cache_other)).
- adjust_count(-1, -sizeof(uint32_t) * num_au);
- }
+ release(alloc_au, bytes_per_au);
+ num_au = 0;
+ alloc_au = 0;
bytes_per_au = 0;
au_size = 0;
- num_au = 0;
}
uint32_t get_referenced_bytes() const {
ceph_assert(_num_au <= num_au);
if (_num_au) {
num_au = _num_au; // bytes_per_au array is left unmodified
-
} else {
clear();
}
if (_num_au > num_au) {
auto old_bytes = bytes_per_au;
auto old_num_au = num_au;
- num_au = _num_au;
- allocate();
+ auto old_alloc_au = alloc_au;
+ alloc_au = num_au = 0; // to bypass an assertion in allocate()
+ bytes_per_au = nullptr;
+ allocate(_num_au);
for (size_t i = 0; i < old_num_au; i++) {
bytes_per_au[i] = old_bytes[i];
}
for (size_t i = old_num_au; i < num_au; i++) {
bytes_per_au[i] = 0;
}
- delete[] old_bytes;
+ release(old_alloc_au, old_bytes);
}
}
}
clear();
denc_varint(au_size, p);
if (au_size) {
- denc_varint(num_au, p);
- if (!num_au) {
+ uint32_t _num_au;
+ denc_varint(_num_au, p);
+ if (!_num_au) {
+ num_au = 0;
denc_varint(total_bytes, p);
} else {
- allocate();
- for (size_t i = 0; i < num_au; ++i) {
+ allocate(_num_au);
+ for (size_t i = 0; i < _num_au; ++i) {
denc_varint(bytes_per_au[i], p);
}
}
void dump(ceph::Formatter *f) const;
static void generate_test_instances(std::list<bluestore_blob_use_tracker_t*>& o);
private:
- void allocate();
+ void allocate(uint32_t _num_au);
+ void release(uint32_t _num_au, uint32_t* ptr);
};
WRITE_CLASS_DENC(bluestore_blob_use_tracker_t)
std::ostream& operator<<(std::ostream& out, const bluestore_blob_use_tracker_t& rm);