if (b->data.length()) {
bufferlist bl;
bl.substr_of(b->data, b->length - tail, tail);
- _add_buffer(cache, new Buffer(this, b->state, b->seq, end, bl), 0, b);
+ Buffer *nb = new Buffer(this, b->state, b->seq, end, bl);
+ nb->maybe_rebuild();
+ _add_buffer(cache, nb, 0, b);
} else {
- _add_buffer(cache, new Buffer(this, b->state, b->seq, end, tail), 0, b);
+ _add_buffer(cache, new Buffer(this, b->state, b->seq, end, tail),
+ 0, b);
}
if (!b->is_writing()) {
cache->_adjust_buffer_size(b, front - (int64_t)b->length);
}
b->truncate(front);
+ b->maybe_rebuild();
cache->_audit("discard end 1");
break;
} else {
cache->_adjust_buffer_size(b, front - (int64_t)b->length);
}
b->truncate(front);
+ b->maybe_rebuild();
++i;
continue;
}
if (b->data.length()) {
bufferlist bl;
bl.substr_of(b->data, b->length - keep, keep);
- _add_buffer(cache, new Buffer(this, b->state, b->seq, end, bl), 0, b);
+ Buffer *nb = new Buffer(this, b->state, b->seq, end, bl);
+ nb->maybe_rebuild();
+ _add_buffer(cache, nb, 0, b);
} else {
_add_buffer(cache, new Buffer(this, b->state, b->seq, end, keep), 0, b);
}
//#define DEBUG_CACHE
//#define DEBUG_DEFERRED
+
+
+// constants for Buffer::optimize()
+#define MAX_BUFFER_SLOP_RATIO_DEN 8 // so actually 1/N
+
+
enum {
l_bluestore_first = 732430,
l_bluestore_kv_flush_lat,
}
length = newlen;
}
+ void maybe_rebuild() {
+ if (data.length() &&
+ (data.get_num_buffers() > 1 ||
+ data.front().wasted() > data.length() / MAX_BUFFER_SLOP_RATIO_DEN)) {
+ data.rebuild();
+ }
+ }
void dump(Formatter *f) const {
f->dump_string("state", get_state_name(state));