}
}
+ buffer::list::reserve_t buffer::list::obtain_contiguous_space(
+ const unsigned len)
+ {
+ // note: if len < the normal append_buffer size it *might*
+ // be better to allocate a normal-sized append_buffer and
+ // use part of it. however, that optimizes for the case of
+ // old-style types including new-style types. and in most
+ // such cases, this won't be the very first thing encoded to
+ // the list, so append_buffer will already be allocated.
+ // OTOH if everything is new-style, we *should* allocate
+ // only what we need and conserve memory.
+ if (unlikely(get_append_buffer_unused_tail_length() < len)) {
+ auto new_back = \
+ buffer::ptr_node::create(buffer::create(len)).release();
+ new_back->set_length(0); // unused, so far.
+ _buffers.push_back(*new_back);
+ _carriage = new_back;
+ return { new_back->c_str(), &new_back->_len, &_len };
+ } else {
+ if (unlikely(_carriage != &_buffers.back())) {
+ auto bptr = ptr_node::create(*_carriage, _carriage->length(), 0);
+ _carriage = bptr.get();
+ _buffers.push_back(*bptr.release());
+ }
+ return { _carriage->end_c_str(), &_carriage->_len, &_len };
+ }
+ }
+
void buffer::list::append(const ptr& bp)
{
push_back(bp);
void copy_in(unsigned len, const list& otherl);
};
+ struct reserve_t {
+ char* bp_data;
+ unsigned* bp_len;
+ unsigned* bl_len;
+ };
+
class contiguous_appender {
bufferlist *pbl;
char *pos;
void append_zero(unsigned len);
void prepend_zero(unsigned len);
+ reserve_t obtain_contiguous_space(unsigned len);
+
/*
* get a char
*/