_len++;
}
- buffer::ptr buffer::list::always_empty_bptr;
+ buffer::ptr_node buffer::list::always_empty_bptr;
buffer::ptr_node& buffer::list::refill_append_space(const unsigned len)
{
++curbuf_prev;
}
- _carriage = &always_empty_bptr;
-
while (len > 0) {
// partial or the last (appendable) one?
if (const auto to_drop = off + len; to_drop < curbuf->length()) {
if (claim_by)
claim_by->append(*curbuf, off, howmuch);
_len -= curbuf->length();
- _num -= 1;
- curbuf = _buffers.erase_after_and_dispose(curbuf_prev);
+ if (curbuf == _carriage) {
+ // no need to reallocate, shrinking and relinking is enough.
+ curbuf = _buffers.erase_after(curbuf_prev);
+ _carriage->set_offset(_carriage->offset() + _carriage->length());
+ _carriage->set_length(0);
+ _buffers.push_back(*_carriage);
+ } else {
+ curbuf = _buffers.erase_after_and_dispose(curbuf_prev);
+ _num -= 1;
+ }
len -= howmuch;
off = 0;
}
static ptr_node* copy_hypercombined(const ptr_node& copy_this);
private:
+ friend list;
+
template <class... Args>
ptr_node(Args&&... args) : ptr(std::forward<Args>(args)...) {
}
// track bufferptr we can modify (especially ::append() to). Not all bptrs
// bufferlist holds have this trait -- if somebody ::push_back(const ptr&),
// he expects it won't change.
- ptr* _carriage;
+ ptr_node* _carriage;
unsigned _len, _num;
template <bool is_const>
// always_empty_bptr has no underlying raw but its _len is always 0.
// This is useful for e.g. get_append_buffer_unused_tail_length() as
// it allows to avoid conditionals on hot paths.
- static ptr always_empty_bptr;
+ static ptr_node always_empty_bptr;
ptr_node& refill_append_space(const unsigned len);
// for page_aligned_appender; never ever expose this publicly!
// Otherwise a costly rebuild could happen in e.g. `KernelDevice`.
buffer_appender.append_zero(padding_len);
buffer_appender.flush();
- // FIXME: `splice` is currently broken at it always thrashes
- // the `_carriage`. This will be fixed in a separated patch.
buffer.splice(buffer.length() - padding_len, padding_len, &bl);
// Deep copy the tail here. This allows to avoid costlier copy on
// bufferlist rebuild in e.g. `KernelDevice` and minimizes number