void buffer::list::rebuild()
{
if (_len == 0) {
- _buffers.clear();
+ _buffers.clear_and_dispose(ptr_node::disposer());
return;
}
ptr nb;
pos += node.length();
}
_memcopy_count += pos;
- _buffers.clear();
+ _buffers.clear_and_dispose(ptr_node::disposer());
if (nb.length())
- _buffers.push_back(nb);
+ _buffers.push_back(ptr_node::create(nb));
invalidate_crc();
last_p = begin();
}
<< " not ok" << std::endl;
*/
offset += p->length();
- unaligned.push_back(*p);
- p = _buffers.erase(p);
+ // no need to reallocate, relinking is enough thankfully to bi::list.
+ auto after = _buffers.erase(p);
+ unaligned._buffers.push_back(*p);
+ unaligned._len += p->length();
+ p = after;
} while (p != std::end(_buffers) &&
(!p->is_aligned(align_memory) ||
!p->is_n_align_sized(align_size) ||
unaligned.rebuild(nb);
_memcopy_count += unaligned._len;
}
- _buffers.insert(p, unaligned._buffers.front());
+ _buffers.insert(p, ptr_node::create(unaligned._buffers.front()));
}
last_p = begin();
_len += bl._len;
if (!(flags & CLAIM_ALLOW_NONSHAREABLE))
bl.make_shareable();
- std::move(std::begin(bl._buffers), std::end(bl._buffers),
- std::back_inserter(_buffers));
- bl._buffers.clear();
+ _buffers.splice(std::end(_buffers), bl._buffers);
bl._len = 0;
bl.last_p = bl.begin();
}
{
_len += bl._len;
for (const auto& node : bl._buffers) {
- _buffers.push_back(node);
+ _buffers.push_back(ptr_node::create(node));
}
}
void buffer::list::prepend_zero(unsigned len)
{
- ptr bp(len);
+ auto& bp = ptr_node::create(len);
bp.zero(false);
_len += len;
- _buffers.emplace_front(std::move(bp));
+ _buffers.push_front(bp);
}
void buffer::list::append_zero(unsigned len)
len -= need;
}
if (len) {
- ptr bp = buffer::create_page_aligned(len);
+ auto& bp = ptr_node::create(buffer::create_page_aligned(len));
bp.zero(false);
- append(std::move(bp));
+ _len += bp.length();
+ _buffers.push_back(bp);
}
}
// partial?
if (off + len < curbuf->length()) {
//cout << "copying partial of " << *curbuf << std::endl;
- _buffers.push_back( ptr( *curbuf, off, len ) );
+ _buffers.push_back( ptr_node::create( *curbuf, off, len ) );
_len += len;
break;
}
// through end
//cout << "copying end (all?) of " << *curbuf << std::endl;
unsigned howmuch = curbuf->length() - off;
- _buffers.push_back( ptr( *curbuf, off, howmuch ) );
+ _buffers.push_back( ptr_node::create( *curbuf, off, howmuch ) );
_len += howmuch;
len -= howmuch;
off = 0;
// add a reference to the front bit
// insert it before curbuf (which we'll hose)
//cout << "keeping front " << off << " of " << *curbuf << std::endl;
- _buffers.insert( curbuf, ptr( *curbuf, 0, off ) );
+ _buffers.insert( curbuf, ptr_node::create( *curbuf, 0, off ) );
_len += off;
}
if (claim_by)
claim_by->append( *curbuf, off, howmuch );
_len -= (*curbuf).length();
- curbuf = _buffers.erase( curbuf );
+ curbuf = _buffers.erase_and_dispose( curbuf, ptr_node::disposer() );
len -= howmuch;
off = 0;
}
#include <exception>
#include <type_traits>
+#include <boost/intrusive/list.hpp>
+
#include "page.h"
#include "crc32c.h"
#include "buffer_fwd.h"
};
+ class ptr_node : public ptr, public boost::intrusive::list_base_hook<> {
+ template <class... Args>
+ ptr_node(Args&&... args) : ptr(std::forward<Args>(args)...) {
+ }
+
+ ptr_node(const ptr_node&) = default;
+ public:
+
+ ~ptr_node() = default;
+
+ template <class... Args>
+ static ptr_node& create(Args&&... args) {
+ return *new ptr_node(std::forward<Args>(args)...);
+ }
+
+ struct cloner {
+ ptr_node* operator()(const ptr_node& clone_this) {
+ return new ptr_node(clone_this);
+ }
+ };
+ struct disposer {
+ void operator()(ptr_node* const delete_this) {
+ delete delete_this;
+ }
+ };
+ };
/*
* list - the useful bit!
*/
class CEPH_BUFFER_API list {
public:
- typedef std::list<ptr> buffers_t;
+ typedef boost::intrusive::list<ptr_node> buffers_t;
class iterator;
private:
reserve(prealloc);
}
- list(const list& other) : _buffers(other._buffers), _len(other._len),
+ list(const list& other) : _len(other._len),
_memcopy_count(other._memcopy_count), last_p(this) {
+ _buffers.clone_from(other._buffers,
+ ptr_node::cloner(), ptr_node::disposer());
make_shareable();
}
list(list&& other) noexcept;
+
+ ~list() {
+ _buffers.clear_and_dispose(ptr_node::disposer());
+ }
+
list& operator= (const list& other) {
if (this != &other) {
- _buffers = other._buffers;
+ _buffers.clone_from(other._buffers,
+ ptr_node::cloner(), ptr_node::disposer());
_len = other._len;
make_shareable();
}
return *this;
}
-
list& operator= (list&& other) noexcept {
_buffers = std::move(other._buffers);
_len = other._len;
uint64_t get_wasted_space() const;
unsigned get_num_buffers() const { return _buffers.size(); }
- const ptr& front() const { return _buffers.front(); }
- const ptr& back() const { return _buffers.back(); }
+ const ptr_node& front() const { return _buffers.front(); }
+ const ptr_node& back() const { return _buffers.back(); }
int get_mempool() const;
void reassign_to_mempool(int pool);
// modifiers
void clear() noexcept {
- _buffers.clear();
+ _buffers.clear_and_dispose(ptr_node::disposer());
_len = 0;
_memcopy_count = 0;
last_p = begin();
void push_back(const ptr& bp) {
if (bp.length() == 0)
return;
- _buffers.push_back(bp);
+ _buffers.push_back(ptr_node::create(bp));
_len += bp.length();
}
void push_back(ptr&& bp) {
if (bp.length() == 0)
return;
_len += bp.length();
- _buffers.push_back(std::move(bp));
+ _buffers.push_back(ptr_node::create(std::move(bp)));
}
void push_back(raw *r) {
- push_back(ptr(r));
+ _buffers.push_back(ptr_node::create(r));
+ _len += _buffers.back().length();
}
void zero();