上一篇文章介紹了raw羊初。
class ptr數(shù)據(jù)結(jié)構(gòu):
- raw *_raw: 指向?qū)嶋H的數(shù)據(jù)塊
- _off,_len: 數(shù)據(jù)在raw中的偏移地址,及數(shù)據(jù)長度
- iterator_impl: 簡易迭代器
迭代器的結(jié)構(gòu)什湘,定義在ptr結(jié)構(gòu)中:
/*
* is_const: 表示是否const類型长赞,const_iterator、iterator
*/
template<bool is_const>
class iterator_impl {
/*
* *bp: 指向ptr,ptr構(gòu)造函數(shù)中使用this指針初始化;*bp = ptr
* *start: 指向bp->c_str()
*/
const ptr *bp;
const char *start; ///< starting pointer into bp->c_str()
const char *pos; ///< pointer into bp->c_str()
const char *end_ptr; ///< pointer to bp->end_c_str()
const bool deep; ///< if true, do not allow shallow ptr copies
iterator_impl(typename std::conditional<is_const, const ptr*, ptr*>::type p,
size_t offset, bool d)
: bp(p),
start(p->c_str() + offset),
pos(start),
end_ptr(p->end_c_str()),
deep(d)
{}
friend class ptr;
public:
using pointer = typename std::conditional<is_const, const char*, char *>::type;
pointer get_pos_add(size_t n) {
auto r = pos;
*this += n;
return r;
}
ptr get_ptr(size_t len) {
if (deep) {
return buffer::copy(get_pos_add(len), len);
} else {
size_t off = pos - bp->c_str();
*this += len;
return ptr(*bp, off, len);
}
}
iterator_impl& operator+=(size_t len) {
pos += len;
if (pos > end_ptr)
throw end_of_buffer();
return *this;
}
const char *get_pos() {
return pos;
}
const char *get_end() {
return end_ptr;
}
size_t get_offset() {
return pos - start;
}
bool end() const {
return pos == end_ptr;
}
};
class ptr {
friend class list;
protected:
raw *_raw;
unsigned _off, _len;
private:
template<bool is_const>
/*
* iterator_impl: 簡易迭代器的定義與實現(xiàn)
*/
class iterator_impl{...};
/*資源釋放*/
void release();
public:
/*
* 定義兩類迭代器
*/
using const_iterator = iterator_impl<true>;
using iterator = iterator_impl<false>;
/*
* ptr相關(guān)的構(gòu)造函數(shù)
*/
ptr() : _raw(nullptr), _off(0), _len(0) {}
/*
* 使用新的數(shù)據(jù)塊初始化此ptr
*/
ptr(ceph::unique_leakable_ptr<raw> r);
/*
* 創(chuàng)建一個大小為l的數(shù)據(jù)塊禽炬,并初始化此ptr
*/
ptr(unsigned l);
ptr(const char *d, unsigned l);
ptr(const ptr& p);
ptr(ptr&& p) noexcept;
ptr(const ptr& p, unsigned o, unsigned l);
ptr(const ptr& p, ceph::unique_leakable_ptr<raw> r);
ptr& operator= (const ptr& p);
ptr& operator= (ptr&& p) noexcept;
~ptr() {
release();
}
bool have_raw() const { return _raw ? true:false; }
ceph::unique_leakable_ptr<raw> clone();
void swap(ptr& other) noexcept;
/*
* 返回迭代器
*/
iterator begin(size_t offset=0) {
return iterator(this, offset, false);
}
const_iterator begin(size_t offset=0) const {
return const_iterator(this, offset, false);
}
const_iterator cbegin() const {
return begin();
}
const_iterator begin_deep(size_t offset=0) const {
return const_iterator(this, offset, true);
}
/*
* 判斷對齊相關(guān)操作
*/
bool is_aligned(unsigned align) const {
return ((long)c_str() & (align-1)) == 0;
}
bool is_page_aligned() const { return is_aligned(CEPH_PAGE_SIZE); }
bool is_n_align_sized(unsigned align) const
{
return (length() % align) == 0;
}
bool is_n_page_sized() const { return is_n_align_sized(CEPH_PAGE_SIZE); }
bool is_partial() const {
return have_raw() && (start() > 0 || end() < raw_length());
}
/*
* mempool相關(guān)操作
*/
int get_mempool() const;
void reassign_to_mempool(int pool);
void try_assign_to_mempool(int pool);
/*
* 數(shù)據(jù)及屬性相關(guān)的操作
*/
const char *c_str() const{
assert(_raw);
return _raw->get_data() + _off;
}
char *c_str(){
assert(_raw);
return _raw->get_data() + _off;
}
const char *end_c_str() const{
assert(_raw);
return _raw->get_data() + _off + _len;
}
char *end_c_str(){assert(_raw);return _raw->get_data() + _off + _len;}
unsigned length() const { return _len; }
unsigned offset() const { return _off; }
unsigned start() const { return _off; }
unsigned end() const { return _off + _len; }
/* raw尾部剩余空間 */
unsigned unused_tail_length() const{
{
if (_raw)
return _raw->len - (_off+_len);
else
return 0;
}
const char& operator[](unsigned n) const{return _raw->get_data()[_off + n];}
char& operator[](unsigned n){return _raw->get_data()[_off + n];}
const char *raw_c_str() const{return _raw->data;}
unsigned raw_length() const{return _raw->len;}
int raw_nref() const{return _raw->nref; }
void copy_out(unsigned o, unsigned l, char *dest) const;
unsigned wasted() const;
int cmp(const ptr& o) const;
bool is_zero() const;
// modifiers
void set_offset(unsigned o) {
assert(raw_length() >= o);
_off = o;
}
void set_length(unsigned l) {
assert(raw_length() >= l);
_len = l;
}
unsigned append(char c);
unsigned append(const char *p, unsigned l);
inline unsigned append(std::string_view s) {
return append(s.data(), s.length());
}
void copy_in(unsigned o, unsigned l, const char *src, bool crc_reset = true);
void zero(bool crc_reset = true);
void zero(unsigned o, unsigned l, bool crc_reset = true);
unsigned append_zeros(unsigned l);
};
release():
/*
* 資源釋放函數(shù):判斷raw的引用計數(shù)是否有它引:
* 引用計數(shù)為1: 減少引用計數(shù)涧卵,delete raw
* 引用計數(shù)>1: 減少引用計數(shù),_raw = nullptr;
*/
void ptr::release(){
if (_raw) {
const bool last_one = (1 == _raw->nref.load(std::memory_order_acquire));
if (likely(last_one) || --_raw->nref == 0) {
const auto* delete_raw = _raw;
_raw = nullptr;
delete delete_raw;
} else {
_raw = nullptr;
}
}
}
構(gòu)造函數(shù)ptr(raw)
:
/*
* _raw(r.release()): 使用的r的裸指針初始化_raw腹尖,清理unique_leakable_ptr
* 初始化_off, _len
* 初始化raw的引用計數(shù)為1
*/
ptr::ptr(ceph::unique_leakable_ptr<raw> r)
: _raw(r.release()),
_off(0),
_len(_raw->len)
{
_raw->nref.store(1, std::memory_order_release);
}
以下是構(gòu)造及拷貝復(fù)制構(gòu)造函數(shù)的實現(xiàn):
/* 創(chuàng)建大小為l的數(shù)據(jù)塊 */
buffer::ptr::ptr(unsigned l) : _off(0), _len(l)
{
_raw = buffer::create(l).release();
_raw->nref.store(1, std::memory_order_release);
}
/* 創(chuàng)建一個新的數(shù)據(jù)塊柳恐,并使用d初始化 */
buffer::ptr::ptr(const char *d, unsigned l) : _off(0), _len(l)
{
_raw = buffer::copy(d, l).release();
_raw->nref.store(1, std::memory_order_release);
}
/* 拷貝構(gòu)造函數(shù),共享一個數(shù)據(jù)塊 */
buffer::ptr::ptr(const ptr& p) : _raw(p._raw), _off(p._off), _len(p._len)
{
if (_raw) {
_raw->nref++;
}
}
/* 移動拷貝構(gòu)造函數(shù)热幔,清理p的數(shù)據(jù)乐设,數(shù)據(jù)塊的控制權(quán)轉(zhuǎn)移至本ptr */
buffer::ptr::ptr(ptr&& p) noexcept : _raw(p._raw), _off(p._off), _len(p._len)
{
p._raw = nullptr;
p._off = p._len = 0;
}
/* 共享p的部分數(shù)據(jù)塊,共享的內(nèi)容: [p._off+o,l] */
buffer::ptr::ptr(const ptr& p, unsigned o, unsigned l)
: _raw(p._raw), _off(p._off + o), _len(l)
{
assert(o+l <= p._len);
assert(_raw);
_raw->nref++;
}
/* 利用新的數(shù)據(jù)塊初始化ptr绎巨,實際使用數(shù)據(jù)地址與p相同 */
buffer::ptr::ptr(const ptr& p, ceph::unique_leakable_ptr<raw> r)
: _raw(r.release()),
_off(p._off),
_len(p._len)
{
_raw->nref.store(1, std::memory_order_release);
}
/* 賦值構(gòu)造函數(shù)近尚,ptr指向p的數(shù)據(jù)塊,添加引用計數(shù)场勤,釋放本地數(shù)據(jù)塊戈锻,此處代碼考慮了數(shù)據(jù)塊同一個的情況 */
buffer::ptr& buffer::ptr::operator= (const ptr& p)
{
if (p._raw) {
p._raw->nref++;
}
buffer::raw *raw = p._raw;
release();
if (raw) {
_raw = raw;
_off = p._off;
_len = p._len;
} else {
_off = _len = 0;
}
return *this;
}
/* 移動賦值構(gòu)造函數(shù)歼跟,釋放本地數(shù)據(jù)塊,指向新的數(shù)據(jù)塊 */
buffer::ptr& buffer::ptr::operator= (ptr&& p) noexcept
{
release();
buffer::raw *raw = p._raw;
if (raw) {
_raw = raw;
_off = p._off;
_len = p._len;
p._raw = nullptr;
p._off = p._len = 0;
} else {
_off = _len = 0;
}
return *this;
}
/* clone一份本地的數(shù)據(jù)塊數(shù)據(jù) */
ceph::unique_leakable_ptr<buffer::raw> buffer::ptr::clone()
{
return _raw->clone();
}
/* 交換ptr */
void buffer::ptr::swap(ptr& other) noexcept
{
raw *r = _raw;
unsigned o = _off;
unsigned l = _len;
_raw = other._raw;
_off = other._off;
_len = other._len;
other._raw = r;
other._off = o;
other._len = l;
}
/* 從ptr中拷貝數(shù)據(jù)至dest格遭,數(shù)據(jù)范圍為:start: _off+o, Len: l */
void buffer::ptr::copy_out(unsigned o, unsigned l, char *dest) const {
assert(_raw);
if (o+l > _len)
throw end_of_buffer();
char* src = _raw->data + _off + o;
maybe_inline_memcpy(dest, src, l, 8);
}
/* 未被此ptr使用的空間大小 */
unsigned buffer::ptr::wasted() const
{
return _raw->len - _len;
}
/* ptr比較函數(shù) */
int buffer::ptr::cmp(const ptr& o) const
{
int l = _len < o._len ? _len : o._len;
if (l) {
int r = memcmp(c_str(), o.c_str(), l);
if (r)
return r;
}
if (_len < o._len)
return -1;
if (_len > o._len)
return 1;
return 0;
}
/* 判斷內(nèi)容是否為0 */
bool buffer::ptr::is_zero() const
{
return mem_is_zero(c_str(), _len);
}
/*
* ptr append一個字符
* 注:append的所有操作哈街,末尾追加,使用unused_tail_length拒迅,不改變raw實際大小
*/
unsigned buffer::ptr::append(char c)
{
assert(_raw);
assert(1 <= unused_tail_length());
char* ptr = _raw->data + _off + _len;
*ptr = c;
_len++;
return _len + _off;
}
unsigned buffer::ptr::append(const char *p, unsigned l)
{
assert(_raw);
assert(l <= unused_tail_length());
char* c = _raw->data + _off + _len;
maybe_inline_memcpy(c, p, l, 32);
_len += l;
return _len + _off;
}
unsigned buffer::ptr::append_zeros(unsigned l)
{
assert(_raw);
assert(l <= unused_tail_length());
char* c = _raw->data + _off + _len;
// FIPS zeroization audit 20191115: this memset is not security related.
memset(c, 0, l);
_len += l;
return _len + _off;
}
/*
* 從src中拷貝數(shù)據(jù)至raw
*/
void buffer::ptr::copy_in(unsigned o, unsigned l, const char *src, bool crc_reset)
{
assert(_raw);
assert(o <= _len);
assert(o+l <= _len);
char* dest = _raw->data + _off + o;
if (crc_reset)
_raw->invalidate_crc();
maybe_inline_memcpy(dest, src, l, 64);
}
/*
* 重置動作
*/
void buffer::ptr::zero(bool crc_reset)
{
if (crc_reset)
_raw->invalidate_crc();
// FIPS zeroization audit 20191115: this memset is not security related.
memset(c_str(), 0, _len);
}
void buffer::ptr::zero(unsigned o, unsigned l, bool crc_reset)
{
assert(o+l <= _len);
if (crc_reset)
_raw->invalidate_crc();
// FIPS zeroization audit 20191115: this memset is not security related.
memset(c_str()+o, 0, l);
}
ptr_hook
用于連接ptr_node:
struct ptr_hook {
mutable ptr_hook* next;
ptr_hook() = default;
ptr_hook(ptr_hook* const next)
: next(next) {
}
};
ptr_node:
ptr_node的定義:
/*
* 繼承ptr_hook:主要用于buffer::list中骚秦,next鏈表
*/
class ptr_node : public ptr_hook, public ptr {
public:
struct cloner {
ptr_node* operator()(const ptr_node& clone_this);
};
/*
* 自定義unique_ptr的資源釋放函數(shù),主要釋放ptr_node本身璧微,raw的釋放ptr的析構(gòu)函數(shù)處理
*/
struct disposer {
void operator()(ptr_node* const delete_this) {
if (!dispose_if_hypercombined(delete_this)) {
delete delete_this;
}
}
};
/* 默認的析構(gòu)函數(shù) */
~ptr_node() = default;
/*
* 靜態(tài)函數(shù)作箍,ptr_node的接口函數(shù),使用raw初始化前硫,調(diào)用create_hypercombined函數(shù)
*/
static std::unique_ptr<ptr_node, disposer> create(ceph::unique_leakable_ptr<raw> r) {
return create_hypercombined(std::move(r));
}
/*
* 重載函數(shù)胞得,創(chuàng)建長度為l的數(shù)據(jù)塊,buffer::create創(chuàng)建unqiue_ptr 的raw塊开瞭,調(diào)用create_hypercombined
*/
static std::unique_ptr<ptr_node, disposer> create(const unsigned l) {
return create_hypercombined(buffer::create(l));
}
/*
* 可變參數(shù)函數(shù)接口懒震,調(diào)用ptr_node構(gòu)造函數(shù)
*/
template <class... Args>
static std::unique_ptr<ptr_node, disposer> create(Args&&... args) {
return std::unique_ptr<ptr_node, disposer>(new ptr_node(std::forward<Args>(args)...));
}
/* ptr_node構(gòu)造接口 */
static ptr_node* copy_hypercombined(const ptr_node& copy_this);
private:
/*
* 私有構(gòu)造函數(shù)
* 可變參數(shù)的構(gòu)造函數(shù)的入口
*/
template <class... Args>
ptr_node(Args&&... args) : ptr(std::forward<Args>(args)...) {}
ptr_node(const ptr_node&) = default;
/*
* 禁止ptr的拷貝以及移動拷貝構(gòu)造函數(shù)
* 禁止ptr_node的賦值及移動賦值構(gòu)造函數(shù)
* 禁止swap功能
*/
ptr& operator= (const ptr& p) = delete;
ptr& operator= (ptr&& p) noexcept = delete;
ptr_node& operator= (const ptr_node& p) = delete;
ptr_node& operator= (ptr_node&& p) noexcept = delete;
void swap(ptr& other) noexcept = delete;
void swap(ptr_node& other) noexcept = delete;
/*
* 判斷是否使用hypercombined
*/
static bool dispose_if_hypercombined(ptr_node* delete_this);
static std::unique_ptr<ptr_node, disposer> create_hypercombined(ceph::unique_leakable_ptr<raw> r);
};
/*
* 判斷是否使用hypercombined方式創(chuàng)建的raw
*/
bool buffer::ptr_node::dispose_if_hypercombined(buffer::ptr_node* const delete_this)
{
const bool is_hypercombined = static_cast<void*>(delete_this) == \
static_cast<void*>(&delete_this->_raw->bptr_storage);
if (is_hypercombined) {
delete_this->~ptr_node();
}
return is_hypercombined;
}
/*
* 基于raw創(chuàng)建ptr_node
*/
std::unique_ptr<buffer::ptr_node, buffer::ptr_node::disposer> buffer::ptr_node::create_hypercombined(ceph::unique_leakable_ptr<buffer::raw> r)
{
return std::unique_ptr<buffer::ptr_node, buffer::ptr_node::disposer>(new ptr_node(std::move(r)));
}
/*
* clone ptr_node
*/
buffer::ptr_node* buffer::ptr_node::cloner::operator()(
const buffer::ptr_node& clone_this)
{
return new ptr_node(clone_this);
}