uint64_t need = bl.length() + cct->_conf->bluefs_max_log_runway;
dout(20) << __func__ << " need " << need << dendl;
- mempool::bluefs::vector<bluefs_extent_t> old_extents;
- uint64_t old_allocated = 0;
+ bluefs_fnode_t old_fnode;
int r;
- log_file->fnode.swap_extents(old_extents, old_allocated);
+ log_file->fnode.swap_extents(old_fnode);
if (allocate_with_fallback) {
r = _allocate(log_dev, need, &log_file->fnode);
ceph_assert(r == 0);
_write_super(super_dev);
flush_bdev();
- dout(10) << __func__ << " release old log extents " << old_extents << dendl;
- for (auto& r : old_extents) {
+ dout(10) << __func__ << " release old log extents " << old_fnode.extents << dendl;
+ for (auto& r : old_fnode.extents) {
pending_release[r.bdev].insert(r.offset, r.length);
}
}
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
+#include <algorithm>
#include "bluefs_types.h"
#include "common/Formatter.h"
#include "include/uuid.h"
uint64_t offset, uint64_t *x_off)
{
auto p = extents.begin();
+
+ if (extents_index.size() > 4) {
+ auto it = std::upper_bound(extents_index.begin(), extents_index.end(),
+ offset);
+ assert(it != extents_index.begin());
+ --it;
+ assert(offset >= *it);
+ p += it - extents_index.begin();
+ offset -= *it;
+ }
+
while (p != extents.end()) {
if ((int64_t) offset >= p->length) {
offset -= p->length;
utime_t mtime;
uint8_t prefer_bdev;
mempool::bluefs::vector<bluefs_extent_t> extents;
+
+ // precalculated logical offsets for extents vector entries
+ // allows fast lookup for extent index by the offset value via upper_bound()
+ mempool::bluefs::vector<uint64_t> extents_index;
+
uint64_t allocated;
bluefs_fnode_t() : ino(0), size(0), prefer_bdev(0), allocated(0) {}
void recalc_allocated() {
allocated = 0;
- for (auto& p : extents)
+ extents_index.reserve(extents.size());
+ for (auto& p : extents) {
+ extents_index.emplace_back(allocated);
allocated += p.length;
+ }
}
DENC_HELPERS
}
void append_extent(const bluefs_extent_t& ext) {
+ extents_index.emplace_back(allocated);
extents.push_back(ext);
allocated += ext.length;
}
void pop_front_extent() {
auto it = extents.begin();
allocated -= it->length;
+ extents_index.erase(extents_index.begin());
+ for (auto& i: extents_index) {
+ i -= it->length;
+ }
extents.erase(it);
}
void swap_extents(bluefs_fnode_t& other) {
other.extents.swap(extents);
+ other.extents_index.swap(extents_index);
std::swap(allocated, other.allocated);
}
- void swap_extents(mempool::bluefs::vector<bluefs_extent_t>& swap_to, uint64_t& new_allocated) {
- swap_to.swap(extents);
- std::swap(allocated, new_allocated);
- }
void clear_extents() {
+ extents_index.clear();
extents.clear();
allocated = 0;
}