1
0
Fork 0
arangodb/arangod/Aql/SharedAqlItemBlockPtr.h

214 lines
6.5 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2019 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Tobias Gödderz
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGOD_AQL_SHAREDAQLITEMBLOCKPTR_H
#define ARANGOD_AQL_SHAREDAQLITEMBLOCKPTR_H
#include "Aql/AqlItemBlock.h"
namespace arangodb {
namespace aql {
class SharedAqlItemBlockPtr {
public:
inline explicit SharedAqlItemBlockPtr(AqlItemBlock* aqlItemBlock) noexcept;
// allow implicit cast from nullptr:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
inline SharedAqlItemBlockPtr(std::nullptr_t) noexcept;
inline SharedAqlItemBlockPtr() noexcept;
inline ~SharedAqlItemBlockPtr() noexcept;
inline SharedAqlItemBlockPtr(SharedAqlItemBlockPtr const& other) noexcept;
inline SharedAqlItemBlockPtr(SharedAqlItemBlockPtr&& other) noexcept;
inline SharedAqlItemBlockPtr& operator=(SharedAqlItemBlockPtr const& other) noexcept;
inline SharedAqlItemBlockPtr& operator=(SharedAqlItemBlockPtr&& other) noexcept;
inline SharedAqlItemBlockPtr& operator=(std::nullptr_t) noexcept;
inline AqlItemBlock& operator*() noexcept;
inline AqlItemBlock* operator->() noexcept;
inline AqlItemBlock const& operator*() const noexcept;
inline AqlItemBlock const* operator->() const noexcept;
inline AqlItemBlock* get() const noexcept;
inline void reset(AqlItemBlock*) noexcept;
inline void swap(SharedAqlItemBlockPtr& other) noexcept;
inline bool operator==(std::nullptr_t) const noexcept;
inline bool operator!=(std::nullptr_t) const noexcept;
inline bool operator==(SharedAqlItemBlockPtr const&) const noexcept;
inline bool operator!=(SharedAqlItemBlockPtr const&) const noexcept;
private:
inline void incrRefCount() const noexcept;
// decrRefCount returns ("frees") _aqlItemBlock if the ref count reaches 0
inline void decrRefCount() noexcept;
AqlItemBlockManager& itemBlockManager() const noexcept;
void returnBlock() noexcept;
private:
AqlItemBlock* _aqlItemBlock;
};
arangodb::aql::SharedAqlItemBlockPtr::SharedAqlItemBlockPtr(arangodb::aql::AqlItemBlock* aqlItemBlock) noexcept
: _aqlItemBlock(aqlItemBlock) {
// This constructor should only be used for fresh AqlItemBlocks in the
// AqlItemBlockManager. All other places should already have a
// SharedAqlItemBlockPtr.
TRI_ASSERT(aqlItemBlock->getRefCount() == 0);
incrRefCount();
}
arangodb::aql::SharedAqlItemBlockPtr::SharedAqlItemBlockPtr(std::nullptr_t) noexcept
: _aqlItemBlock(nullptr) {}
arangodb::aql::SharedAqlItemBlockPtr::SharedAqlItemBlockPtr() noexcept
: _aqlItemBlock(nullptr) {}
SharedAqlItemBlockPtr::~SharedAqlItemBlockPtr() noexcept {
decrRefCount();
}
SharedAqlItemBlockPtr::SharedAqlItemBlockPtr(SharedAqlItemBlockPtr const& other) noexcept
: _aqlItemBlock(other._aqlItemBlock) {
TRI_ASSERT(this != &other);
incrRefCount();
}
SharedAqlItemBlockPtr::SharedAqlItemBlockPtr(SharedAqlItemBlockPtr&& other) noexcept
: _aqlItemBlock(other._aqlItemBlock) {
TRI_ASSERT(this != &other);
other._aqlItemBlock = nullptr;
}
SharedAqlItemBlockPtr& SharedAqlItemBlockPtr::operator=(SharedAqlItemBlockPtr const& other) noexcept {
TRI_ASSERT(this != &other);
decrRefCount();
_aqlItemBlock = other._aqlItemBlock;
incrRefCount();
return *this;
}
SharedAqlItemBlockPtr& SharedAqlItemBlockPtr::operator=(SharedAqlItemBlockPtr&& other) noexcept {
TRI_ASSERT(this != &other);
decrRefCount();
_aqlItemBlock = other._aqlItemBlock;
other._aqlItemBlock = nullptr;
return *this;
}
SharedAqlItemBlockPtr& SharedAqlItemBlockPtr::operator=(std::nullptr_t) noexcept {
decrRefCount();
_aqlItemBlock = nullptr;
return *this;
}
AqlItemBlock& SharedAqlItemBlockPtr::operator*() noexcept {
TRI_ASSERT(_aqlItemBlock != nullptr);
TRI_ASSERT(_aqlItemBlock->getRefCount() > 0);
return *_aqlItemBlock;
}
AqlItemBlock* SharedAqlItemBlockPtr::operator->() noexcept {
TRI_ASSERT(_aqlItemBlock != nullptr);
TRI_ASSERT(_aqlItemBlock->getRefCount() > 0);
return _aqlItemBlock;
}
AqlItemBlock const& SharedAqlItemBlockPtr::operator*() const noexcept {
TRI_ASSERT(_aqlItemBlock != nullptr);
TRI_ASSERT(_aqlItemBlock->getRefCount() > 0);
return *_aqlItemBlock;
}
AqlItemBlock const* SharedAqlItemBlockPtr::operator->() const noexcept {
TRI_ASSERT(_aqlItemBlock != nullptr);
TRI_ASSERT(_aqlItemBlock->getRefCount() > 0);
return _aqlItemBlock;
}
void SharedAqlItemBlockPtr::incrRefCount() const noexcept {
if (_aqlItemBlock != nullptr) {
_aqlItemBlock->incrRefCount();
}
}
bool SharedAqlItemBlockPtr::operator==(std::nullptr_t) const noexcept {
return _aqlItemBlock == nullptr;
}
bool SharedAqlItemBlockPtr::operator!=(std::nullptr_t) const noexcept {
return _aqlItemBlock != nullptr;
}
bool SharedAqlItemBlockPtr::operator==(SharedAqlItemBlockPtr const& other) const noexcept {
return _aqlItemBlock == other._aqlItemBlock;
}
bool SharedAqlItemBlockPtr::operator!=(SharedAqlItemBlockPtr const& other) const noexcept {
return _aqlItemBlock != other._aqlItemBlock;
}
AqlItemBlock* SharedAqlItemBlockPtr::get() const noexcept {
TRI_ASSERT(_aqlItemBlock == nullptr || _aqlItemBlock->getRefCount() > 0);
return _aqlItemBlock;
}
void SharedAqlItemBlockPtr::reset(AqlItemBlock* other) noexcept {
TRI_ASSERT(_aqlItemBlock != other);
decrRefCount();
_aqlItemBlock = other;
incrRefCount();
}
void SharedAqlItemBlockPtr::swap(SharedAqlItemBlockPtr& other) noexcept {
AqlItemBlock* tmp = _aqlItemBlock;
_aqlItemBlock = other._aqlItemBlock;
other._aqlItemBlock = tmp;
}
void arangodb::aql::SharedAqlItemBlockPtr::decrRefCount() noexcept {
if (_aqlItemBlock != nullptr) {
_aqlItemBlock->decrRefCount();
if (_aqlItemBlock->getRefCount() == 0) {
returnBlock();
}
}
}
} // namespace aql
} // namespace arangodb
#endif // ARANGOD_AQL_SHAREDAQLITEMBLOCKPTR_H