StupidAllocator::StupidAllocator(CephContext* cct)
: cct(cct), num_free(0),
- num_reserved(0),
free(10),
last_alloc(0)
{
}
}
-int StupidAllocator::reserve(uint64_t need)
-{
- std::lock_guard<std::mutex> l(lock);
- dout(10) << __func__ << " need 0x" << std::hex << need
- << " num_free 0x" << num_free
- << " num_reserved 0x" << num_reserved << std::dec << dendl;
- if ((int64_t)need > num_free - num_reserved)
- return -ENOSPC;
- num_reserved += need;
- return 0;
-}
-
-void StupidAllocator::unreserve(uint64_t unused)
-{
- std::lock_guard<std::mutex> l(lock);
- dout(10) << __func__ << " unused 0x" << std::hex << unused
- << " num_free 0x" << num_free
- << " num_reserved 0x" << num_reserved << std::dec << dendl;
- assert(num_reserved >= (int64_t)unused);
- num_reserved -= unused;
-}
-
/// return the effective length of the extent if we align to alloc_unit
uint64_t StupidAllocator::_aligned_len(
StupidAllocator::interval_set_t::iterator p,
}
num_free -= *length;
- num_reserved -= *length;
assert(num_free >= 0);
- assert(num_reserved >= 0);
last_alloc = *offset + *length;
return 0;
}
uint64_t alloc_unit,
uint64_t max_alloc_size,
int64_t hint,
- mempool::bluestore_alloc::vector<AllocExtent> *extents)
+ PExtentVector *extents)
{
uint64_t allocated_size = 0;
uint64_t offset = 0;
max_alloc_size = want_size;
}
- ExtentList block_list = ExtentList(extents, 1, max_alloc_size);
-
while (allocated_size < want_size) {
res = allocate_int(MIN(max_alloc_size, (want_size - allocated_size)),
alloc_unit, hint, &offset, &length);
*/
break;
}
- block_list.add_extents(offset, length);
+ bool can_append = true;
+ if (!extents->empty()) {
+ bluestore_pextent_t &last_extent = extents->back();
+ if ((last_extent.end() == offset) &&
+ ((last_extent.length + length) <= max_alloc_size)) {
+ can_append = false;
+ last_extent.length += length;
+ }
+ }
+ if (can_append) {
+ extents->emplace_back(bluestore_pextent_t(offset, length));
+ }
+
allocated_size += length;
hint = offset + length;
}
}
void StupidAllocator::release(
- uint64_t offset, uint64_t length)
+ const interval_set<uint64_t>& release_set)
{
std::lock_guard<std::mutex> l(lock);
- dout(10) << __func__ << " 0x" << std::hex << offset << "~" << length
- << std::dec << dendl;
- _insert_free(offset, length);
- num_free += length;
+ for (interval_set<uint64_t>::const_iterator p = release_set.begin();
+ p != release_set.end();
+ ++p) {
+ const auto offset = p.get_start();
+ const auto length = p.get_len();
+ ldout(cct, 10) << __func__ << " 0x" << std::hex << offset << "~" << length
+ << std::dec << dendl;
+ _insert_free(offset, length);
+ num_free += length;
+ }
}
uint64_t StupidAllocator::get_free()
return num_free;
}
+double StupidAllocator::get_fragmentation(uint64_t alloc_unit)
+{
+ assert(alloc_unit);
+ double res;
+ uint64_t max_intervals = 0;
+ uint64_t intervals = 0;
+ {
+ std::lock_guard<std::mutex> l(lock);
+ max_intervals = num_free / alloc_unit;
+ for (unsigned bin = 0; bin < free.size(); ++bin) {
+ intervals += free[bin].num_intervals();
+ }
+ }
+ ldout(cct, 30) << __func__ << " " << intervals << "/" << max_intervals
+ << dendl;
+ assert(intervals <= max_intervals);
+ if (!intervals || max_intervals <= 1) {
+ return 0.0;
+ }
+ intervals--;
+ max_intervals--;
+ res = (double)intervals / max_intervals;
+ return res;
+}
+
void StupidAllocator::dump()
{
std::lock_guard<std::mutex> l(lock);