From 7bc1db5c967eb1fa59e210c3d393468951683239 Mon Sep 17 00:00:00 2001 From: zuochunwei Date: Sat, 1 Jan 2022 08:27:19 +0800 Subject: [PATCH] cow refactor: giveup using boost --- be/src/vec/common/cow.h | 172 ++++++++++++++++++++---- be/src/vec/exec/vanalytic_eval_node.cpp | 2 +- be/src/vec/functions/function_cast.h | 2 +- 3 files changed, 146 insertions(+), 30 deletions(-) diff --git a/be/src/vec/common/cow.h b/be/src/vec/common/cow.h index dbee2b97cd8eb9..08edb891649174 100644 --- a/be/src/vec/common/cow.h +++ b/be/src/vec/common/cow.h @@ -24,6 +24,7 @@ #include #include + /** Copy-on-write shared ptr. * Allows to work with shared immutable objects and sometimes unshare and mutate you own unique copy. * @@ -92,36 +93,158 @@ * to use std::unique_ptr for it somehow. */ template -class COW : public boost::intrusive_ref_counter { -private: +class COW { + std::atomic_uint ref_counter; + +protected: + COW() : ref_counter(0) {} + + COW(COW const&) : ref_counter(0) {} + + COW& operator=(COW const&) { + return *this; + } + + unsigned int use_count() const { + return ref_counter.load(); + } + + void add_ref() { + ++ref_counter; + } + + void release_ref() { + if (--ref_counter == 0) { + delete static_cast(this); + } + } + Derived* derived() { return static_cast(this); } + const Derived* derived() const { return static_cast(this); } template - class IntrusivePtr : public boost::intrusive_ptr { + class intrusive_ptr { public: - using boost::intrusive_ptr::intrusive_ptr; + intrusive_ptr() : t(nullptr) {} + + intrusive_ptr(T* t, bool add_ref=true) : t(t) { + if (t && add_ref) ((std::remove_const_t*)t)->add_ref(); + } + + template + intrusive_ptr(intrusive_ptr const& rhs) : t(rhs.get()) { + if (t) ((std::remove_const_t*)t)->add_ref(); + } + + intrusive_ptr(intrusive_ptr const& rhs) : t(rhs.get()) { + if (t) ((std::remove_const_t*)t)->add_ref(); + } + + ~intrusive_ptr() { + if (t) ((std::remove_const_t*)t)->release_ref(); + } + + template + intrusive_ptr& operator=(intrusive_ptr const& rhs) { + intrusive_ptr(rhs).swap(*this); + return *this; + } + + intrusive_ptr(intrusive_ptr&& rhs) : t(rhs.t) { + rhs.t = nullptr; + } + + intrusive_ptr& operator=(intrusive_ptr&& rhs) { + intrusive_ptr(static_cast(rhs)).swap(*this); + return *this; + } + + template friend class intrusive_ptr; + + template + intrusive_ptr(intrusive_ptr&& rhs) : t(rhs.t) { + rhs.t = nullptr; + } + + template + intrusive_ptr& operator=(intrusive_ptr&& rhs) { + intrusive_ptr(static_cast&&>(rhs)).swap(*this); + return *this; + } + + intrusive_ptr& operator=(intrusive_ptr const& rhs) { + intrusive_ptr(rhs).swap(*this); + return *this; + } + + intrusive_ptr& operator=(T* rhs) { + intrusive_ptr(rhs).swap(*this); + return *this; + } + + void reset() { + intrusive_ptr().swap(*this); + } + + void reset(T* rhs) { + intrusive_ptr(rhs).swap(*this); + } + + void reset(T* rhs, bool add_ref) { + intrusive_ptr(rhs, add_ref).swap(*this); + } + + T* get() const { + return t; + } + + T* detach() { + T* ret = t; + t = nullptr; + return ret; + } + + void swap(intrusive_ptr& rhs) { + T* tmp = t; + t = rhs.t; + rhs.t = tmp; + } + + T& operator*() const& { + return *t; + } - T& operator*() const& { return boost::intrusive_ptr::operator*(); } T&& operator*() const&& { - return const_cast::type&&>( - *boost::intrusive_ptr::get()); + return const_cast&&>(*t); + } + + T* operator->() const { + return t; + } + + operator bool() const { + return t != nullptr; + } + + operator T*() const { + return t; } + + private: + T* t; }; protected: template - class mutable_ptr : public IntrusivePtr { + class mutable_ptr : public intrusive_ptr { private: - using Base = IntrusivePtr; + using Base = intrusive_ptr; - template - friend class COW; - template - friend class COWHelper; + template friend class COW; + template friend class COWHelper; explicit mutable_ptr(T* ptr) : Base(ptr) {} - public: /// Copy: not possible. mutable_ptr(const mutable_ptr&) = delete; @@ -144,17 +267,14 @@ class COW : public boost::intrusive_ref_counter { protected: template - class immutable_ptr : public IntrusivePtr { + class immutable_ptr : public intrusive_ptr { private: - using Base = IntrusivePtr; + using Base = intrusive_ptr; - template - friend class COW; - template - friend class COWHelper; + template friend class COW; + template friend class COWHelper; explicit immutable_ptr(const T* ptr) : Base(ptr) {} - public: /// Copy from immutable ptr: ok. immutable_ptr(const immutable_ptr&) = default; @@ -198,8 +318,8 @@ class COW : public boost::intrusive_ref_counter { } public: - Ptr get_ptr() const { return static_cast(derived()); } - MutablePtr get_ptr() { return static_cast(derived()); } + Ptr get_ptr() const { return Ptr(derived()); } + MutablePtr get_ptr() { return MutablePtr(derived()); } protected: MutablePtr shallow_mutate() const { @@ -294,10 +414,6 @@ class COW : public boost::intrusive_ref_counter { */ template class COWHelper : public Base { -private: - Derived* derived() { return static_cast(this); } - const Derived* derived() const { return static_cast(this); } - public: using Ptr = typename Base::template immutable_ptr; using MutablePtr = typename Base::template mutable_ptr; @@ -313,7 +429,7 @@ class COWHelper : public Base { } typename Base::MutablePtr clone() const override { - return typename Base::MutablePtr(new Derived(*derived())); + return typename Base::MutablePtr(new Derived(static_cast(*this))); } protected: diff --git a/be/src/vec/exec/vanalytic_eval_node.cpp b/be/src/vec/exec/vanalytic_eval_node.cpp index e828a73e598f9e..4d69716216c7cb 100644 --- a/be/src/vec/exec/vanalytic_eval_node.cpp +++ b/be/src/vec/exec/vanalytic_eval_node.cpp @@ -391,7 +391,7 @@ BlockRowPos VAnalyticEvalNode::_compare_row_to_find_end(int idx, BlockRowPos sta } //check whether need get column again, maybe same as first init - if (start_column != start_next_block_column) { + if (start_column.get() != start_next_block_column.get()) { start_init_row_num = 0; start.block_num = start_block_num; start_column = _input_blocks[start.block_num].get_by_position(idx).column; diff --git a/be/src/vec/functions/function_cast.h b/be/src/vec/functions/function_cast.h index 03856b9fce8466..0aa93d0df5b281 100644 --- a/be/src/vec/functions/function_cast.h +++ b/be/src/vec/functions/function_cast.h @@ -1110,7 +1110,7 @@ class FunctionCast final : public IFunctionBase { const auto& tmp_res = tmp_block.get_by_position(tmp_res_index); /// May happen in fuzzy tests. For debug purpose. - if (!tmp_res.column) { + if (!tmp_res.column.get()) { return Status::RuntimeError(fmt::format( "Couldn't convert {} to {} in prepare_remove_nullable wrapper.", block.get_by_position(arguments[0]).type->get_name(),