Replace debug_assert, permanent_assert with DCHECK/CHECK

Summary:
Phase 2.

Phase 3.

Phase 4.

Phase 5.

Complete refactor.

Reviewers: florijan, mislav.bradac

Reviewed By: mislav.bradac

Subscribers: mislav.bradac, pullbot

Differential Revision: https://phabricator.memgraph.io/D895
This commit is contained in:
Dominik Gleich 2017-10-11 13:19:10 +02:00
parent 4f7f59f9fc
commit fcecb14545
81 changed files with 612 additions and 692 deletions

View File

@ -3,9 +3,10 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "memory/allocator.hpp" #include "memory/allocator.hpp"
#include "memory/maker.hpp" #include "memory/maker.hpp"
#include "utils/assert.hpp"
#include "utils/measure_time.hpp" #include "utils/measure_time.hpp"
struct TestStructure { struct TestStructure {
@ -50,9 +51,9 @@ int main(void) {
} }
}); });
std::cout << "Fast (fast allocator): " << elapsed_fast << "ms" << std::endl; std::cout << "Fast (fast allocator): " << elapsed_fast << "ms" << std::endl;
permanent_assert(elapsed_fast < elapsed_classic, CHECK(elapsed_fast < elapsed_classic)
"Custom fast allocator " << "Custom fast allocator "
"has to perform faster on simple array allocation"); "has to perform faster on simple array allocation";
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "utils/assert.hpp" #include "glog/logging.h"
// Like option just for pointers. More efficent than option. // Like option just for pointers. More efficent than option.
template <class T> template <class T>
@ -12,7 +12,7 @@ class OptionPtr {
bool is_present() { return ptr != nullptr; } bool is_present() { return ptr != nullptr; }
T *get() { T *get() {
debug_assert(is_present(), "Data is not present."); DCHECK(is_present()) << "Data is not present.";
return ptr; return ptr;
} }

View File

@ -3,8 +3,9 @@
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include "glog/logging.h"
#include "option_ptr.hpp" #include "option_ptr.hpp"
#include "utils/assert.hpp"
#include "utils/crtp.hpp" #include "utils/crtp.hpp"
// RobinHood base. // RobinHood base.
@ -95,20 +96,20 @@ class RhBase {
IteratorBase(IteratorBase &&) = default; IteratorBase(IteratorBase &&) = default;
D *operator*() { D *operator*() {
debug_assert(index < map->capacity && map->array[index].valid(), DCHECK(index < map->capacity && map->array[index].valid())
"Either index is invalid or data is not valid."); << "Either index is invalid or data is not valid.";
return map->array[index].ptr(); return map->array[index].ptr();
} }
D *operator->() { D *operator->() {
debug_assert(index < map->capacity && map->array[index].valid(), DCHECK(index < map->capacity && map->array[index].valid())
"Either index is invalid or data is not valid."); << "Either index is invalid or data is not valid.";
return map->array[index].ptr(); return map->array[index].ptr();
} }
It &operator++() { It &operator++() {
debug_assert(index < map->capacity && map->array[index].valid(), DCHECK(index < map->capacity && map->array[index].valid())
"Either index is invalid or data is not valid."); << "Either index is invalid or data is not valid.";
auto mask = map->mask(); auto mask = map->mask();
do { do {
advanced++; advanced++;
@ -298,14 +299,14 @@ class RhBase {
* K must be comparable with ==. * K must be comparable with ==.
* HashMap behaves as if it isn't owner of entries. * HashMap behaves as if it isn't owner of entries.
* BE CAREFUL - this structure assumes that the pointer to Data is 8-alligned! * BE CAREFUL - this structure assumes that the pointer to Data is 8-alligned!
*/ */
template <class K, class D, size_t init_size_pow2 = 2> template <class K, class D, size_t init_size_pow2 = 2>
class RhHashMap : public RhBase<K, D, init_size_pow2> { class RhHashMap : public RhBase<K, D, init_size_pow2> {
typedef RhBase<K, D, init_size_pow2> base; typedef RhBase<K, D, init_size_pow2> base;
using base::array; using base::array;
using base::index;
using base::capacity; using base::capacity;
using base::count; using base::count;
using base::index;
using typename base::Combined; using typename base::Combined;
void increase_size() { void increase_size() {
@ -357,8 +358,8 @@ class RhHashMap : public RhBase<K, D, init_size_pow2> {
// Inserts element. Returns true if element wasn't in the map. // Inserts element. Returns true if element wasn't in the map.
bool insert(D *data) { bool insert(D *data) {
permanent_assert(!(((uint64_t) static_cast<void *>(data) & 7)), CHECK(!(((uint64_t) static_cast<void *>(data) & 7)))
"Data is not 8-alligned."); << "Data is not 8-alligned.";
if (count < capacity) { if (count < capacity) {
size_t mask = this->mask(); size_t mask = this->mask();
auto key = std::ref(data->get_key()); auto key = std::ref(data->get_key());

View File

@ -5,9 +5,10 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "communication/bolt/v1/constants.hpp" #include "communication/bolt/v1/constants.hpp"
#include "io/network/stream_buffer.hpp" #include "io/network/stream_buffer.hpp"
#include "utils/assert.hpp"
#include "utils/bswap.hpp" #include "utils/bswap.hpp"
namespace communication::bolt { namespace communication::bolt {
@ -54,7 +55,7 @@ class Buffer {
*/ */
void Written(size_t len) { void Written(size_t len) {
size_ += len; size_ += len;
debug_assert(size_ <= Size, "Written more than storage has space!"); DCHECK(size_ <= Size) << "Written more than storage has space!";
} }
/** /**
@ -65,7 +66,7 @@ class Buffer {
* the buffer * the buffer
*/ */
void Shift(size_t len) { void Shift(size_t len) {
debug_assert(len <= size_, "Tried to shift more data than the buffer has!"); DCHECK(len <= size_) << "Tried to shift more data than the buffer has!";
memmove(data_, data_ + len, size_ - len); memmove(data_, data_ + len, size_ - len);
size_ -= len; size_ -= len;
} }
@ -90,4 +91,4 @@ class Buffer {
uint8_t data_[Size]; uint8_t data_[Size];
size_t size_{0}; size_t size_{0};
}; };
} } // namespace communication::bolt

View File

@ -1,3 +1,5 @@
#include "glog/logging.h"
#include "communication/bolt/v1/decoder/decoded_value.hpp" #include "communication/bolt/v1/decoder/decoded_value.hpp"
namespace communication::bolt { namespace communication::bolt {
@ -74,7 +76,7 @@ DecodedValue::DecodedValue(const DecodedValue &other) : type_(other.type_) {
new (&path_v) DecodedPath(other.path_v); new (&path_v) DecodedPath(other.path_v);
return; return;
} }
permanent_fail("Unsupported DecodedValue::Type"); LOG(FATAL) << "Unsupported DecodedValue::Type";
} }
DecodedValue &DecodedValue::operator=(const DecodedValue &other) { DecodedValue &DecodedValue::operator=(const DecodedValue &other) {
@ -117,7 +119,7 @@ DecodedValue &DecodedValue::operator=(const DecodedValue &other) {
new (&path_v) DecodedPath(other.path_v); new (&path_v) DecodedPath(other.path_v);
return *this; return *this;
} }
permanent_fail("Unsupported DecodedValue::Type"); LOG(FATAL) << "Unsupported DecodedValue::Type";
} }
return *this; return *this;
} }
@ -160,7 +162,7 @@ DecodedValue::~DecodedValue() {
path_v.~DecodedPath(); path_v.~DecodedPath();
return; return;
} }
permanent_fail("Unsupported DecodedValue::Type"); LOG(FATAL) << "Unsupported DecodedValue::Type";
} }
DecodedValue::operator query::TypedValue() const { DecodedValue::operator query::TypedValue() const {
@ -224,8 +226,7 @@ std::ostream &operator<<(std::ostream &os, const DecodedUnboundedEdge &edge) {
std::ostream &operator<<(std::ostream &os, const DecodedPath &path) { std::ostream &operator<<(std::ostream &os, const DecodedPath &path) {
os << path.vertices[0]; os << path.vertices[0];
debug_assert(path.indices.size() % 2 == 0, DCHECK(path.indices.size() % 2 == 0) << "Must have even number of indices";
"Must have even number of indices");
for (auto it = path.indices.begin(); it != path.indices.end();) { for (auto it = path.indices.begin(); it != path.indices.end();) {
auto edge_ind = *it++; auto edge_ind = *it++;
auto vertex_ind = *it++; auto vertex_ind = *it++;
@ -276,7 +277,7 @@ std::ostream &operator<<(std::ostream &os, const DecodedValue &value) {
case DecodedValue::Type::Path: case DecodedValue::Type::Path:
return os << value.ValuePath(); return os << value.ValuePath();
} }
permanent_fail("Unsupported DecodedValue::Type"); LOG(FATAL) << "Unsupported DecodedValue::Type";
} }
std::ostream &operator<<(std::ostream &os, const DecodedValue::Type type) { std::ostream &operator<<(std::ostream &os, const DecodedValue::Type type) {
@ -304,6 +305,6 @@ std::ostream &operator<<(std::ostream &os, const DecodedValue::Type type) {
case DecodedValue::Type::Path: case DecodedValue::Type::Path:
return os << "path"; return os << "path";
} }
permanent_fail("Unsupported DecodedValue::Type"); LOG(FATAL) << "Unsupported DecodedValue::Type";
} }
} }

View File

@ -168,7 +168,7 @@ class Decoder {
private: private:
bool ReadNull(const Marker &marker, DecodedValue *data) { bool ReadNull(const Marker &marker, DecodedValue *data) {
DLOG(INFO) << "[ReadNull] Start"; DLOG(INFO) << "[ReadNull] Start";
debug_assert(marker == Marker::Null, "Received invalid marker!"); DCHECK(marker == Marker::Null) << "Received invalid marker!";
*data = DecodedValue(); *data = DecodedValue();
DLOG(INFO) << "[ReadNull] Success"; DLOG(INFO) << "[ReadNull] Success";
return true; return true;
@ -176,8 +176,8 @@ class Decoder {
bool ReadBool(const Marker &marker, DecodedValue *data) { bool ReadBool(const Marker &marker, DecodedValue *data) {
DLOG(INFO) << "[ReadBool] Start"; DLOG(INFO) << "[ReadBool] Start";
debug_assert(marker == Marker::False || marker == Marker::True, DCHECK(marker == Marker::False || marker == Marker::True)
"Received invalid marker!"); << "Received invalid marker!";
if (marker == Marker::False) { if (marker == Marker::False) {
*data = DecodedValue(false); *data = DecodedValue(false);
} else { } else {
@ -243,7 +243,7 @@ class Decoder {
uint64_t value; uint64_t value;
double ret; double ret;
DLOG(INFO) << "[ReadDouble] Start"; DLOG(INFO) << "[ReadDouble] Start";
debug_assert(marker == Marker::Float64, "Received invalid marker!"); DCHECK(marker == Marker::Float64) << "Received invalid marker!";
if (!buffer_.Read(reinterpret_cast<uint8_t *>(&value), sizeof(value))) { if (!buffer_.Read(reinterpret_cast<uint8_t *>(&value), sizeof(value))) {
DLOG(WARNING) << "[ReadDouble] Missing data!"; DLOG(WARNING) << "[ReadDouble] Missing data!";
return false; return false;
@ -523,7 +523,8 @@ class Decoder {
} }
for (const auto &vertex : dv.ValueList()) { for (const auto &vertex : dv.ValueList()) {
if (vertex.type() != DecodedValue::Type::Vertex) { if (vertex.type() != DecodedValue::Type::Vertex) {
DLOG(WARNING) << "[ReadPath] Received a '" << vertex.type() << "' element in the vertices list!"; DLOG(WARNING) << "[ReadPath] Received a '" << vertex.type()
<< "' element in the vertices list!";
return false; return false;
} }
path.vertices.emplace_back(vertex.ValueVertex()); path.vertices.emplace_back(vertex.ValueVertex());
@ -536,7 +537,8 @@ class Decoder {
} }
for (const auto &edge : dv.ValueList()) { for (const auto &edge : dv.ValueList()) {
if (edge.type() != DecodedValue::Type::UnboundedEdge) { if (edge.type() != DecodedValue::Type::UnboundedEdge) {
DLOG(WARNING) << "[ReadPath] Received a '" << edge.type() << "' element in the edges list!"; DLOG(WARNING) << "[ReadPath] Received a '" << edge.type()
<< "' element in the edges list!";
return false; return false;
} }
path.edges.emplace_back(edge.ValueUnboundedEdge()); path.edges.emplace_back(edge.ValueUnboundedEdge());
@ -549,7 +551,8 @@ class Decoder {
} }
for (const auto &index : dv.ValueList()) { for (const auto &index : dv.ValueList()) {
if (index.type() != DecodedValue::Type::Int) { if (index.type() != DecodedValue::Type::Int) {
DLOG(WARNING) << "[ReadPath] Received a '" << index.type() << "' element in the indices list (expected an int)!"; DLOG(WARNING) << "[ReadPath] Received a '" << index.type()
<< "' element in the indices list (expected an int)!";
return false; return false;
} }
path.indices.emplace_back(index.ValueInt()); path.indices.emplace_back(index.ValueInt());
@ -562,4 +565,4 @@ class Decoder {
return true; return true;
} }
}; };
} } // namespace communication::bolt

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "glog/logging.h"
#include "io/network/epoll.hpp" #include "io/network/epoll.hpp"
#include "io/network/socket.hpp" #include "io/network/socket.hpp"
@ -60,8 +62,8 @@ class Session {
} }
~Session() { ~Session() {
debug_assert(!db_accessor_, DCHECK(!db_accessor_)
"Transaction should have already be closed in Close"); << "Transaction should have already be closed in Close";
} }
/** /**
@ -167,7 +169,7 @@ class Session {
* Commits associated transaction. * Commits associated transaction.
*/ */
void Commit() { void Commit() {
debug_assert(db_accessor_, "Commit called and there is no transaction"); DCHECK(db_accessor_) << "Commit called and there is no transaction";
db_accessor_->Commit(); db_accessor_->Commit();
db_accessor_ = nullptr; db_accessor_ = nullptr;
} }
@ -176,7 +178,7 @@ class Session {
* Aborts associated transaction. * Aborts associated transaction.
*/ */
void Abort() { void Abort() {
debug_assert(db_accessor_, "Abort called and there is no transaction"); DCHECK(db_accessor_) << "Abort called and there is no transaction";
db_accessor_->Abort(); db_accessor_->Abort();
db_accessor_ = nullptr; db_accessor_ = nullptr;
} }
@ -215,4 +217,4 @@ class Session {
Close(); Close();
} }
}; };
} } // namespace communication::bolt

View File

@ -55,7 +55,7 @@ State StateErrorRun(Session &session, State state) {
} else if (state == State::ErrorWaitForRollback) { } else if (state == State::ErrorWaitForRollback) {
return State::WaitForRollback; return State::WaitForRollback;
} else { } else {
permanent_assert(false, "Shouldn't happen"); LOG(FATAL) << "Shouldn't happen";
} }
} else { } else {
uint8_t value = underlying_cast(marker); uint8_t value = underlying_cast(marker);
@ -89,4 +89,4 @@ State StateErrorRun(Session &session, State state) {
return state; return state;
} }
} }
} } // namespace communication::bolt

View File

@ -63,8 +63,8 @@ State HandleRun(Session &session, State state, Marker marker) {
return State::Close; return State::Close;
} }
debug_assert(!session.encoder_buffer_.HasData(), DCHECK(!session.encoder_buffer_.HasData())
"There should be no data to write in this state"); << "There should be no data to write in this state";
DLOG(INFO) << fmt::format("[Run] '{}'", query.ValueString()); DLOG(INFO) << fmt::format("[Run] '{}'", query.ValueString());
bool in_explicit_transaction = false; bool in_explicit_transaction = false;
@ -313,4 +313,4 @@ State StateExecutingRun(Session &session, State state) {
return State::Close; return State::Close;
} }
} }
} } // namespace communication::bolt

View File

@ -18,8 +18,8 @@ namespace communication::bolt {
*/ */
template <typename Session> template <typename Session>
State StateInitRun(Session &session) { State StateInitRun(Session &session) {
debug_assert(!session.encoder_buffer_.HasData(), DCHECK(!session.encoder_buffer_.HasData())
"There should be no data to write in this state"); << "There should be no data to write in this state";
DLOG(INFO) << "Parsing message"; DLOG(INFO) << "Parsing message";
Marker marker; Marker marker;
@ -68,4 +68,4 @@ State StateInitRun(Session &session) {
return State::Idle; return State::Idle;
} }
} } // namespace communication::bolt

View File

@ -2,8 +2,8 @@
#include <map> #include <map>
#include "glog/logging.h"
#include "query/typed_value.hpp" #include "query/typed_value.hpp"
#include "utils/assert.hpp"
/** /**
* A mocker for the data output record stream. * A mocker for the data output record stream.
@ -20,33 +20,33 @@ class ResultStreamFaker {
ResultStreamFaker &operator=(ResultStreamFaker &&) = default; ResultStreamFaker &operator=(ResultStreamFaker &&) = default;
void Header(const std::vector<std::string> &fields) { void Header(const std::vector<std::string> &fields) {
debug_assert(current_state_ == State::Start, DCHECK(current_state_ == State::Start)
"Headers can only be written in the beginning"); << "Headers can only be written in the beginning";
header_ = fields; header_ = fields;
current_state_ = State::WritingResults; current_state_ = State::WritingResults;
} }
void Result(const std::vector<query::TypedValue> &values) { void Result(const std::vector<query::TypedValue> &values) {
debug_assert(current_state_ == State::WritingResults, DCHECK(current_state_ == State::WritingResults)
"Can't accept results before header nor after summary"); << "Can't accept results before header nor after summary";
results_.push_back(values); results_.push_back(values);
} }
void Summary(const std::map<std::string, query::TypedValue> &summary) { void Summary(const std::map<std::string, query::TypedValue> &summary) {
debug_assert(current_state_ != State::Done, "Can only send a summary once"); DCHECK(current_state_ != State::Done) << "Can only send a summary once";
summary_ = summary; summary_ = summary;
current_state_ = State::Done; current_state_ = State::Done;
} }
const auto &GetHeader() const { const auto &GetHeader() const {
debug_assert(current_state_ != State::Start, "Header not written"); DCHECK(current_state_ != State::Start) << "Header not written";
return header_; return header_;
} }
const auto &GetResults() const { return results_; } const auto &GetResults() const { return results_; }
const auto &GetSummary() const { const auto &GetSummary() const {
debug_assert(current_state_ == State::Done, "Summary not written"); DCHECK(current_state_ == State::Done) << "Summary not written";
return summary_; return summary_;
} }

View File

@ -87,8 +87,7 @@ class Server {
: io::network::BaseListener(socket), server_(server) {} : io::network::BaseListener(socket), server_(server) {}
void OnData() { void OnData() {
debug_assert(server_.idx_ < server_.workers_.size(), DCHECK(server_.idx_ < server_.workers_.size()) << "Invalid worker id.";
"Invalid worker id.");
DLOG(INFO) << "On connect"; DLOG(INFO) << "On connect";
auto connection = AcceptConnection(); auto connection = AcceptConnection();
if (UNLIKELY(!connection)) { if (UNLIKELY(!connection)) {

View File

@ -2,9 +2,9 @@
#include <atomic> #include <atomic>
#include "glog/logging.h"
#include "threading/sync/lockable.hpp" #include "threading/sync/lockable.hpp"
#include "threading/sync/spinlock.hpp" #include "threading/sync/spinlock.hpp"
#include "utils/assert.hpp"
/** /**
* A sequentially ordered non-unique lock-free concurrent collection of bits. * A sequentially ordered non-unique lock-free concurrent collection of bits.
@ -36,17 +36,17 @@ class DynamicBitset {
static constexpr size_t kSize = sizeof(block_t) * 8; static constexpr size_t kSize = sizeof(block_t) * 8;
block_t at(size_t k, size_t n) const { block_t at(size_t k, size_t n) const {
debug_assert(k + n - 1 < kSize, "Invalid index."); DCHECK(k + n - 1 < kSize) << "Invalid index.";
return (block_.load() >> k) & bitmask(n); return (block_.load() >> k) & bitmask(n);
} }
void set(size_t k, size_t n) { void set(size_t k, size_t n) {
debug_assert(k + n - 1 < kSize, "Invalid index."); DCHECK(k + n - 1 < kSize) << "Invalid index.";
block_.fetch_or(bitmask(n) << k); block_.fetch_or(bitmask(n) << k);
} }
void clear(size_t k, size_t n) { void clear(size_t k, size_t n) {
debug_assert(k + n - 1 < kSize, "Invalid index."); DCHECK(k + n - 1 < kSize) << "Invalid index.";
block_.fetch_and(~(bitmask(n) << k)); block_.fetch_and(~(bitmask(n) << k));
} }
@ -151,12 +151,12 @@ class DynamicBitset {
private: private:
// Finds the chunk to which k-th bit belongs fails if k is out of bounds. // Finds the chunk to which k-th bit belongs fails if k is out of bounds.
const Chunk &FindChunk(size_t &k) const { const Chunk &FindChunk(size_t &k) const {
debug_assert(k < head_.load()->high(), "Index out of bounds"); DCHECK(k < head_.load()->high()) << "Index out of bounds";
Chunk *chunk = head_; Chunk *chunk = head_;
while (k < chunk->low()) { while (k < chunk->low()) {
chunk = chunk->next_; chunk = chunk->next_;
debug_assert(chunk != nullptr, "chunk is nullptr"); DCHECK(chunk != nullptr) << "chunk is nullptr";
} }
k -= chunk->low(); k -= chunk->low();
return *chunk; return *chunk;

View File

@ -5,7 +5,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "utils/assert.hpp" #include "glog/logging.h"
/** /**
* Bitset data structure with a number of bits provided in constructor. * Bitset data structure with a number of bits provided in constructor.
@ -27,9 +27,9 @@ class Bitset {
* @param idx position of bit. * @param idx position of bit.
*/ */
void Set(int idx) { void Set(int idx) {
debug_assert(idx >= 0, "Invalid bit location."); DCHECK(idx >= 0) << "Invalid bit location.";
debug_assert(idx < static_cast<int64_t>(blocks_.size()) * block_size_, DCHECK(idx < static_cast<int64_t>(blocks_.size()) * block_size_)
"Invalid bit location."); << "Invalid bit location.";
int bucket = idx / block_size_; int bucket = idx / block_size_;
blocks_[bucket] |= TStore(1) << idx % block_size_; blocks_[bucket] |= TStore(1) << idx % block_size_;
} }
@ -39,9 +39,9 @@ class Bitset {
* @return 1/0. * @return 1/0.
*/ */
bool At(int idx) const { bool At(int idx) const {
debug_assert(idx >= 0, "Invalid bit location."); DCHECK(idx >= 0) << "Invalid bit location.";
debug_assert(idx < static_cast<int64_t>(blocks_.size()) * block_size_, DCHECK(idx < static_cast<int64_t>(blocks_.size()) * block_size_)
"Invalid bit location."); << "Invalid bit location.";
int bucket = idx / block_size_; int bucket = idx / block_size_;
return (blocks_[bucket] >> (idx % block_size_)) & 1; return (blocks_[bucket] >> (idx % block_size_)) & 1;
} }
@ -51,8 +51,8 @@ class Bitset {
* @return intersection. * @return intersection.
*/ */
Bitset<TStore> Intersect(const Bitset<TStore> &other) const { Bitset<TStore> Intersect(const Bitset<TStore> &other) const {
debug_assert(this->blocks_.size() == other.blocks_.size(), DCHECK(this->blocks_.size() == other.blocks_.size())
"Bitsets are not of equal size."); << "Bitsets are not of equal size.";
Bitset<TStore> ret(this->blocks_.size() * this->block_size_); Bitset<TStore> ret(this->blocks_.size() * this->block_size_);
for (int i = 0; i < (int)this->blocks_.size(); ++i) { for (int i = 0; i < (int)this->blocks_.size(); ++i) {
ret.blocks_[i] = this->blocks_[i] & other.blocks_[i]; ret.blocks_[i] = this->blocks_[i] & other.blocks_[i];

View File

@ -2,7 +2,7 @@
#include <atomic> #include <atomic>
#include <utility> #include <utility>
#include "utils/assert.hpp" #include "glog/logging.h"
#include "utils/crtp.hpp" #include "utils/crtp.hpp"
// TODO: reimplement this. It's correct but somewhat inefecient and it could be // TODO: reimplement this. It's correct but somewhat inefecient and it could be
@ -63,7 +63,7 @@ class ConcurrentList {
IteratorBase() : list(nullptr), curr(nullptr) {} IteratorBase() : list(nullptr), curr(nullptr) {}
IteratorBase(ConcurrentList *list) : list(list) { IteratorBase(ConcurrentList *list) : list(list) {
debug_assert(list != nullptr, "List is nullptr."); DCHECK(list != nullptr) << "List is nullptr.";
// Increment number of iterators accessing list. // Increment number of iterators accessing list.
list->active_threads_no_++; list->active_threads_no_++;
// Start from the begining of list. // Start from the begining of list.
@ -113,11 +113,11 @@ class ConcurrentList {
IteratorBase &operator=(IteratorBase &&other) = delete; IteratorBase &operator=(IteratorBase &&other) = delete;
T &operator*() const { T &operator*() const {
debug_assert(valid(), "Not valid data."); DCHECK(valid()) << "Not valid data.";
return curr->data; return curr->data;
} }
T *operator->() const { T *operator->() const {
debug_assert(valid(), "Not valid data."); DCHECK(valid()) << "Not valid data.";
return &(curr->data); return &(curr->data);
} }
@ -125,7 +125,7 @@ class ConcurrentList {
// Iterating is wait free. // Iterating is wait free.
It &operator++() { It &operator++() {
debug_assert(valid(), "Not valid data."); DCHECK(valid()) << "Not valid data.";
do { do {
// We don't care about previous unless it's alive. If it's not alive we // We don't care about previous unless it's alive. If it's not alive we
// are going to look for it again and just incurr performance hit // are going to look for it again and just incurr performance hit
@ -141,7 +141,7 @@ class ConcurrentList {
It &operator++(int) { return operator++(); } It &operator++(int) { return operator++(); }
bool is_removed() { bool is_removed() {
debug_assert(valid(), "Not valid data."); DCHECK(valid()) << "Not valid data.";
return load(curr->removed); return load(curr->removed);
} }
@ -180,7 +180,7 @@ class ConcurrentList {
// This can be improved with combinig the removed flag with prev.next or // This can be improved with combinig the removed flag with prev.next or
// curr.next // curr.next
bool remove() { bool remove() {
debug_assert(valid(), "Not valid data."); DCHECK(valid()) << "Not valid data.";
// Try to logically remove it. // Try to logically remove it.
if (cas(curr->removed, false, true)) { if (cas(curr->removed, false, true)) {
// I removed it!!! // I removed it!!!

View File

@ -3,7 +3,7 @@
#include <atomic> #include <atomic>
#include <mutex> #include <mutex>
#include "utils/assert.hpp" #include "glog/logging.h"
/** @brief A queue with lock-free concurrent push and /** @brief A queue with lock-free concurrent push and
* single-threaded deletion. * single-threaded deletion.
@ -57,15 +57,14 @@ class ConcurrentPushQueue {
bool operator!=(const Iterator &rhs) const { return !(*this == rhs); } bool operator!=(const Iterator &rhs) const { return !(*this == rhs); }
Iterator &operator++() { Iterator &operator++() {
debug_assert(current_ != nullptr, "Prefix increment on invalid iterator"); DCHECK(current_ != nullptr) << "Prefix increment on invalid iterator";
previous_ = current_; previous_ = current_;
current_ = current_->next_; current_ = current_->next_;
return *this; return *this;
} }
Iterator operator++(int) { Iterator operator++(int) {
debug_assert(current_ != nullptr, DCHECK(current_ != nullptr) << "Postfix increment on invalid iterator";
"Postfix increment on invalid iterator");
Iterator rval(queue_, current_); Iterator rval(queue_, current_);
previous_ = current_; previous_ = current_;
current_ = current_->next_; current_ = current_->next_;
@ -73,12 +72,12 @@ class ConcurrentPushQueue {
} }
TElement &operator*() { TElement &operator*() {
debug_assert(current_ != nullptr, DCHECK(current_ != nullptr)
"Dereferencing operator on invalid iterator"); << "Dereferencing operator on invalid iterator";
return current_->element_; return current_->element_;
} }
TElement *operator->() { TElement *operator->() {
debug_assert(current_ != nullptr, "Arrow operator on invalid iterator"); DCHECK(current_ != nullptr) << "Arrow operator on invalid iterator";
return &current_->element_; return &current_->element_;
} }

View File

@ -5,7 +5,7 @@
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include "utils/assert.hpp" #include "glog/logging.h"
#include "utils/crtp.hpp" #include "utils/crtp.hpp"
#include "utils/placeholder.hpp" #include "utils/placeholder.hpp"
#include "utils/random/fast_binomial.hpp" #include "utils/random/fast_binomial.hpp"
@ -256,38 +256,38 @@ class SkipList : private Lockable<lock_t> {
IteratorBase(const IteratorBase &) = default; IteratorBase(const IteratorBase &) = default;
const T &operator*() const { const T &operator*() const {
debug_assert(node != nullptr, "Node is nullptr."); DCHECK(node != nullptr) << "Node is nullptr.";
return node->value(); return node->value();
} }
const T *operator->() const { const T *operator->() const {
debug_assert(node != nullptr, "Node is nullptr."); DCHECK(node != nullptr) << "Node is nullptr.";
return &node->value(); return &node->value();
} }
T &operator*() { T &operator*() {
debug_assert(node != nullptr, "Node is nullptr."); DCHECK(node != nullptr) << "Node is nullptr.";
return node->value(); return node->value();
} }
T *operator->() { T *operator->() {
debug_assert(node != nullptr, "Node is nullptr."); DCHECK(node != nullptr) << "Node is nullptr.";
return &node->value(); return &node->value();
} }
operator T &() { operator T &() {
debug_assert(node != nullptr, "Node is nullptr."); DCHECK(node != nullptr) << "Node is nullptr.";
return node->value(); return node->value();
} }
It &operator++() { It &operator++() {
debug_assert(node != nullptr, "Node is nullptr."); DCHECK(node != nullptr) << "Node is nullptr.";
node = node->forward(0); node = node->forward(0);
return this->derived(); return this->derived();
} }
bool has_next() { bool has_next() {
debug_assert(node != nullptr, "Node is nullptr."); DCHECK(node != nullptr) << "Node is nullptr.";
return node->forward(0) != nullptr; return node->forward(0) != nullptr;
} }
@ -357,22 +357,22 @@ class SkipList : private Lockable<lock_t> {
} }
T &operator*() { T &operator*() {
debug_assert(node_ != nullptr, "Node is nullptr."); DCHECK(node_ != nullptr) << "Node is nullptr.";
return node_->value(); return node_->value();
} }
T *operator->() { T *operator->() {
debug_assert(node_ != nullptr, "Node is nullptr."); DCHECK(node_ != nullptr) << "Node is nullptr.";
return &node_->value(); return &node_->value();
} }
operator T &() { operator T &() {
debug_assert(node_ != nullptr, "Node is nullptr."); DCHECK(node_ != nullptr) << "Node is nullptr.";
return node_->value(); return node_->value();
} }
ReverseIterator &operator++() { ReverseIterator &operator++() {
debug_assert(node_ != nullptr, "Node is nullptr."); DCHECK(node_ != nullptr) << "Node is nullptr.";
do { do {
next(); next();
} while (node_->flags.is_marked()); } while (node_->flags.is_marked());
@ -458,7 +458,7 @@ class SkipList : private Lockable<lock_t> {
Accessor(TSkipList *skiplist) Accessor(TSkipList *skiplist)
: skiplist(skiplist), status_(skiplist->gc.CreateNewAccessor()) { : skiplist(skiplist), status_(skiplist->gc.CreateNewAccessor()) {
debug_assert(skiplist != nullptr, "Skiplist is nullptr."); DCHECK(skiplist != nullptr) << "Skiplist is nullptr.";
} }
public: public:

View File

@ -20,31 +20,29 @@ GraphDbAccessor::~GraphDbAccessor() {
const std::string &GraphDbAccessor::name() const { return db_.name_; } const std::string &GraphDbAccessor::name() const { return db_.name_; }
void GraphDbAccessor::AdvanceCommand() { void GraphDbAccessor::AdvanceCommand() {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
transaction_->engine_.Advance(transaction_->id_); transaction_->engine_.Advance(transaction_->id_);
} }
void GraphDbAccessor::Commit() { void GraphDbAccessor::Commit() {
debug_assert(!commited_ && !aborted_, DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
"Already aborted or commited transaction.");
transaction_->Commit(); transaction_->Commit();
commited_ = true; commited_ = true;
} }
void GraphDbAccessor::Abort() { void GraphDbAccessor::Abort() {
debug_assert(!commited_ && !aborted_, DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
"Already aborted or commited transaction.");
transaction_->Abort(); transaction_->Abort();
aborted_ = true; aborted_ = true;
} }
bool GraphDbAccessor::should_abort() const { bool GraphDbAccessor::should_abort() const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return transaction_->should_abort(); return transaction_->should_abort();
} }
VertexAccessor GraphDbAccessor::InsertVertex() { VertexAccessor GraphDbAccessor::InsertVertex() {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
// create a vertex // create a vertex
auto vertex_vlist = new mvcc::VersionList<Vertex>(*transaction_); auto vertex_vlist = new mvcc::VersionList<Vertex>(*transaction_);
@ -56,7 +54,7 @@ VertexAccessor GraphDbAccessor::InsertVertex() {
void GraphDbAccessor::BuildIndex(const GraphDbTypes::Label &label, void GraphDbAccessor::BuildIndex(const GraphDbTypes::Label &label,
const GraphDbTypes::Property &property) { const GraphDbTypes::Property &property) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
{ {
// switch the build_in_progress to true // switch the build_in_progress to true
@ -70,7 +68,7 @@ void GraphDbAccessor::BuildIndex(const GraphDbTypes::Label &label,
bool expected = true; bool expected = true;
[[gnu::unused]] bool success = [[gnu::unused]] bool success =
db_.index_build_in_progress_.compare_exchange_strong(expected, false); db_.index_build_in_progress_.compare_exchange_strong(expected, false);
debug_assert(success, "BuildIndexInProgress flag was not set during build"); DCHECK(success) << "BuildIndexInProgress flag was not set during build";
}); });
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
@ -115,7 +113,7 @@ void GraphDbAccessor::BuildIndex(const GraphDbTypes::Label &label,
void GraphDbAccessor::UpdateLabelIndices(const GraphDbTypes::Label &label, void GraphDbAccessor::UpdateLabelIndices(const GraphDbTypes::Label &label,
const VertexAccessor &vertex_accessor, const VertexAccessor &vertex_accessor,
const Vertex *const vertex) { const Vertex *const vertex) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
db_.labels_index_.Update(label, vertex_accessor.vlist_, vertex); db_.labels_index_.Update(label, vertex_accessor.vlist_, vertex);
db_.label_property_index_.UpdateOnLabel(label, vertex_accessor.vlist_, db_.label_property_index_.UpdateOnLabel(label, vertex_accessor.vlist_,
vertex); vertex);
@ -124,38 +122,36 @@ void GraphDbAccessor::UpdateLabelIndices(const GraphDbTypes::Label &label,
void GraphDbAccessor::UpdatePropertyIndex( void GraphDbAccessor::UpdatePropertyIndex(
const GraphDbTypes::Property &property, const GraphDbTypes::Property &property,
const RecordAccessor<Vertex> &record_accessor, const Vertex *const vertex) { const RecordAccessor<Vertex> &record_accessor, const Vertex *const vertex) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
db_.label_property_index_.UpdateOnProperty(property, record_accessor.vlist_, db_.label_property_index_.UpdateOnProperty(property, record_accessor.vlist_,
vertex); vertex);
} }
int64_t GraphDbAccessor::VerticesCount() const { int64_t GraphDbAccessor::VerticesCount() const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.vertices_.access().size(); return db_.vertices_.access().size();
} }
int64_t GraphDbAccessor::VerticesCount(const GraphDbTypes::Label &label) const { int64_t GraphDbAccessor::VerticesCount(const GraphDbTypes::Label &label) const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.labels_index_.Count(label); return db_.labels_index_.Count(label);
} }
int64_t GraphDbAccessor::VerticesCount( int64_t GraphDbAccessor::VerticesCount(
const GraphDbTypes::Label &label, const GraphDbTypes::Label &label,
const GraphDbTypes::Property &property) const { const GraphDbTypes::Property &property) const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
debug_assert(db_.label_property_index_.IndexExists(key), DCHECK(db_.label_property_index_.IndexExists(key)) << "Index doesn't exist.";
"Index doesn't exist.");
return db_.label_property_index_.Count(key); return db_.label_property_index_.Count(key);
} }
int64_t GraphDbAccessor::VerticesCount(const GraphDbTypes::Label &label, int64_t GraphDbAccessor::VerticesCount(const GraphDbTypes::Label &label,
const GraphDbTypes::Property &property, const GraphDbTypes::Property &property,
const PropertyValue &value) const { const PropertyValue &value) const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
debug_assert(db_.label_property_index_.IndexExists(key), DCHECK(db_.label_property_index_.IndexExists(key)) << "Index doesn't exist.";
"Index doesn't exist.");
return db_.label_property_index_.PositionAndCount(key, value).second; return db_.label_property_index_.PositionAndCount(key, value).second;
} }
@ -164,17 +160,14 @@ int64_t GraphDbAccessor::VerticesCount(
const std::experimental::optional<utils::Bound<PropertyValue>> lower, const std::experimental::optional<utils::Bound<PropertyValue>> lower,
const std::experimental::optional<utils::Bound<PropertyValue>> upper) const std::experimental::optional<utils::Bound<PropertyValue>> upper)
const { const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
debug_assert(db_.label_property_index_.IndexExists(key), DCHECK(db_.label_property_index_.IndexExists(key)) << "Index doesn't exist.";
"Index doesn't exist."); CHECK(lower || upper) << "At least one bound must be provided";
permanent_assert(lower || upper, "At least one bound must be provided"); CHECK(!lower || lower.value().value().type() != PropertyValue::Type::Null)
permanent_assert( << "Null value is not a valid index bound";
!lower || lower.value().value().type() != PropertyValue::Type::Null, CHECK(!upper || upper.value().value().type() != PropertyValue::Type::Null)
"Null value is not a valid index bound"); << "Null value is not a valid index bound";
permanent_assert(
!upper || upper.value().value().type() != PropertyValue::Type::Null,
"Null value is not a valid index bound");
if (!upper) { if (!upper) {
auto lower_pac = auto lower_pac =
@ -203,7 +196,7 @@ int64_t GraphDbAccessor::VerticesCount(
} }
bool GraphDbAccessor::RemoveVertex(VertexAccessor &vertex_accessor) { bool GraphDbAccessor::RemoveVertex(VertexAccessor &vertex_accessor) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
vertex_accessor.SwitchNew(); vertex_accessor.SwitchNew();
// it's possible the vertex was removed already in this transaction // it's possible the vertex was removed already in this transaction
// due to it getting matched multiple times by some patterns // due to it getting matched multiple times by some patterns
@ -217,7 +210,7 @@ bool GraphDbAccessor::RemoveVertex(VertexAccessor &vertex_accessor) {
} }
void GraphDbAccessor::DetachRemoveVertex(VertexAccessor &vertex_accessor) { void GraphDbAccessor::DetachRemoveVertex(VertexAccessor &vertex_accessor) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
vertex_accessor.SwitchNew(); vertex_accessor.SwitchNew();
for (auto edge_accessor : vertex_accessor.in()) for (auto edge_accessor : vertex_accessor.in())
RemoveEdge(edge_accessor, true, false); RemoveEdge(edge_accessor, true, false);
@ -236,7 +229,7 @@ void GraphDbAccessor::DetachRemoveVertex(VertexAccessor &vertex_accessor) {
EdgeAccessor GraphDbAccessor::InsertEdge(VertexAccessor &from, EdgeAccessor GraphDbAccessor::InsertEdge(VertexAccessor &from,
VertexAccessor &to, VertexAccessor &to,
GraphDbTypes::EdgeType edge_type) { GraphDbTypes::EdgeType edge_type) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
// create an edge // create an edge
auto edge_vlist = new mvcc::VersionList<Edge>(*transaction_, *from.vlist_, auto edge_vlist = new mvcc::VersionList<Edge>(*transaction_, *from.vlist_,
*to.vlist_, edge_type); *to.vlist_, edge_type);
@ -262,13 +255,13 @@ EdgeAccessor GraphDbAccessor::InsertEdge(VertexAccessor &from,
} }
int64_t GraphDbAccessor::EdgesCount() const { int64_t GraphDbAccessor::EdgesCount() const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.edges_.access().size(); return db_.edges_.access().size();
} }
void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge_accessor, void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge_accessor,
bool remove_from_from, bool remove_from_to) { bool remove_from_from, bool remove_from_to) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
// it's possible the edge was removed already in this transaction // it's possible the edge was removed already in this transaction
// due to it getting matched multiple times by some patterns // due to it getting matched multiple times by some patterns
// we can only delete it once, so check if it's already deleted // we can only delete it once, so check if it's already deleted
@ -282,37 +275,37 @@ void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge_accessor,
} }
GraphDbTypes::Label GraphDbAccessor::Label(const std::string &label_name) { GraphDbTypes::Label GraphDbAccessor::Label(const std::string &label_name) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return &(*db_.labels_.access().insert(label_name).first); return &(*db_.labels_.access().insert(label_name).first);
} }
const std::string &GraphDbAccessor::LabelName( const std::string &GraphDbAccessor::LabelName(
const GraphDbTypes::Label label) const { const GraphDbTypes::Label label) const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return *label; return *label;
} }
GraphDbTypes::EdgeType GraphDbAccessor::EdgeType( GraphDbTypes::EdgeType GraphDbAccessor::EdgeType(
const std::string &edge_type_name) { const std::string &edge_type_name) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return &(*db_.edge_types_.access().insert(edge_type_name).first); return &(*db_.edge_types_.access().insert(edge_type_name).first);
} }
const std::string &GraphDbAccessor::EdgeTypeName( const std::string &GraphDbAccessor::EdgeTypeName(
const GraphDbTypes::EdgeType edge_type) const { const GraphDbTypes::EdgeType edge_type) const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return *edge_type; return *edge_type;
} }
GraphDbTypes::Property GraphDbAccessor::Property( GraphDbTypes::Property GraphDbAccessor::Property(
const std::string &property_name) { const std::string &property_name) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return &(*db_.properties_.access().insert(property_name).first); return &(*db_.properties_.access().insert(property_name).first);
} }
const std::string &GraphDbAccessor::PropertyName( const std::string &GraphDbAccessor::PropertyName(
const GraphDbTypes::Property property) const { const GraphDbTypes::Property property) const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return *property; return *property;
} }

View File

@ -10,6 +10,7 @@
#include "cppitertools/filter.hpp" #include "cppitertools/filter.hpp"
#include "cppitertools/imap.hpp" #include "cppitertools/imap.hpp"
#include "glog/logging.h"
#include "graph_db.hpp" #include "graph_db.hpp"
#include "storage/edge_accessor.hpp" #include "storage/edge_accessor.hpp"
@ -107,7 +108,7 @@ class GraphDbAccessor {
* ignored). * ignored).
*/ */
auto Vertices(bool current_state) { auto Vertices(bool current_state) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
// wrap version lists into accessors, which will look for visible versions // wrap version lists into accessors, which will look for visible versions
auto accessors = auto accessors =
iter::imap([this](auto vlist) { return VertexAccessor(*vlist, *this); }, iter::imap([this](auto vlist) { return VertexAccessor(*vlist, *this); },
@ -136,7 +137,7 @@ class GraphDbAccessor {
* @return iterable collection * @return iterable collection
*/ */
auto Vertices(const GraphDbTypes::Label &label, bool current_state) { auto Vertices(const GraphDbTypes::Label &label, bool current_state) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return iter::imap( return iter::imap(
[this](auto vlist) { return VertexAccessor(*vlist, *this); }, [this](auto vlist) { return VertexAccessor(*vlist, *this); },
db_.labels_index_.GetVlists(label, *transaction_, current_state)); db_.labels_index_.GetVlists(label, *transaction_, current_state));
@ -155,10 +156,10 @@ class GraphDbAccessor {
*/ */
auto Vertices(const GraphDbTypes::Label &label, auto Vertices(const GraphDbTypes::Label &label,
const GraphDbTypes::Property &property, bool current_state) { const GraphDbTypes::Property &property, bool current_state) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
debug_assert(db_.label_property_index_.IndexExists( DCHECK(db_.label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property)), LabelPropertyIndex::Key(label, property)))
"Label+property index doesn't exist."); << "Label+property index doesn't exist.";
return iter::imap( return iter::imap(
[this](auto vlist) { return VertexAccessor(*vlist, *this); }, [this](auto vlist) { return VertexAccessor(*vlist, *this); },
db_.label_property_index_.GetVlists( db_.label_property_index_.GetVlists(
@ -182,12 +183,12 @@ class GraphDbAccessor {
auto Vertices(const GraphDbTypes::Label &label, auto Vertices(const GraphDbTypes::Label &label,
const GraphDbTypes::Property &property, const GraphDbTypes::Property &property,
const PropertyValue &value, bool current_state) { const PropertyValue &value, bool current_state) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
debug_assert(db_.label_property_index_.IndexExists( DCHECK(db_.label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property)), LabelPropertyIndex::Key(label, property)))
"Label+property index doesn't exist."); << "Label+property index doesn't exist.";
permanent_assert(value.type() != PropertyValue::Type::Null, CHECK(value.type() != PropertyValue::Type::Null)
"Can't query index for propery value type null."); << "Can't query index for propery value type null.";
return iter::imap( return iter::imap(
[this](auto vlist) { return VertexAccessor(*vlist, *this); }, [this](auto vlist) { return VertexAccessor(*vlist, *this); },
db_.label_property_index_.GetVlists( db_.label_property_index_.GetVlists(
@ -227,10 +228,10 @@ class GraphDbAccessor {
const std::experimental::optional<utils::Bound<PropertyValue>> lower, const std::experimental::optional<utils::Bound<PropertyValue>> lower,
const std::experimental::optional<utils::Bound<PropertyValue>> upper, const std::experimental::optional<utils::Bound<PropertyValue>> upper,
bool current_state) { bool current_state) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
debug_assert(db_.label_property_index_.IndexExists( DCHECK(db_.label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property)), LabelPropertyIndex::Key(label, property)))
"Label+property index doesn't exist."); << "Label+property index doesn't exist.";
return iter::imap( return iter::imap(
[this](auto vlist) { return VertexAccessor(*vlist, *this); }, [this](auto vlist) { return VertexAccessor(*vlist, *this); },
db_.label_property_index_.GetVlists( db_.label_property_index_.GetVlists(
@ -274,7 +275,7 @@ class GraphDbAccessor {
* ignored). * ignored).
*/ */
auto Edges(bool current_state) { auto Edges(bool current_state) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
// wrap version lists into accessors, which will look for visible versions // wrap version lists into accessors, which will look for visible versions
auto accessors = auto accessors =
@ -349,7 +350,7 @@ class GraphDbAccessor {
*/ */
bool LabelPropertyIndexExists(const GraphDbTypes::Label &label, bool LabelPropertyIndexExists(const GraphDbTypes::Label &label,
const GraphDbTypes::Property &property) const { const GraphDbTypes::Property &property) const {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.label_property_index_.IndexExists( return db_.label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property)); LabelPropertyIndex::Key(label, property));
} }
@ -358,7 +359,7 @@ class GraphDbAccessor {
* @brief - Returns vector of keys of label-property indices. * @brief - Returns vector of keys of label-property indices.
*/ */
std::vector<LabelPropertyIndex::Key> GetIndicesKeys() { std::vector<LabelPropertyIndex::Key> GetIndicesKeys() {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.label_property_index_.GetIndicesKeys(); return db_.label_property_index_.GetIndicesKeys();
} }
@ -493,7 +494,7 @@ class GraphDbAccessor {
*/ */
template <typename TRecord> template <typename TRecord>
bool Reconstruct(RecordAccessor<TRecord> &accessor) { bool Reconstruct(RecordAccessor<TRecord> &accessor) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
accessor.vlist_->find_set_old_new(*transaction_, accessor.old_, accessor.vlist_->find_set_old_new(*transaction_, accessor.old_,
accessor.new_); accessor.new_);
accessor.current_ = accessor.old_ ? accessor.old_ : accessor.new_; accessor.current_ = accessor.old_ ? accessor.old_ : accessor.new_;
@ -516,18 +517,16 @@ class GraphDbAccessor {
*/ */
template <typename TRecord> template <typename TRecord>
void Update(RecordAccessor<TRecord> &accessor) { void Update(RecordAccessor<TRecord> &accessor) {
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted"); DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
// can't update a deleted record if: // can't update a deleted record if:
// - we only have old_ and it hasn't been deleted // - we only have old_ and it hasn't been deleted
// - we have new_ and it hasn't been deleted // - we have new_ and it hasn't been deleted
if (!accessor.new_) { if (!accessor.new_) {
debug_assert( DCHECK(!accessor.old_->is_expired_by(*transaction_))
!accessor.old_->is_expired_by(*transaction_), << "Can't update a record deleted in the current transaction+commad";
"Can't update a record deleted in the current transaction+command");
} else { } else {
debug_assert( DCHECK(!accessor.new_->is_expired_by(*transaction_))
!accessor.new_->is_expired_by(*transaction_), << "Can't update a record deleted in the current transaction+command";
"Can't update a record deleted in the current transaction+command");
} }
if (!accessor.new_) accessor.new_ = accessor.vlist_->update(*transaction_); if (!accessor.new_) accessor.new_ = accessor.vlist_->update(*transaction_);

View File

@ -3,6 +3,7 @@
#include "cppitertools/filter.hpp" #include "cppitertools/filter.hpp"
#include "cppitertools/imap.hpp" #include "cppitertools/imap.hpp"
#include "cppitertools/takewhile.hpp" #include "cppitertools/takewhile.hpp"
#include "glog/logging.h"
#include "data_structures/concurrent/concurrent_map.hpp" #include "data_structures/concurrent/concurrent_map.hpp"
#include "data_structures/concurrent/skiplist.hpp" #include "data_structures/concurrent/skiplist.hpp"
@ -162,7 +163,7 @@ static void Refresh(
[[gnu::unused]] auto success = [[gnu::unused]] auto success =
indices_entries_accessor.remove(indices_entry); indices_entries_accessor.remove(indices_entry);
debug_assert(success, "Unable to delete entry."); DCHECK(success) << "Unable to delete entry.";
} }
// if the record is still visible, // if the record is still visible,

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "glog/logging.h"
#include "data_structures/concurrent/concurrent_map.hpp" #include "data_structures/concurrent/concurrent_map.hpp"
#include "database/graph_db.hpp" #include "database/graph_db.hpp"
#include "database/graph_db_datatypes.hpp" #include "database/graph_db_datatypes.hpp"
@ -171,7 +173,7 @@ class KeyIndex {
* @return true if it contains, false otherwise. * @return true if it contains, false otherwise.
*/ */
static bool Exists(const GraphDbTypes::Label &label, const Vertex *const v) { static bool Exists(const GraphDbTypes::Label &label, const Vertex *const v) {
debug_assert(v != nullptr, "Vertex is nullptr."); DCHECK(v != nullptr) << "Vertex is nullptr.";
// We have to check for existance of label because the transaction // We have to check for existance of label because the transaction
// might not see the label, or the label was deleted and not yet // might not see the label, or the label was deleted and not yet
// removed from the index. // removed from the index.
@ -186,7 +188,7 @@ class KeyIndex {
*/ */
static bool Exists(const GraphDbTypes::EdgeType &edge_type, static bool Exists(const GraphDbTypes::EdgeType &edge_type,
const Edge *const e) { const Edge *const e) {
debug_assert(e != nullptr, "Edge is nullptr."); DCHECK(e != nullptr) << "Edge is nullptr.";
// We have to check for equality of edge types because the transaction // We have to check for equality of edge types because the transaction
// might not see the edge type, or the edge type was deleted and not yet // might not see the edge type, or the edge type was deleted and not yet
// removed from the index. // removed from the index.

View File

@ -168,7 +168,7 @@ class LabelPropertyIndex {
* key sorted ascendingly by the property value. * key sorted ascendingly by the property value.
*/ */
auto GetVlists(const Key &key, const tx::Transaction &t, bool current_state) { auto GetVlists(const Key &key, const tx::Transaction &t, bool current_state) {
debug_assert(ready_for_use_.access().contains(key), "Index not yet ready."); DCHECK(ready_for_use_.access().contains(key)) << "Index not yet ready.";
auto access = GetKeyStorage(key)->access(); auto access = GetKeyStorage(key)->access();
auto begin = access.begin(); auto begin = access.begin();
return IndexUtils::GetVlists<typename SkipList<IndexEntry>::Iterator, return IndexUtils::GetVlists<typename SkipList<IndexEntry>::Iterator,
@ -196,7 +196,7 @@ class LabelPropertyIndex {
*/ */
auto GetVlists(const Key &key, const PropertyValue &value, auto GetVlists(const Key &key, const PropertyValue &value,
const tx::Transaction &t, bool current_state) { const tx::Transaction &t, bool current_state) {
debug_assert(ready_for_use_.access().contains(key), "Index not yet ready."); DCHECK(ready_for_use_.access().contains(key)) << "Index not yet ready.";
auto access = GetKeyStorage(key)->access(); auto access = GetKeyStorage(key)->access();
auto min_ptr = std::numeric_limits<std::uintptr_t>::min(); auto min_ptr = std::numeric_limits<std::uintptr_t>::min();
auto start_iter = access.find_or_larger(IndexEntry( auto start_iter = access.find_or_larger(IndexEntry(
@ -246,14 +246,14 @@ class LabelPropertyIndex {
const std::experimental::optional<utils::Bound<PropertyValue>> lower, const std::experimental::optional<utils::Bound<PropertyValue>> lower,
const std::experimental::optional<utils::Bound<PropertyValue>> upper, const std::experimental::optional<utils::Bound<PropertyValue>> upper,
const tx::Transaction &transaction, bool current_state) { const tx::Transaction &transaction, bool current_state) {
debug_assert(ready_for_use_.access().contains(key), "Index not yet ready."); DCHECK(ready_for_use_.access().contains(key)) << "Index not yet ready.";
auto type = [](const auto &bound) { return bound.value().value().type(); }; auto type = [](const auto &bound) { return bound.value().value().type(); };
permanent_assert(lower || upper, "At least one bound must be provided"); CHECK(lower || upper) << "At least one bound must be provided";
permanent_assert(!lower || type(lower) != PropertyValue::Type::Null, CHECK(!lower || type(lower) != PropertyValue::Type::Null)
"Null value is not a valid index bound"); << "Null value is not a valid index bound";
permanent_assert(!upper || type(upper) != PropertyValue::Type::Null, CHECK(!upper || type(upper) != PropertyValue::Type::Null)
"Null value is not a valid index bound"); << "Null value is not a valid index bound";
// helper function for creating a bound with an IndexElement // helper function for creating a bound with an IndexElement
auto make_index_bound = [](const auto &optional_bound, bool bottom) { auto make_index_bound = [](const auto &optional_bound, bool bottom) {
@ -328,9 +328,8 @@ class LabelPropertyIndex {
*/ */
int64_t Count(const Key &key) { int64_t Count(const Key &key) {
auto index = GetKeyStorage(key); auto index = GetKeyStorage(key);
permanent_assert(index != nullptr, "Index doesn't exist."); CHECK(index != nullptr) << "Index doesn't exist.";
permanent_assert(ready_for_use_.access().contains(key), CHECK(ready_for_use_.access().contains(key)) << "Index not yet ready.";
"Index not yet ready.");
return index->access().size(); return index->access().size();
} }
@ -468,15 +467,15 @@ class LabelPropertyIndex {
mb.end(), cmp); mb.end(), cmp);
} }
default: default:
permanent_fail("Unimplemented type operator."); LOG(FATAL) << "Unimplemented type operator.";
} }
} }
// helper for getting a double from PropertyValue, if possible // helper for getting a double from PropertyValue, if possible
auto get_double = [](const PropertyValue &value) { auto get_double = [](const PropertyValue &value) {
debug_assert(value.type() == PropertyValue::Type::Int || DCHECK(value.type() == PropertyValue::Type::Int ||
value.type() == PropertyValue::Type::Double, value.type() == PropertyValue::Type::Double)
"Invalid data type."); << "Invalid data type.";
if (value.type() == PropertyValue::Type::Int) if (value.type() == PropertyValue::Type::Int)
return static_cast<double>(value.Value<int64_t>()); return static_cast<double>(value.Value<int64_t>());
return value.Value<double>(); return value.Value<double>();
@ -539,7 +538,7 @@ class LabelPropertyIndex {
*/ */
static bool Exists(const Key &key, const PropertyValue &value, static bool Exists(const Key &key, const PropertyValue &value,
const Vertex *const v) { const Vertex *const v) {
debug_assert(v != nullptr, "Vertex is nullptr."); DCHECK(v != nullptr) << "Vertex is nullptr.";
// We have to check for existance of label because the transaction // We have to check for existance of label because the transaction
// might not see the label, or the label was deleted and not yet // might not see the label, or the label was deleted and not yet
// removed from the index. // removed from the index.

View File

@ -73,8 +73,8 @@ class FileReaderBuffer {
* reference to a summary object where summary should be written. * reference to a summary object where summary should be written.
*/ */
bool ReadSummary(snapshot::Summary &summary) { bool ReadSummary(snapshot::Summary &summary) {
debug_assert(input_stream_.tellg() == 0, DCHECK(input_stream_.tellg() == 0)
"Summary should be read before other data!"); << "Summary should be read before other data!";
input_stream_.seekg(-static_cast<int64_t>(sizeof(snapshot::Summary)), input_stream_.seekg(-static_cast<int64_t>(sizeof(snapshot::Summary)),
std::ios::end); std::ios::end);
if (input_stream_.fail()) return false; if (input_stream_.fail()) return false;

View File

@ -64,8 +64,8 @@ class FileWriterBuffer {
* writing was successful. * writing was successful.
*/ */
void WriteSummary(int64_t vertex_num, int64_t edge_num) { void WriteSummary(int64_t vertex_num, int64_t edge_num) {
debug_assert(vertex_num >= 0, "Number of vertices should't be negative"); DCHECK(vertex_num >= 0) << "Number of vertices should't be negative";
debug_assert(vertex_num >= 0, "Number of edges should't be negative"); DCHECK(vertex_num >= 0) << "Number of edges should't be negative";
WriteLong(vertex_num); WriteLong(vertex_num);
WriteLong(edge_num); WriteLong(edge_num);
WriteLong(hasher_.hash()); WriteLong(hasher_.hash());

View File

@ -56,7 +56,7 @@ class Record : public Version<T> {
} }
void mark_created(const tx::Transaction &t) { void mark_created(const tx::Transaction &t) {
debug_assert(tx_.cre == 0, "Marking node as created twice."); DCHECK(tx_.cre == 0) << "Marking node as created twice.";
tx_.cre = t.id_; tx_.cre = t.id_;
cmd_.cre = t.cid(); cmd_.cre = t.cid();
} }
@ -217,8 +217,8 @@ class Record : public Version<T> {
// below, but it has a same name. // below, but it has a same name.
bool committed(uint8_t mask, tx::transaction_id_t id, bool committed(uint8_t mask, tx::transaction_id_t id,
const tx::Transaction &t) { const tx::Transaction &t) {
debug_assert(mask == Hints::kCre || mask == Hints::kExp, DCHECK(mask == Hints::kCre || mask == Hints::kExp)
"Mask must be either kCre or kExp"); << "Mask must be either kCre or kExp";
// Dominik Gleich says 4 april 2017: the tests in this routine are correct; // Dominik Gleich says 4 april 2017: the tests in this routine are correct;
// if you think they're not, you're wrong, and you should think about it // if you think they're not, you're wrong, and you should think about it
// again. I know, it happened to me (and also to Matej Gradicek). // again. I know, it happened to me (and also to Matej Gradicek).
@ -245,8 +245,8 @@ class Record : public Version<T> {
*/ */
bool committed(uint8_t mask, tx::transaction_id_t id, bool committed(uint8_t mask, tx::transaction_id_t id,
const tx::Engine &engine) const { const tx::Engine &engine) const {
debug_assert(mask == Hints::kCre || mask == Hints::kExp, DCHECK(mask == Hints::kCre || mask == Hints::kExp)
"Mask must be either kCre or kExp"); << "Mask must be either kCre or kExp";
// If hints are set, return if id is committed. // If hints are set, return if id is committed.
if (hints_.Get(mask)) return hints_.Get(Hints::kCmt & mask); if (hints_.Get(mask)) return hints_.Get(Hints::kCmt & mask);
@ -295,4 +295,4 @@ class Record : public Version<T> {
return false; return false;
} }
}; };
} } // namespace mvcc

View File

@ -194,7 +194,7 @@ class VersionList {
* @param t The transaction * @param t The transaction
*/ */
T *update(tx::Transaction &t) { T *update(tx::Transaction &t) {
debug_assert(head_ != nullptr, "Head is nullptr on update."); DCHECK(head_ != nullptr) << "Head is nullptr on update.";
T *old_record = nullptr; T *old_record = nullptr;
T *new_record = nullptr; T *new_record = nullptr;
find_set_old_new(t, old_record, new_record); find_set_old_new(t, old_record, new_record);
@ -204,16 +204,16 @@ class VersionList {
if (new_record) return new_record; if (new_record) return new_record;
// check if we found any visible records // check if we found any visible records
permanent_assert(old_record != nullptr, "Updating nullptr record"); CHECK(old_record != nullptr) << "Updating nullptr record";
return update(old_record, t); return update(old_record, t);
} }
void remove(tx::Transaction &t) { void remove(tx::Transaction &t) {
debug_assert(head_ != nullptr, "Head is nullptr on removal."); DCHECK(head_ != nullptr) << "Head is nullptr on removal.";
auto record = find(t); auto record = find(t);
permanent_assert(record != nullptr, "Removing nullptr record"); CHECK(record != nullptr) << "Removing nullptr record";
// TODO: Is this lock and validate necessary // TODO: Is this lock and validate necessary
lock_and_validate(record, t); lock_and_validate(record, t);
@ -223,15 +223,14 @@ class VersionList {
// TODO(flor): This should also be private but can't be right now because of // TODO(flor): This should also be private but can't be right now because of
// the way graph_db_accessor works. // the way graph_db_accessor works.
void remove(T *record, tx::Transaction &t) { void remove(T *record, tx::Transaction &t) {
debug_assert(record != nullptr, "Record is nullptr on removal."); DCHECK(record != nullptr) << "Record is nullptr on removal.";
lock_and_validate(record, t); lock_and_validate(record, t);
record->mark_expired(t); record->mark_expired(t);
} }
private: private:
void lock_and_validate(T *record, tx::Transaction &t) { void lock_and_validate(T *record, tx::Transaction &t) {
debug_assert(record != nullptr, DCHECK(record != nullptr) << "Record is nullptr on lock and validation.";
"Record is nullptr on lock and validation.");
// take a lock on this node // take a lock on this node
t.TakeLock(lock_); t.TakeLock(lock_);
@ -245,7 +244,7 @@ class VersionList {
} }
T *update(T *record, tx::Transaction &t) { T *update(T *record, tx::Transaction &t) {
debug_assert(record != nullptr, "Record is nullptr on update."); DCHECK(record != nullptr) << "Record is nullptr on update.";
lock_and_validate(record, t); lock_and_validate(record, t);
// It could be done with unique_ptr but while this could mean memory // It could be done with unique_ptr but while this could mean memory
@ -269,4 +268,4 @@ class VersionList {
std::atomic<T *> head_{nullptr}; std::atomic<T *> head_{nullptr};
RecordLock lock_; RecordLock lock_;
}; };
} } // namespace mvcc

View File

@ -5,8 +5,9 @@
#include <locale> #include <locale>
#include <stdexcept> #include <stdexcept>
#include "glog/logging.h"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "utils/assert.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
namespace query { namespace query {
@ -142,7 +143,7 @@ std::string ParseStringLiteral(const std::string &s) {
default: default:
// This should never happen, except grammar changes and we don't // This should never happen, except grammar changes and we don't
// notice change in this production. // notice change in this production.
debug_assert(false, "can't happen"); DLOG(FATAL) << "can't happen";
throw std::exception(); throw std::exception();
} }
escape = false; escape = false;
@ -164,12 +165,12 @@ double ParseDoubleLiteral(const std::string &s) {
} }
std::string ParseParameter(const std::string &s) { std::string ParseParameter(const std::string &s) {
debug_assert(s[0] == '$', "Invalid string passed as parameter name"); DCHECK(s[0] == '$') << "Invalid string passed as parameter name";
if (s[1] != '`') return s.substr(1); if (s[1] != '`') return s.substr(1);
// If parameter name is escaped symbolic name then symbolic name should be // If parameter name is escaped symbolic name then symbolic name should be
// unescaped and leading and trailing backquote should be removed. // unescaped and leading and trailing backquote should be removed.
debug_assert(s.size() > 3U && s.back() == '`', DCHECK(s.size() > 3U && s.back() == '`')
"Invalid string passed as parameter name"); << "Invalid string passed as parameter name";
std::string out; std::string out;
for (int i = 2; i < static_cast<int>(s.size()) - 1; ++i) { for (int i = 2; i < static_cast<int>(s.size()) - 1; ++i) {
if (s[i] == '`') { if (s[i] == '`') {
@ -179,4 +180,4 @@ std::string ParseParameter(const std::string &s) {
} }
return out; return out;
} }
} } // namespace query

View File

@ -5,12 +5,13 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "database/graph_db.hpp" #include "database/graph_db.hpp"
#include "database/graph_db_datatypes.hpp" #include "database/graph_db_datatypes.hpp"
#include "query/frontend/ast/ast_visitor.hpp" #include "query/frontend/ast/ast_visitor.hpp"
#include "query/parameters.hpp" #include "query/parameters.hpp"
#include "query/typed_value.hpp" #include "query/typed_value.hpp"
#include "utils/assert.hpp"
// Hash function for the key in pattern atom property maps. // Hash function for the key in pattern atom property maps.
namespace std { namespace std {
@ -25,20 +26,20 @@ struct hash<std::pair<std::string, GraphDbTypes::Property>> {
std::hash<std::string> string_hash{}; std::hash<std::string> string_hash{};
std::hash<GraphDbTypes::Property> property_hash{}; std::hash<GraphDbTypes::Property> property_hash{};
}; };
} } // namespace std
namespace query { namespace query {
#define CLONE_BINARY_EXPRESSION \ #define CLONE_BINARY_EXPRESSION \
auto Clone(AstTreeStorage &storage) const->std::remove_const< \ auto Clone(AstTreeStorage &storage) const->std::remove_const< \
std::remove_pointer<decltype(this)>::type>::type * override { \ std::remove_pointer<decltype(this)>::type>::type *override { \
return storage.Create< \ return storage.Create< \
std::remove_cv<std::remove_reference<decltype(*this)>::type>::type>( \ std::remove_cv<std::remove_reference<decltype(*this)>::type>::type>( \
expression1_->Clone(storage), expression2_->Clone(storage)); \ expression1_->Clone(storage), expression2_->Clone(storage)); \
} }
#define CLONE_UNARY_EXPRESSION \ #define CLONE_UNARY_EXPRESSION \
auto Clone(AstTreeStorage &storage) const->std::remove_const< \ auto Clone(AstTreeStorage &storage) const->std::remove_const< \
std::remove_pointer<decltype(this)>::type>::type * override { \ std::remove_pointer<decltype(this)>::type>::type *override { \
return storage.Create< \ return storage.Create< \
std::remove_cv<std::remove_reference<decltype(*this)>::type>::type>( \ std::remove_cv<std::remove_reference<decltype(*this)>::type>::type>( \
expression_->Clone(storage)); \ expression_->Clone(storage)); \
@ -498,10 +499,9 @@ class IfOperator : public Expression {
condition_(condition), condition_(condition),
then_expression_(then_expression), then_expression_(then_expression),
else_expression_(else_expression) { else_expression_(else_expression) {
debug_assert( DCHECK(condition_ != nullptr && then_expression_ != nullptr &&
condition_ != nullptr && then_expression_ != nullptr && else_expression_ != nullptr)
else_expression_ != nullptr, << "clause_, then_expression_ and else_expression_ can't be nullptr";
"clause_, then_expression_ and else_expression_ can't be nullptr");
} }
}; };
@ -782,7 +782,8 @@ class Function : public Expression {
std::vector<Expression *> arguments_; std::vector<Expression *> arguments_;
protected: protected:
Function(int uid, std::function<TypedValue(const std::vector<TypedValue> &, Function(int uid,
std::function<TypedValue(const std::vector<TypedValue> &,
GraphDbAccessor &)> GraphDbAccessor &)>
function, function,
const std::vector<Expression *> &arguments) const std::vector<Expression *> &arguments)
@ -824,11 +825,11 @@ class Aggregation : public BinaryOperator {
Aggregation(int uid, Expression *expression1, Expression *expression2, Op op) Aggregation(int uid, Expression *expression1, Expression *expression2, Op op)
: BinaryOperator(uid, expression1, expression2), op_(op) { : BinaryOperator(uid, expression1, expression2), op_(op) {
// COUNT without expression denotes COUNT(*) in cypher. // COUNT without expression denotes COUNT(*) in cypher.
debug_assert(expression1 || op == Aggregation::Op::COUNT, DCHECK(expression1 || op == Aggregation::Op::COUNT)
"All aggregations, except COUNT require expression"); << "All aggregations, except COUNT require expression";
debug_assert(expression2 == nullptr ^ op == Aggregation::Op::COLLECT_MAP, DCHECK(expression2 == nullptr ^ op == Aggregation::Op::COLLECT_MAP)
"The second expression is obligatory in COLLECT_MAP and " << "The second expression is obligatory in COLLECT_MAP and "
"invalid otherwise"); "invalid otherwise";
} }
}; };
@ -862,9 +863,9 @@ class All : public Expression {
identifier_(identifier), identifier_(identifier),
list_expression_(list_expression), list_expression_(list_expression),
where_(where) { where_(where) {
debug_assert(identifier, "identifier must not be nullptr"); DCHECK(identifier) << "identifier must not be nullptr";
debug_assert(list_expression, "list_expression must not be nullptr"); DCHECK(list_expression) << "list_expression must not be nullptr";
debug_assert(where, "where must not be nullptr"); DCHECK(where) << "where must not be nullptr";
} }
}; };
@ -1545,8 +1546,8 @@ class Unwind : public Clause {
protected: protected:
Unwind(int uid, NamedExpression *named_expression) Unwind(int uid, NamedExpression *named_expression)
: Clause(uid), named_expression_(named_expression) { : Clause(uid), named_expression_(named_expression) {
debug_assert(named_expression, DCHECK(named_expression)
"Unwind cannot take nullptr for named_expression") << "Unwind cannot take nullptr for named_expression";
} }
}; };

View File

@ -11,11 +11,12 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "database/graph_db.hpp" #include "database/graph_db.hpp"
#include "query/common.hpp" #include "query/common.hpp"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "query/interpret/awesome_memgraph_functions.hpp" #include "query/interpret/awesome_memgraph_functions.hpp"
#include "utils/assert.hpp"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
@ -91,7 +92,7 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(
} }
has_create_index = true; has_create_index = true;
} else { } else {
debug_assert(false, "Can't happen"); DLOG(FATAL) << "Can't happen";
} }
} }
if (!has_update && !has_return && !has_create_index) { if (!has_update && !has_return && !has_create_index) {
@ -338,9 +339,9 @@ antlrcpp::Any CypherMainVisitor::visitSymbolicName(
CypherParser::SymbolicNameContext *ctx) { CypherParser::SymbolicNameContext *ctx) {
if (ctx->EscapedSymbolicName()) { if (ctx->EscapedSymbolicName()) {
auto quoted_name = ctx->getText(); auto quoted_name = ctx->getText();
debug_assert(quoted_name.size() >= 2U && quoted_name[0] == '`' && DCHECK(quoted_name.size() >= 2U && quoted_name[0] == '`' &&
quoted_name.back() == '`', quoted_name.back() == '`')
"Can't happen. Grammar ensures this"); << "Can't happen. Grammar ensures this";
// Remove enclosing backticks. // Remove enclosing backticks.
std::string escaped_name = std::string escaped_name =
quoted_name.substr(1, static_cast<int>(quoted_name.size()) - 2); quoted_name.substr(1, static_cast<int>(quoted_name.size()) - 2);
@ -353,7 +354,7 @@ antlrcpp::Any CypherMainVisitor::visitSymbolicName(
name.push_back('`'); name.push_back('`');
escaped = false; escaped = false;
} else { } else {
debug_assert(false, "Can't happen. Grammar ensures that."); DLOG(FATAL) << "Can't happen. Grammar ensures that.";
} }
} else if (c == '`') { } else if (c == '`') {
escaped = true; escaped = true;
@ -519,13 +520,13 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(
antlrcpp::Any CypherMainVisitor::visitRelationshipDetail( antlrcpp::Any CypherMainVisitor::visitRelationshipDetail(
CypherParser::RelationshipDetailContext *) { CypherParser::RelationshipDetailContext *) {
debug_assert(false, "Should never be called. See documentation in hpp."); DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
antlrcpp::Any CypherMainVisitor::visitRelationshipLambda( antlrcpp::Any CypherMainVisitor::visitRelationshipLambda(
CypherParser::RelationshipLambdaContext *) { CypherParser::RelationshipLambdaContext *) {
debug_assert(false, "Should never be called. See documentation in hpp."); DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
@ -540,8 +541,8 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipTypes(
antlrcpp::Any CypherMainVisitor::visitVariableExpansion( antlrcpp::Any CypherMainVisitor::visitVariableExpansion(
CypherParser::VariableExpansionContext *ctx) { CypherParser::VariableExpansionContext *ctx) {
debug_assert(ctx->expression().size() <= 2U, DCHECK(ctx->expression().size() <= 2U)
"Expected 0, 1 or 2 bounds in range literal."); << "Expected 0, 1 or 2 bounds in range literal.";
bool is_bfs = !ctx->getTokens(CypherParser::BFS).empty(); bool is_bfs = !ctx->getTokens(CypherParser::BFS).empty();
Expression *lower = nullptr; Expression *lower = nullptr;
@ -667,7 +668,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression8(
antlrcpp::Any CypherMainVisitor::visitPartialComparisonExpression( antlrcpp::Any CypherMainVisitor::visitPartialComparisonExpression(
CypherParser::PartialComparisonExpressionContext *) { CypherParser::PartialComparisonExpressionContext *) {
debug_assert(false, "Should never be called. See documentation in hpp."); DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
@ -743,7 +744,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression3a(
antlrcpp::Any CypherMainVisitor::visitStringAndNullOperators( antlrcpp::Any CypherMainVisitor::visitStringAndNullOperators(
CypherParser::StringAndNullOperatorsContext *) { CypherParser::StringAndNullOperatorsContext *) {
debug_assert(false, "Should never be called. See documentation in hpp."); DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
@ -776,7 +777,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression3b(
antlrcpp::Any CypherMainVisitor::visitListIndexingOrSlicing( antlrcpp::Any CypherMainVisitor::visitListIndexingOrSlicing(
CypherParser::ListIndexingOrSlicingContext *) { CypherParser::ListIndexingOrSlicingContext *) {
debug_assert(false, "Should never be called. See documentation in hpp."); DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
@ -874,7 +875,7 @@ antlrcpp::Any CypherMainVisitor::visitLiteral(
return static_cast<Expression *>(storage_.Create<PrimitiveLiteral>( return static_cast<Expression *>(storage_.Create<PrimitiveLiteral>(
ctx->numberLiteral()->accept(this).as<TypedValue>(), token_position)); ctx->numberLiteral()->accept(this).as<TypedValue>(), token_position));
} }
debug_fail("Expected to handle all cases above"); LOG(FATAL) << "Expected to handle all cases above";
} else if (ctx->listLiteral()) { } else if (ctx->listLiteral()) {
return static_cast<Expression *>(storage_.Create<ListLiteral>( return static_cast<Expression *>(storage_.Create<ListLiteral>(
ctx->listLiteral()->accept(this).as<std::vector<Expression *>>())); ctx->listLiteral()->accept(this).as<std::vector<Expression *>>()));
@ -903,7 +904,7 @@ antlrcpp::Any CypherMainVisitor::visitNumberLiteral(
} else { } else {
// This should never happen, except grammar changes and we don't notice // This should never happen, except grammar changes and we don't notice
// change in this production. // change in this production.
debug_assert(false, "can't happen"); DLOG(FATAL) << "can't happen";
throw std::exception(); throw std::exception();
} }
} }
@ -985,7 +986,7 @@ antlrcpp::Any CypherMainVisitor::visitBooleanLiteral(
if (ctx->getTokens(CypherParser::FALSE).size()) { if (ctx->getTokens(CypherParser::FALSE).size()) {
return false; return false;
} }
debug_assert(false, "Shouldn't happend"); DLOG(FATAL) << "Shouldn't happend";
throw std::exception(); throw std::exception();
} }
@ -1112,7 +1113,7 @@ antlrcpp::Any CypherMainVisitor::visitCaseExpression(
antlrcpp::Any CypherMainVisitor::visitCaseAlternatives( antlrcpp::Any CypherMainVisitor::visitCaseAlternatives(
CypherParser::CaseAlternativesContext *) { CypherParser::CaseAlternativesContext *) {
debug_fail("Should never be called. See documentation in hpp."); DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
@ -1138,7 +1139,7 @@ antlrcpp::Any CypherMainVisitor::visitMerge(CypherParser::MergeContext *ctx) {
if (merge_action->MATCH()) { if (merge_action->MATCH()) {
merge->on_match_.insert(merge->on_match_.end(), set.begin(), set.end()); merge->on_match_.insert(merge->on_match_.end(), set.begin(), set.end());
} else { } else {
debug_assert(merge_action->CREATE(), "Expected ON MATCH or ON CREATE"); DCHECK(merge_action->CREATE()) << "Expected ON MATCH or ON CREATE";
merge->on_create_.insert(merge->on_create_.end(), set.begin(), set.end()); merge->on_create_.insert(merge->on_create_.end(), set.begin(), set.end());
} }
} }
@ -1155,7 +1156,7 @@ antlrcpp::Any CypherMainVisitor::visitUnwind(CypherParser::UnwindContext *ctx) {
antlrcpp::Any CypherMainVisitor::visitFilterExpression( antlrcpp::Any CypherMainVisitor::visitFilterExpression(
CypherParser::FilterExpressionContext *) { CypherParser::FilterExpressionContext *) {
debug_fail("Should never be called. See documentation in hpp."); LOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }

View File

@ -5,6 +5,8 @@
#include <utility> #include <utility>
#include "antlr4-runtime.h" #include "antlr4-runtime.h"
#include "glog/logging.h"
#include "query/context.hpp" #include "query/context.hpp"
#include "query/frontend/ast/ast.hpp" #include "query/frontend/ast/ast.hpp"
#include "query/frontend/ast/named_antlr_tokens.hpp" #include "query/frontend/ast/named_antlr_tokens.hpp"
@ -14,8 +16,8 @@
namespace query { namespace query {
namespace frontend { namespace frontend {
using query::Context;
using antlropencypher::CypherParser; using antlropencypher::CypherParser;
using query::Context;
class CypherMainVisitor : public antlropencypher::CypherBaseVisitor { class CypherMainVisitor : public antlropencypher::CypherBaseVisitor {
public: public:
@ -100,7 +102,7 @@ class CypherMainVisitor : public antlropencypher::CypherBaseVisitor {
std::vector<TExpression *> _expressions, std::vector<TExpression *> _expressions,
std::vector<antlr4::tree::ParseTree *> all_children, std::vector<antlr4::tree::ParseTree *> all_children,
const std::vector<size_t> &allowed_operators) { const std::vector<size_t> &allowed_operators) {
debug_assert(_expressions.size(), "can't happen"); DCHECK(_expressions.size()) << "can't happen";
std::vector<Expression *> expressions; std::vector<Expression *> expressions;
auto operators = ExtractOperators(all_children, allowed_operators); auto operators = ExtractOperators(all_children, allowed_operators);
@ -121,7 +123,7 @@ class CypherMainVisitor : public antlropencypher::CypherBaseVisitor {
TExpression *_expression, TExpression *_expression,
std::vector<antlr4::tree::ParseTree *> all_children, std::vector<antlr4::tree::ParseTree *> all_children,
const std::vector<size_t> &allowed_operators) { const std::vector<size_t> &allowed_operators) {
debug_assert(_expression, "can't happen"); DCHECK(_expression) << "can't happen";
auto operators = ExtractOperators(all_children, allowed_operators); auto operators = ExtractOperators(all_children, allowed_operators);
Expression *expression = _expression->accept(this); Expression *expression = _expression->accept(this);
@ -575,5 +577,5 @@ class CypherMainVisitor : public antlropencypher::CypherBaseVisitor {
// return. // return.
bool in_with_ = false; bool in_with_ = false;
}; };
} } // namespace frontend
} } // namespace query

View File

@ -7,6 +7,8 @@
#include <experimental/optional> #include <experimental/optional>
#include <unordered_set> #include <unordered_set>
#include "glog/logging.h"
#include "utils/algorithm.hpp" #include "utils/algorithm.hpp"
namespace query { namespace query {
@ -298,8 +300,8 @@ bool SymbolGenerator::PreVisit(All &all) {
bool SymbolGenerator::PreVisit(Pattern &pattern) { bool SymbolGenerator::PreVisit(Pattern &pattern) {
scope_.in_pattern = true; scope_.in_pattern = true;
if ((scope_.in_create || scope_.in_merge) && pattern.atoms_.size() == 1U) { if ((scope_.in_create || scope_.in_merge) && pattern.atoms_.size() == 1U) {
debug_assert(dynamic_cast<NodeAtom *>(pattern.atoms_[0]), DCHECK(dynamic_cast<NodeAtom *>(pattern.atoms_[0]))
"Expected a single NodeAtom in Pattern"); << "Expected a single NodeAtom in Pattern";
scope_.in_create_node = true; scope_.in_create_node = true;
} }
return true; return true;

View File

@ -6,13 +6,14 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "query/common.hpp" #include "query/common.hpp"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "query/frontend/opencypher/generated/CypherBaseVisitor.h" #include "query/frontend/opencypher/generated/CypherBaseVisitor.h"
#include "query/frontend/opencypher/generated/CypherLexer.h" #include "query/frontend/opencypher/generated/CypherLexer.h"
#include "query/frontend/opencypher/generated/CypherParser.h" #include "query/frontend/opencypher/generated/CypherParser.h"
#include "query/frontend/stripped_lexer_constants.hpp" #include "query/frontend/stripped_lexer_constants.hpp"
#include "utils/assert.hpp"
#include "utils/hashing/fnv.hpp" #include "utils/hashing/fnv.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
@ -64,8 +65,9 @@ StrippedQuery::StrippedQuery(const std::string &query) : original_(query) {
// A helper function that stores literal and its token position in a // A helper function that stores literal and its token position in a
// literals_. In stripped query text literal is replaced with a new_value. // literals_. In stripped query text literal is replaced with a new_value.
// new_value can be any value that is lexed as a literal. // new_value can be any value that is lexed as a literal.
auto replace_stripped = [this, &token_strings]( auto replace_stripped = [this, &token_strings](int position,
int position, const TypedValue &value, const std::string &new_value) { const TypedValue &value,
const std::string &new_value) {
literals_.Add(position, value); literals_.Add(position, value);
token_strings.push_back(new_value); token_strings.push_back(new_value);
}; };
@ -88,7 +90,7 @@ StrippedQuery::StrippedQuery(const std::string &query) : original_(query) {
int token_index = token_strings.size() * 2 + parameters_.size(); int token_index = token_strings.size() * 2 + parameters_.size();
switch (token.first) { switch (token.first) {
case Token::UNMATCHED: case Token::UNMATCHED:
debug_assert(false, "Shouldn't happen"); LOG(FATAL) << "Shouldn't happen";
case Token::KEYWORD: { case Token::KEYWORD: {
token.second = utils::ToLowerCase(token.second); token.second = utils::ToLowerCase(token.second);
const auto &s = token.second; const auto &s = token.second;
@ -505,4 +507,4 @@ int StrippedQuery::MatchWhitespaceAndComments(int start) const {
if (state != State::OUT) return comment_position - start; if (state != State::OUT) return comment_position - start;
return i - start; return i - start;
} }
} } // namespace query

View File

@ -5,7 +5,6 @@
#include "query/parameters.hpp" #include "query/parameters.hpp"
#include "query/typed_value.hpp" #include "query/typed_value.hpp"
#include "utils/assert.hpp"
#include "utils/hashing/fnv.hpp" #include "utils/hashing/fnv.hpp"
namespace query { namespace query {
@ -90,4 +89,4 @@ class StrippedQuery {
// Hash based on the stripped query. // Hash based on the stripped query.
HashType hash_; HashType hash_;
}; };
} } // namespace query

View File

@ -535,7 +535,8 @@ TypedValue Counter(const std::vector<TypedValue> &args, GraphDbAccessor &dba) {
return dba.Counter(args[0].ValueString()); return dba.Counter(args[0].ValueString());
} }
TypedValue CounterSet(const std::vector<TypedValue> &args, GraphDbAccessor &dba) { TypedValue CounterSet(const std::vector<TypedValue> &args,
GraphDbAccessor &dba) {
if (args.size() != 2U) { if (args.size() != 2U) {
throw QueryRuntimeException("counterSet takes two arguments"); throw QueryRuntimeException("counterSet takes two arguments");
} }
@ -556,7 +557,7 @@ TypedValue IndexInfo(const std::vector<TypedValue> &args,
auto info = dba.IndexInfo(); auto info = dba.IndexInfo();
return std::vector<TypedValue>(info.begin(), info.end()); return std::vector<TypedValue>(info.begin(), info.end());
} }
} // annonymous namespace } // namespace
std::function<TypedValue(const std::vector<TypedValue> &, GraphDbAccessor &)> std::function<TypedValue(const std::vector<TypedValue> &, GraphDbAccessor &)>
NameToFunction(const std::string &function_name) { NameToFunction(const std::string &function_name) {

View File

@ -12,7 +12,6 @@
#include "query/frontend/semantic/symbol_table.hpp" #include "query/frontend/semantic/symbol_table.hpp"
#include "query/interpret/frame.hpp" #include "query/interpret/frame.hpp"
#include "query/typed_value.hpp" #include "query/typed_value.hpp"
#include "utils/assert.hpp"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
namespace query { namespace query {
@ -33,7 +32,7 @@ class ExpressionEvaluator : public TreeVisitor<TypedValue> {
#define BLOCK_VISIT(TREE_TYPE) \ #define BLOCK_VISIT(TREE_TYPE) \
TypedValue Visit(TREE_TYPE &) override { \ TypedValue Visit(TREE_TYPE &) override { \
permanent_fail("ExpressionEvaluator should not visit " #TREE_TYPE); \ LOG(FATAL) << "ExpressionEvaluator should not visit " #TREE_TYPE; \
} }
BLOCK_VISIT(Query); BLOCK_VISIT(Query);
@ -388,7 +387,7 @@ class ExpressionEvaluator : public TreeVisitor<TypedValue> {
vertex.SwitchOld(); vertex.SwitchOld();
break; break;
default: default:
permanent_fail("Unhandled GraphView enum"); LOG(FATAL) << "Unhandled GraphView enum";
} }
break; break;
} }
@ -402,7 +401,7 @@ class ExpressionEvaluator : public TreeVisitor<TypedValue> {
edge.SwitchOld(); edge.SwitchOld();
break; break;
default: default:
permanent_fail("Unhandled GraphView enum"); LOG(FATAL) << "Unhandled GraphView enum";
} }
break; break;
} }

View File

@ -39,8 +39,8 @@ struct Parameters {
[&](const std::pair<int, query::TypedValue> a) { [&](const std::pair<int, query::TypedValue> a) {
return a.first == position; return a.first == position;
}); });
permanent_assert(found != storage_.end(), CHECK(found != storage_.end())
"Token position must be present in container"); << "Token position must be present in container";
return found->second; return found->second;
} }
@ -52,8 +52,7 @@ struct Parameters {
* @return Token position and value for sought param. * @return Token position and value for sought param.
*/ */
const std::pair<int, query::TypedValue> &At(int position) const { const std::pair<int, query::TypedValue> &At(int position) const {
permanent_assert(position < static_cast<int>(storage_.size()), CHECK(position < static_cast<int>(storage_.size())) << "Invalid position";
"Invalid position");
return storage_[position]; return storage_[position];
} }

View File

@ -3,9 +3,10 @@
#include <functional> #include <functional>
#include <utility> #include <utility>
#include "glog/logging.h"
#include "storage/edge_accessor.hpp" #include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp" #include "storage/vertex_accessor.hpp"
#include "utils/assert.hpp"
namespace query { namespace query {
@ -29,15 +30,15 @@ class Path {
/** Expands the path with the given vertex. */ /** Expands the path with the given vertex. */
void Expand(const VertexAccessor &vertex) { void Expand(const VertexAccessor &vertex) {
debug_assert(vertices_.size() == edges_.size(), DCHECK(vertices_.size() == edges_.size())
"Illegal path construction order"); << "Illegal path construction order";
vertices_.emplace_back(vertex); vertices_.emplace_back(vertex);
} }
/** Expands the path with the given edge. */ /** Expands the path with the given edge. */
void Expand(const EdgeAccessor &edge) { void Expand(const EdgeAccessor &edge) {
debug_assert(vertices_.size() - 1 == edges_.size(), DCHECK(vertices_.size() - 1 == edges_.size())
"Illegal path construction order"); << "Illegal path construction order";
edges_.emplace_back(edge); edges_.emplace_back(edge);
} }
@ -61,8 +62,8 @@ class Path {
} }
friend std::ostream &operator<<(std::ostream &os, const Path &path) { friend std::ostream &operator<<(std::ostream &os, const Path &path) {
debug_assert(path.vertices_.size() > 0U, DCHECK(path.vertices_.size() > 0U)
"Attempting to stream out an invalid path"); << "Attempting to stream out an invalid path";
os << path.vertices_[0]; os << path.vertices_[0];
for (int i = 0; i < static_cast<int>(path.edges_.size()); i++) { for (int i = 0; i < static_cast<int>(path.edges_.size()); i++) {
bool arrow_to_left = path.vertices_[i] == path.edges_[i].to(); bool arrow_to_left = path.vertices_[i] == path.edges_[i].to();

View File

@ -3,13 +3,15 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include "query/plan/operator.hpp" #include "glog/logging.h"
#include "query/context.hpp" #include "query/context.hpp"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "query/frontend/ast/ast.hpp" #include "query/frontend/ast/ast.hpp"
#include "query/interpret/eval.hpp" #include "query/interpret/eval.hpp"
#include "query/plan/operator.hpp"
// macro for the default implementation of LogicalOperator::Accept // macro for the default implementation of LogicalOperator::Accept
// that accepts the visitor and visits it's input_ operator // that accepts the visitor and visits it's input_ operator
#define ACCEPT_WITH_INPUT(class_name) \ #define ACCEPT_WITH_INPUT(class_name) \
@ -251,8 +253,8 @@ ScanAll::ScanAll(const std::shared_ptr<LogicalOperator> &input,
: input_(input ? input : std::make_shared<Once>()), : input_(input ? input : std::make_shared<Once>()),
output_symbol_(output_symbol), output_symbol_(output_symbol),
graph_view_(graph_view) { graph_view_(graph_view) {
permanent_assert(graph_view != GraphView::AS_IS, CHECK(graph_view != GraphView::AS_IS)
"ScanAll must have explicitly defined GraphView"); << "ScanAll must have explicitly defined GraphView";
} }
ACCEPT_WITH_INPUT(ScanAll) ACCEPT_WITH_INPUT(ScanAll)
@ -290,7 +292,7 @@ ScanAllByLabelPropertyRange::ScanAllByLabelPropertyRange(
property_(property), property_(property),
lower_bound_(lower_bound), lower_bound_(lower_bound),
upper_bound_(upper_bound) { upper_bound_(upper_bound) {
debug_assert(lower_bound_ || upper_bound_, "Only one bound can be left out"); DCHECK(lower_bound_ || upper_bound_) << "Only one bound can be left out";
} }
ACCEPT_WITH_INPUT(ScanAllByLabelPropertyRange) ACCEPT_WITH_INPUT(ScanAllByLabelPropertyRange)
@ -321,7 +323,7 @@ ScanAllByLabelPropertyValue::ScanAllByLabelPropertyValue(
label_(label), label_(label),
property_(property), property_(property),
expression_(expression) { expression_(expression) {
debug_assert(expression, "Expression is not optional."); DCHECK(expression) << "Expression is not optional.";
} }
ACCEPT_WITH_INPUT(ScanAllByLabelPropertyValue) ACCEPT_WITH_INPUT(ScanAllByLabelPropertyValue)
@ -430,7 +432,7 @@ bool Expand::ExpandCursor::Pull(Frame &frame, Context &context) {
frame[self_.node_symbol_] = new_edge.to(); frame[self_.node_symbol_] = new_edge.to();
break; break;
case EdgeAtom::Direction::BOTH: case EdgeAtom::Direction::BOTH:
permanent_fail("Must indicate exact expansion direction here"); LOG(FATAL) << "Must indicate exact expansion direction here";
} }
}; };
@ -561,12 +563,11 @@ ExpandVariable::ExpandVariable(
inner_edge_symbol_(inner_edge_symbol), inner_edge_symbol_(inner_edge_symbol),
inner_node_symbol_(inner_node_symbol), inner_node_symbol_(inner_node_symbol),
filter_(filter) { filter_(filter) {
debug_assert( DCHECK(type_ == EdgeAtom::Type::DEPTH_FIRST ||
type_ == EdgeAtom::Type::DEPTH_FIRST || type_ == EdgeAtom::Type::BREADTH_FIRST)
type_ == EdgeAtom::Type::BREADTH_FIRST, << "ExpandVariable can only be used with breadth or depth first type";
"ExpandVariable can only be used with breadth or depth first type"); DCHECK(!(type_ == EdgeAtom::Type::BREADTH_FIRST && is_reverse))
debug_assert(!(type_ == EdgeAtom::Type::BREADTH_FIRST && is_reverse), << "Breadth first expansion can't be reversed";
"Breadth first expansion can't be reversed");
} }
ACCEPT_WITH_INPUT(ExpandVariable) ACCEPT_WITH_INPUT(ExpandVariable)
@ -747,7 +748,7 @@ class ExpandVariableCursor : public Cursor {
std::vector<TypedValue> &edges_on_frame) { std::vector<TypedValue> &edges_on_frame) {
// We are placing an edge on the frame. It is possible that there already // We are placing an edge on the frame. It is possible that there already
// exists an edge on the frame for this level. If so first remove it. // exists an edge on the frame for this level. If so first remove it.
debug_assert(edges_.size() > 0, "Edges are empty"); DCHECK(edges_.size() > 0) << "Edges are empty";
if (self_.is_reverse_) { if (self_.is_reverse_) {
// TODO: This is innefficient, we should look into replacing // TODO: This is innefficient, we should look into replacing
// vector with something else for TypedValue::List. // vector with something else for TypedValue::List.
@ -1027,8 +1028,8 @@ class ConstructNamedPathCursor : public Cursor {
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
auto symbol_it = self_.path_elements().begin(); auto symbol_it = self_.path_elements().begin();
debug_assert(symbol_it != self_.path_elements().end(), DCHECK(symbol_it != self_.path_elements().end())
"Named path must contain at least one node"); << "Named path must contain at least one node";
TypedValue start_vertex = frame[*symbol_it++]; TypedValue start_vertex = frame[*symbol_it++];
@ -1038,8 +1039,8 @@ class ConstructNamedPathCursor : public Cursor {
return true; return true;
} }
debug_assert(start_vertex.IsVertex(), DCHECK(start_vertex.IsVertex())
"First named path element must be a vertex"); << "First named path element must be a vertex";
query::Path path(start_vertex.ValueVertex()); query::Path path(start_vertex.ValueVertex());
// If the last path element symbol was for an edge list, then // If the last path element symbol was for an edge list, then
@ -1079,7 +1080,7 @@ class ConstructNamedPathCursor : public Cursor {
break; break;
} }
default: default:
permanent_fail("Unsupported type in named path construction"); LOG(FATAL) << "Unsupported type in named path construction";
break; break;
} }
@ -1763,12 +1764,12 @@ void Aggregate::AggregateCursor::EnsureInitialized(
void Aggregate::AggregateCursor::Update( void Aggregate::AggregateCursor::Update(
Frame &, const SymbolTable &, ExpressionEvaluator &evaluator, Frame &, const SymbolTable &, ExpressionEvaluator &evaluator,
Aggregate::AggregateCursor::AggregationValue &agg_value) { Aggregate::AggregateCursor::AggregationValue &agg_value) {
debug_assert(self_.aggregations_.size() == agg_value.values_.size(), DCHECK(self_.aggregations_.size() == agg_value.values_.size())
"Expected as much AggregationValue.values_ as there are " << "Expected as much AggregationValue.values_ as there are "
"aggregations."); "aggregations.";
debug_assert(self_.aggregations_.size() == agg_value.counts_.size(), DCHECK(self_.aggregations_.size() == agg_value.counts_.size())
"Expected as much AggregationValue.counts_ as there are " << "Expected as much AggregationValue.counts_ as there are "
"aggregations."); "aggregations.";
// we iterate over counts, values and aggregation info at the same time // we iterate over counts, values and aggregation info at the same time
auto count_it = agg_value.counts_.begin(); auto count_it = agg_value.counts_.begin();
@ -1909,9 +1910,9 @@ void Aggregate::AggregateCursor::EnsureOkForAvgSum(
bool TypedValueVectorEqual::operator()( bool TypedValueVectorEqual::operator()(
const std::vector<TypedValue> &left, const std::vector<TypedValue> &left,
const std::vector<TypedValue> &right) const { const std::vector<TypedValue> &right) const {
debug_assert(left.size() == right.size(), DCHECK(left.size() == right.size())
"TypedValueVector comparison should only be done over vectors " << "TypedValueVector comparison should only be done over vectors "
"of the same size"); "of the same size";
return std::equal(left.begin(), left.end(), right.begin(), return std::equal(left.begin(), left.end(), right.begin(),
TypedValue::BoolEqual{}); TypedValue::BoolEqual{});
} }
@ -2075,9 +2076,9 @@ bool OrderBy::OrderByCursor::Pull(Frame &frame, Context &context) {
if (cache_it_ == cache_.end()) return false; if (cache_it_ == cache_.end()) return false;
// place the output values on the frame // place the output values on the frame
debug_assert(self_.output_symbols_.size() == cache_it_->second.size(), DCHECK(self_.output_symbols_.size() == cache_it_->second.size())
"Number of values does not match the number of output symbols " << "Number of values does not match the number of output symbols "
"in OrderBy"); "in OrderBy";
auto output_sym_it = self_.output_symbols_.begin(); auto output_sym_it = self_.output_symbols_.begin();
for (const TypedValue &output : cache_it_->second) for (const TypedValue &output : cache_it_->second)
frame[*output_sym_it++] = output; frame[*output_sym_it++] = output;
@ -2131,7 +2132,7 @@ bool OrderBy::TypedValueCompare(const TypedValue &a, const TypedValue &b) {
throw QueryRuntimeException( throw QueryRuntimeException(
"Comparison is not defined for values of type {}", a.type()); "Comparison is not defined for values of type {}", a.type());
default: default:
permanent_fail("Unhandled comparison for types"); LOG(FATAL) << "Unhandled comparison for types";
} }
} }
@ -2140,8 +2141,8 @@ bool OrderBy::TypedValueVectorCompare::operator()(
const std::vector<TypedValue> &c2) const { const std::vector<TypedValue> &c2) const {
// ordering is invalid if there are more elements in the collections // ordering is invalid if there are more elements in the collections
// then there are in the ordering_ vector // then there are in the ordering_ vector
debug_assert(c1.size() <= ordering_.size() && c2.size() <= ordering_.size(), DCHECK(c1.size() <= ordering_.size() && c2.size() <= ordering_.size())
"Collections contain more elements then there are orderings"); << "Collections contain more elements then there are orderings";
auto c1_it = c1.begin(); auto c1_it = c1.begin();
auto c2_it = c2.begin(); auto c2_it = c2.begin();
@ -2208,7 +2209,7 @@ bool Merge::MergeCursor::Pull(Frame &frame, Context &context) {
// and failed to pull from merge_match, we should create // and failed to pull from merge_match, we should create
__attribute__((unused)) bool merge_create_pull_result = __attribute__((unused)) bool merge_create_pull_result =
merge_create_cursor_->Pull(frame, context); merge_create_cursor_->Pull(frame, context);
debug_assert(merge_create_pull_result, "MergeCreate must never fail"); DCHECK(merge_create_pull_result) << "MergeCreate must never fail";
return true; return true;
} }
// we have exhausted merge_match_cursor_ after 1 or more successful // we have exhausted merge_match_cursor_ after 1 or more successful

View File

@ -43,20 +43,20 @@ template <typename T>
auto ReducePattern( auto ReducePattern(
Pattern &pattern, std::function<T(NodeAtom *)> base, Pattern &pattern, std::function<T(NodeAtom *)> base,
std::function<T(T, NodeAtom *, EdgeAtom *, NodeAtom *)> collect) { std::function<T(T, NodeAtom *, EdgeAtom *, NodeAtom *)> collect) {
debug_assert(!pattern.atoms_.empty(), "Missing atoms in pattern"); DCHECK(!pattern.atoms_.empty()) << "Missing atoms in pattern";
auto atoms_it = pattern.atoms_.begin(); auto atoms_it = pattern.atoms_.begin();
auto current_node = dynamic_cast<NodeAtom *>(*atoms_it++); auto current_node = dynamic_cast<NodeAtom *>(*atoms_it++);
debug_assert(current_node, "First pattern atom is not a node"); DCHECK(current_node) << "First pattern atom is not a node";
auto last_res = base(current_node); auto last_res = base(current_node);
// Remaining atoms need to follow sequentially as (EdgeAtom, NodeAtom)* // Remaining atoms need to follow sequentially as (EdgeAtom, NodeAtom)*
while (atoms_it != pattern.atoms_.end()) { while (atoms_it != pattern.atoms_.end()) {
auto edge = dynamic_cast<EdgeAtom *>(*atoms_it++); auto edge = dynamic_cast<EdgeAtom *>(*atoms_it++);
debug_assert(edge, "Expected an edge atom in pattern."); DCHECK(edge) << "Expected an edge atom in pattern.";
debug_assert(atoms_it != pattern.atoms_.end(), DCHECK(atoms_it != pattern.atoms_.end())
"Edge atom should not end the pattern."); << "Edge atom should not end the pattern.";
auto prev_node = current_node; auto prev_node = current_node;
current_node = dynamic_cast<NodeAtom *>(*atoms_it++); current_node = dynamic_cast<NodeAtom *>(*atoms_it++);
debug_assert(current_node, "Expected a node atom in pattern."); DCHECK(current_node) << "Expected a node atom in pattern.";
last_res = collect(last_res, prev_node, edge, current_node); last_res = collect(last_res, prev_node, edge, current_node);
} }
return last_res; return last_res;
@ -65,20 +65,20 @@ auto ReducePattern(
void ForEachPattern( void ForEachPattern(
Pattern &pattern, std::function<void(NodeAtom *)> base, Pattern &pattern, std::function<void(NodeAtom *)> base,
std::function<void(NodeAtom *, EdgeAtom *, NodeAtom *)> collect) { std::function<void(NodeAtom *, EdgeAtom *, NodeAtom *)> collect) {
debug_assert(!pattern.atoms_.empty(), "Missing atoms in pattern"); DCHECK(!pattern.atoms_.empty()) << "Missing atoms in pattern";
auto atoms_it = pattern.atoms_.begin(); auto atoms_it = pattern.atoms_.begin();
auto current_node = dynamic_cast<NodeAtom *>(*atoms_it++); auto current_node = dynamic_cast<NodeAtom *>(*atoms_it++);
debug_assert(current_node, "First pattern atom is not a node"); DCHECK(current_node) << "First pattern atom is not a node";
base(current_node); base(current_node);
// Remaining atoms need to follow sequentially as (EdgeAtom, NodeAtom)* // Remaining atoms need to follow sequentially as (EdgeAtom, NodeAtom)*
while (atoms_it != pattern.atoms_.end()) { while (atoms_it != pattern.atoms_.end()) {
auto edge = dynamic_cast<EdgeAtom *>(*atoms_it++); auto edge = dynamic_cast<EdgeAtom *>(*atoms_it++);
debug_assert(edge, "Expected an edge atom in pattern."); DCHECK(edge) << "Expected an edge atom in pattern.";
debug_assert(atoms_it != pattern.atoms_.end(), DCHECK(atoms_it != pattern.atoms_.end())
"Edge atom should not end the pattern."); << "Edge atom should not end the pattern.";
auto prev_node = current_node; auto prev_node = current_node;
current_node = dynamic_cast<NodeAtom *>(*atoms_it++); current_node = dynamic_cast<NodeAtom *>(*atoms_it++);
debug_assert(current_node, "Expected a node atom in pattern."); DCHECK(current_node) << "Expected a node atom in pattern.";
collect(prev_node, edge, current_node); collect(prev_node, edge, current_node);
} }
} }
@ -100,8 +100,8 @@ class UsedSymbolsCollector : public HierarchicalTreeVisitor {
explicit UsedSymbolsCollector(const SymbolTable &symbol_table) explicit UsedSymbolsCollector(const SymbolTable &symbol_table)
: symbol_table_(symbol_table) {} : symbol_table_(symbol_table) {}
using HierarchicalTreeVisitor::PreVisit;
using HierarchicalTreeVisitor::PostVisit; using HierarchicalTreeVisitor::PostVisit;
using HierarchicalTreeVisitor::PreVisit;
using HierarchicalTreeVisitor::Visit; using HierarchicalTreeVisitor::Visit;
bool PostVisit(All &all) override { bool PostVisit(All &all) override {
@ -181,14 +181,14 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
if (where) { if (where) {
where->Accept(*this); where->Accept(*this);
} }
debug_assert(aggregations_.empty(), DCHECK(aggregations_.empty())
"Unexpected aggregations in ORDER BY or WHERE"); << "Unexpected aggregations in ORDER BY or WHERE";
} }
} }
using HierarchicalTreeVisitor::PostVisit;
using HierarchicalTreeVisitor::PreVisit; using HierarchicalTreeVisitor::PreVisit;
using HierarchicalTreeVisitor::Visit; using HierarchicalTreeVisitor::Visit;
using HierarchicalTreeVisitor::PostVisit;
bool Visit(PrimitiveLiteral &) override { bool Visit(PrimitiveLiteral &) override {
has_aggregation_.emplace_back(false); has_aggregation_.emplace_back(false);
@ -196,9 +196,9 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
} }
bool PostVisit(ListLiteral &list_literal) override { bool PostVisit(ListLiteral &list_literal) override {
debug_assert( DCHECK(list_literal.elements_.size() <= has_aggregation_.size())
list_literal.elements_.size() <= has_aggregation_.size(), << "Expected has_aggregation_ flags as much as there are list "
"Expected has_aggregation_ flags as much as there are list elements."); "elements.";
bool has_aggr = false; bool has_aggr = false;
auto it = has_aggregation_.end(); auto it = has_aggregation_.end();
std::advance(it, -list_literal.elements_.size()); std::advance(it, -list_literal.elements_.size());
@ -211,9 +211,8 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
} }
bool PostVisit(MapLiteral &map_literal) override { bool PostVisit(MapLiteral &map_literal) override {
debug_assert( DCHECK(map_literal.elements_.size() <= has_aggregation_.size())
map_literal.elements_.size() <= has_aggregation_.size(), << "Expected has_aggregation_ flags as much as there are map elements.";
"Expected has_aggregation_ flags as much as there are map elements.");
bool has_aggr = false; bool has_aggr = false;
auto it = has_aggregation_.end(); auto it = has_aggregation_.end();
std::advance(it, -map_literal.elements_.size()); std::advance(it, -map_literal.elements_.size());
@ -229,8 +228,8 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
// Remove the symbol which is bound by all, because we are only interested // Remove the symbol which is bound by all, because we are only interested
// in free (unbound) symbols. // in free (unbound) symbols.
used_symbols_.erase(symbol_table_.at(*all.identifier_)); used_symbols_.erase(symbol_table_.at(*all.identifier_));
debug_assert(has_aggregation_.size() >= 3U, DCHECK(has_aggregation_.size() >= 3U)
"Expected 3 has_aggregation_ flags for ALL arguments"); << "Expected 3 has_aggregation_ flags for ALL arguments";
bool has_aggr = false; bool has_aggr = false;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
has_aggr = has_aggr || has_aggregation_.back(); has_aggr = has_aggr || has_aggregation_.back();
@ -289,14 +288,14 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
has_aggregation_.emplace_back(has_aggr); has_aggregation_.emplace_back(has_aggr);
// TODO: Once we allow aggregations here, insert appropriate stuff in // TODO: Once we allow aggregations here, insert appropriate stuff in
// group_by. // group_by.
debug_assert(!has_aggr, "Currently aggregations in CASE are not allowed"); DCHECK(!has_aggr) << "Currently aggregations in CASE are not allowed";
return false; return false;
} }
bool PostVisit(Function &function) override { bool PostVisit(Function &function) override {
debug_assert(function.arguments_.size() <= has_aggregation_.size(), DCHECK(function.arguments_.size() <= has_aggregation_.size())
"Expected has_aggregation_ flags as much as there are " << "Expected has_aggregation_ flags as much as there are "
"function arguments."); "function arguments.";
bool has_aggr = false; bool has_aggr = false;
auto it = has_aggregation_.end(); auto it = has_aggregation_.end();
std::advance(it, -function.arguments_.size()); std::advance(it, -function.arguments_.size());
@ -310,8 +309,8 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
#define VISIT_BINARY_OPERATOR(BinaryOperator) \ #define VISIT_BINARY_OPERATOR(BinaryOperator) \
bool PostVisit(BinaryOperator &op) override { \ bool PostVisit(BinaryOperator &op) override { \
debug_assert(has_aggregation_.size() >= 2U, \ DCHECK(has_aggregation_.size() >= 2U) \
"Expected at least 2 has_aggregation_ flags."); \ << "Expected at least 2 has_aggregation_ flags."; \
/* has_aggregation_ stack is reversed, last result is from the 2nd */ \ /* has_aggregation_ stack is reversed, last result is from the 2nd */ \
/* expression. */ \ /* expression. */ \
bool aggr2 = has_aggregation_.back(); \ bool aggr2 = has_aggregation_.back(); \
@ -368,8 +367,8 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
} }
bool PostVisit(NamedExpression &named_expr) override { bool PostVisit(NamedExpression &named_expr) override {
debug_assert(has_aggregation_.size() == 1U, DCHECK(has_aggregation_.size() == 1U)
"Expected to reduce has_aggregation_ to single boolean."); << "Expected to reduce has_aggregation_ to single boolean.";
if (!has_aggregation_.back()) { if (!has_aggregation_.back()) {
group_by_.emplace_back(named_expr.expression_); group_by_.emplace_back(named_expr.expression_);
} }
@ -391,11 +390,10 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
// This should be used when body.all_identifiers is true, to generate // This should be used when body.all_identifiers is true, to generate
// expressions for Produce operator. // expressions for Produce operator.
void ExpandUserSymbols() { void ExpandUserSymbols() {
debug_assert( DCHECK(named_expressions_.empty())
named_expressions_.empty(), << "ExpandUserSymbols should be first to fill named_expressions_";
"ExpandUserSymbols should be first to fill named_expressions_"); DCHECK(output_symbols_.empty())
debug_assert(output_symbols_.empty(), << "ExpandUserSymbols should be first to fill output_symbols_";
"ExpandUserSymbols should be first to fill output_symbols_");
for (const auto &symbol : bound_symbols_) { for (const auto &symbol : bound_symbols_) {
if (!symbol.user_declared()) { if (!symbol.user_declared()) {
continue; continue;
@ -536,7 +534,7 @@ std::vector<Expansion> NormalizePatterns(
for (const auto &pattern : patterns) { for (const auto &pattern : patterns) {
if (pattern->atoms_.size() == 1U) { if (pattern->atoms_.size() == 1U) {
auto *node = dynamic_cast<NodeAtom *>(pattern->atoms_[0]); auto *node = dynamic_cast<NodeAtom *>(pattern->atoms_[0]);
debug_assert(node, "First pattern atom is not a node"); DCHECK(node) << "First pattern atom is not a node";
expansions.emplace_back(Expansion{node}); expansions.emplace_back(Expansion{node});
} else { } else {
ForEachPattern(*pattern, ignore_node, collect_expansion); ForEachPattern(*pattern, ignore_node, collect_expansion);
@ -719,7 +717,7 @@ LogicalOperator *GenCreateForPattern(
node_existing = true; node_existing = true;
} }
if (!BindSymbol(bound_symbols, symbol_table.at(*edge->identifier_))) { if (!BindSymbol(bound_symbols, symbol_table.at(*edge->identifier_))) {
permanent_fail("Symbols used for created edges cannot be redeclared."); LOG(FATAL) << "Symbols used for created edges cannot be redeclared.";
} }
return new CreateExpand(node, edge, return new CreateExpand(node, edge,
std::shared_ptr<LogicalOperator>(last_op), std::shared_ptr<LogicalOperator>(last_op),
@ -1004,8 +1002,8 @@ std::vector<QueryPart> CollectQueryParts(SymbolTable &symbol_table,
AddMatching(*match, symbol_table, storage, AddMatching(*match, symbol_table, storage,
query_part->optional_matching.back()); query_part->optional_matching.back());
} else { } else {
debug_assert(query_part->optional_matching.empty(), DCHECK(query_part->optional_matching.empty())
"Match clause cannot follow optional match."); << "Match clause cannot follow optional match.";
AddMatching(*match, symbol_table, storage, query_part->matching); AddMatching(*match, symbol_table, storage, query_part->matching);
} }
} else { } else {

View File

@ -300,8 +300,8 @@ class RuleBasedPlanner {
} }
int merge_id = 0; int merge_id = 0;
for (auto &clause : query_part.remaining_clauses) { for (auto &clause : query_part.remaining_clauses) {
debug_assert(dynamic_cast<Match *>(clause) == nullptr, DCHECK(dynamic_cast<Match *>(clause) == nullptr)
"Unexpected Match in remaining clauses"); << "Unexpected Match in remaining clauses";
if (auto *ret = dynamic_cast<Return *>(clause)) { if (auto *ret = dynamic_cast<Return *>(clause)) {
input_op = input_op =
impl::GenReturn(*ret, input_op, context.symbol_table, is_write, impl::GenReturn(*ret, input_op, context.symbol_table, is_write,
@ -332,7 +332,7 @@ class RuleBasedPlanner {
unwind->named_expression_->expression_, symbol); unwind->named_expression_->expression_, symbol);
} else if (auto *create_index = } else if (auto *create_index =
dynamic_cast<query::CreateIndex *>(clause)) { dynamic_cast<query::CreateIndex *>(clause)) {
debug_assert(!input_op, "Unexpected operator before CreateIndex"); DCHECK(!input_op) << "Unexpected operator before CreateIndex";
input_op = new plan::CreateIndex(create_index->label_, input_op = new plan::CreateIndex(create_index->label_,
create_index->property_); create_index->property_);
} else { } else {
@ -403,8 +403,8 @@ class RuleBasedPlanner {
const GraphDbTypes::Label &FindBestLabelIndex( const GraphDbTypes::Label &FindBestLabelIndex(
const std::unordered_set<GraphDbTypes::Label> &labels) { const std::unordered_set<GraphDbTypes::Label> &labels) {
debug_assert(!labels.empty(), DCHECK(!labels.empty())
"Trying to find the best label without any labels."); << "Trying to find the best label without any labels.";
return *std::min_element(labels.begin(), labels.end(), return *std::min_element(labels.begin(), labels.end(),
[this](const auto &label1, const auto &label2) { [this](const auto &label1, const auto &label2) {
return context_.db.VerticesCount(label1) < return context_.db.VerticesCount(label1) <
@ -454,9 +454,8 @@ class RuleBasedPlanner {
best_property.first, prop_filter.lower_bound, best_property.first, prop_filter.lower_bound,
prop_filter.upper_bound, match_ctx.graph_view); prop_filter.upper_bound, match_ctx.graph_view);
} else { } else {
debug_assert( DCHECK(prop_filter.expression)
prop_filter.expression, << "Property filter should either have bounds or an expression.";
"Property filter should either have bounds or an expression.");
return new ScanAllByLabelPropertyValue( return new ScanAllByLabelPropertyValue(
std::shared_ptr<LogicalOperator>(last_op), node_symbol, best_label, std::shared_ptr<LogicalOperator>(last_op), node_symbol, best_label,
best_property.first, prop_filter.expression, match_ctx.graph_view); best_property.first, prop_filter.expression, match_ctx.graph_view);
@ -519,8 +518,8 @@ class RuleBasedPlanner {
symbol_table.at(*expansion.node2->identifier_); symbol_table.at(*expansion.node2->identifier_);
auto existing_node = utils::Contains(bound_symbols, node_symbol); auto existing_node = utils::Contains(bound_symbols, node_symbol);
const auto &edge_symbol = symbol_table.at(*edge->identifier_); const auto &edge_symbol = symbol_table.at(*edge->identifier_);
debug_assert(!utils::Contains(bound_symbols, edge_symbol), DCHECK(!utils::Contains(bound_symbols, edge_symbol))
"Existing edges are not supported"); << "Existing edges are not supported";
if (edge->IsVariable()) { if (edge->IsVariable()) {
Symbol inner_edge_symbol = symbol_table.at(*edge->inner_edge_); Symbol inner_edge_symbol = symbol_table.at(*edge->inner_edge_);
Symbol inner_node_symbol = symbol_table.at(*edge->inner_node_); Symbol inner_node_symbol = symbol_table.at(*edge->inner_node_);
@ -531,8 +530,8 @@ class RuleBasedPlanner {
impl::BindSymbol(bound_symbols, inner_edge_symbol); impl::BindSymbol(bound_symbols, inner_edge_symbol);
bool inner_node_bound = bool inner_node_bound =
impl::BindSymbol(bound_symbols, inner_node_symbol); impl::BindSymbol(bound_symbols, inner_node_symbol);
debug_assert(inner_edge_bound && inner_node_bound, DCHECK(inner_edge_bound && inner_node_bound)
"An inner edge and node can't be bound from before"); << "An inner edge and node can't be bound from before";
} }
auto *filter_expr = impl::BoolJoin<AndOperator>( auto *filter_expr = impl::BoolJoin<AndOperator>(
storage, storage,
@ -614,7 +613,7 @@ class RuleBasedPlanner {
impl::GenFilters(last_op, bound_symbols, all_filters, storage); impl::GenFilters(last_op, bound_symbols, all_filters, storage);
} }
} }
debug_assert(all_filters.empty(), "Expected to generate all filters"); DCHECK(all_filters.empty()) << "Expected to generate all filters";
return last_op; return last_op;
} }
@ -633,12 +632,12 @@ class RuleBasedPlanner {
for (auto &set : merge.on_create_) { for (auto &set : merge.on_create_) {
on_create = impl::HandleWriteClause(set, on_create, context_.symbol_table, on_create = impl::HandleWriteClause(set, on_create, context_.symbol_table,
context_.bound_symbols); context_.bound_symbols);
debug_assert(on_create, "Expected SET in MERGE ... ON CREATE"); DCHECK(on_create) << "Expected SET in MERGE ... ON CREATE";
} }
for (auto &set : merge.on_match_) { for (auto &set : merge.on_match_) {
on_match = impl::HandleWriteClause(set, on_match, context_.symbol_table, on_match = impl::HandleWriteClause(set, on_match, context_.symbol_table,
context_.bound_symbols); context_.bound_symbols);
debug_assert(on_match, "Expected SET in MERGE ... ON MATCH"); DCHECK(on_match) << "Expected SET in MERGE ... ON MATCH";
} }
return new plan::Merge(std::shared_ptr<LogicalOperator>(input_op), return new plan::Merge(std::shared_ptr<LogicalOperator>(input_op),
std::shared_ptr<LogicalOperator>(on_match), std::shared_ptr<LogicalOperator>(on_match),

View File

@ -3,6 +3,8 @@
#include <limits> #include <limits>
#include <queue> #include <queue>
#include "glog/logging.h"
#include "utils/flag_validation.hpp" #include "utils/flag_validation.hpp"
DEFINE_VALIDATED_HIDDEN_uint64( DEFINE_VALIDATED_HIDDEN_uint64(
@ -89,10 +91,9 @@ void AddNextExpansions(
} }
if (symbol_table.at(*expansion.node1->identifier_) != node_symbol) { if (symbol_table.at(*expansion.node1->identifier_) != node_symbol) {
// We are not expanding from node1, so flip the expansion. // We are not expanding from node1, so flip the expansion.
debug_assert( DCHECK(expansion.node2 &&
expansion.node2 && symbol_table.at(*expansion.node2->identifier_) == node_symbol)
symbol_table.at(*expansion.node2->identifier_) == node_symbol, << "Expected node_symbol to be bound in node2";
"Expected node_symbol to be bound in node2");
if (expansion.edge->type_ != EdgeAtom::Type::BREADTH_FIRST) { if (expansion.edge->type_ != EdgeAtom::Type::BREADTH_FIRST) {
// BFS must *not* be flipped. Doing that changes the BFS results. // BFS must *not* be flipped. Doing that changes the BFS results.
std::swap(expansion.node1, expansion.node2); std::swap(expansion.node1, expansion.node2);
@ -214,9 +215,9 @@ class VaryMatchingStart {
current_matching_.expansions = ExpansionsFrom( current_matching_.expansions = ExpansionsFrom(
**start_nodes_it_, self_.matching_, self_.symbol_table_); **start_nodes_it_, self_.matching_, self_.symbol_table_);
} }
debug_assert( DCHECK(start_nodes_it_ || self_.nodes_.empty())
start_nodes_it_ || self_.nodes_.empty(), << "start_nodes_it_ should only be nullopt when self_.nodes_ is "
"start_nodes_it_ should only be nullopt when self_.nodes_ is empty"); "empty";
if (is_done) { if (is_done) {
start_nodes_it_ = self.nodes_.end(); start_nodes_it_ = self.nodes_.end();
} }
@ -224,9 +225,9 @@ class VaryMatchingStart {
iterator &operator++() { iterator &operator++() {
if (!start_nodes_it_) { if (!start_nodes_it_) {
debug_assert(self_.nodes_.empty(), DCHECK(self_.nodes_.empty())
"start_nodes_it_ should only be nullopt when self_.nodes_ " << "start_nodes_it_ should only be nullopt when self_.nodes_ "
"is empty"); "is empty";
start_nodes_it_ = self_.nodes_.end(); start_nodes_it_ = self_.nodes_.end();
} }
if (*start_nodes_it_ == self_.nodes_.end()) { if (*start_nodes_it_ == self_.nodes_.end()) {

View File

@ -81,9 +81,8 @@ class CartesianProduct {
sets_it->second++; sets_it->second++;
} }
// We can now collect another product from the modified set iterators. // We can now collect another product from the modified set iterators.
debug_assert( DCHECK(current_product_.size() == sets_.size())
current_product_.size() == sets_.size(), << "Expected size of current_product_ to match the size of sets_";
"Expected size of current_product_ to match the size of sets_");
size_t i = 0; size_t i = 0;
// Change only the prefix of the product, remaining elements (after // Change only the prefix of the product, remaining elements (after
// sets_it) should be the same. // sets_it) should be the same.

View File

@ -5,8 +5,9 @@
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include "glog/logging.h"
#include "utils/algorithm.hpp" #include "utils/algorithm.hpp"
#include "utils/assert.hpp"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
#include "utils/hashing/fnv.hpp" #include "utils/hashing/fnv.hpp"
@ -46,7 +47,7 @@ TypedValue::TypedValue(const PropertyValue &value) {
return; return;
} }
} }
permanent_fail("Unsupported type"); LOG(FATAL) << "Unsupported type";
} }
TypedValue::TypedValue(const TypedValue &other) : type_(other.type_) { TypedValue::TypedValue(const TypedValue &other) : type_(other.type_) {
@ -81,7 +82,7 @@ TypedValue::TypedValue(const TypedValue &other) : type_(other.type_) {
new (&path_v) Path(other.path_v); new (&path_v) Path(other.path_v);
return; return;
} }
permanent_fail("Unsupported TypedValue::Type"); LOG(FATAL) << "Unsupported TypedValue::Type";
} }
TypedValue::operator PropertyValue() const { TypedValue::operator PropertyValue() const {
@ -186,7 +187,7 @@ std::ostream &operator<<(std::ostream &os, const TypedValue::Type type) {
case TypedValue::Type::Path: case TypedValue::Type::Path:
return os << "path"; return os << "path";
} }
permanent_fail("Unsupported TypedValue::Type"); LOG(FATAL) << "Unsupported TypedValue::Type";
} }
std::ostream &operator<<(std::ostream &os, const TypedValue &value) { std::ostream &operator<<(std::ostream &os, const TypedValue &value) {
@ -219,7 +220,7 @@ std::ostream &operator<<(std::ostream &os, const TypedValue &value) {
case TypedValue::Type::Path: case TypedValue::Type::Path:
return os << value.Value<Path>(); return os << value.Value<Path>();
} }
permanent_fail("Unsupported PropertyValue::Type"); LOG(FATAL) << "Unsupported PropertyValue::Type";
} }
TypedValue &TypedValue::operator=(const TypedValue &other) { TypedValue &TypedValue::operator=(const TypedValue &other) {
@ -259,7 +260,7 @@ TypedValue &TypedValue::operator=(const TypedValue &other) {
new (&path_v) Path(other.path_v); new (&path_v) Path(other.path_v);
return *this; return *this;
} }
permanent_fail("Unsupported TypedValue::Type"); LOG(FATAL) << "Unsupported TypedValue::Type";
} }
return *this; return *this;
} }
@ -301,7 +302,7 @@ TypedValue::~TypedValue() {
path_v.~Path(); path_v.~Path();
return; return;
} }
permanent_fail("Unsupported TypedValue::Type"); LOG(FATAL) << "Unsupported TypedValue::Type";
} }
/** /**
@ -423,7 +424,7 @@ TypedValue operator==(const TypedValue &a, const TypedValue &b) {
case TypedValue::Type::Path: case TypedValue::Type::Path:
return a.ValuePath() == b.ValuePath(); return a.ValuePath() == b.ValuePath();
default: default:
permanent_fail("Unhandled comparison for types"); LOG(FATAL) << "Unhandled comparison for types";
} }
} }
@ -619,9 +620,9 @@ bool TypedValue::BoolEqual::operator()(const TypedValue &lhs,
case TypedValue::Type::Null: case TypedValue::Type::Null:
return false; return false;
default: default:
permanent_fail( LOG(FATAL)
"Equality between two TypedValues resulted in something other " << "Equality between two TypedValues resulted in something other "
"then Null or bool"); "then Null or bool";
} }
} }
@ -662,7 +663,7 @@ size_t TypedValue::Hash::operator()(const TypedValue &value) const {
FnvCollection<std::vector<EdgeAccessor>, EdgeAccessor>{}( FnvCollection<std::vector<EdgeAccessor>, EdgeAccessor>{}(
value.ValuePath().edges()); value.ValuePath().edges());
} }
permanent_fail("Unhandled TypedValue.type() in hash function"); LOG(FATAL) << "Unhandled TypedValue.type() in hash function";
} }
} // namespace query } // namespace query

View File

@ -5,9 +5,9 @@
#include <limits> #include <limits>
#include <list> #include <list>
#include "glog/logging.h"
#include "mvcc/record.hpp" #include "mvcc/record.hpp"
#include "transactions/transaction.hpp" #include "transactions/transaction.hpp"
#include "utils/assert.hpp"
/** /**
* @brief - Implements deferred deletion. * @brief - Implements deferred deletion.
@ -31,8 +31,8 @@ class DeferredDeleter {
* @brief - check if everything is freed * @brief - check if everything is freed
*/ */
~DeferredDeleter() { ~DeferredDeleter() {
permanent_assert(objects_.size() == 0, CHECK(objects_.size() == 0U)
"Objects are not freed when calling the destructor."); << "Objects are not freed when calling the destructor.";
} }
/** /**

View File

@ -3,7 +3,6 @@
#include "database/graph_db.hpp" #include "database/graph_db.hpp"
#include "storage/edge.hpp" #include "storage/edge.hpp"
#include "storage/record_accessor.hpp" #include "storage/record_accessor.hpp"
#include "utils/assert.hpp"
// forward declaring the VertexAccessor because it's returned // forward declaring the VertexAccessor because it's returned
// by some functions // by some functions
@ -58,4 +57,4 @@ template <>
struct hash<EdgeAccessor> { struct hash<EdgeAccessor> {
size_t operator()(const EdgeAccessor &e) const { return e.temporary_id(); }; size_t operator()(const EdgeAccessor &e) const { return e.temporary_id(); };
}; };
} } // namespace std

View File

@ -4,6 +4,7 @@
#include <vector> #include <vector>
#include "database/graph_db_datatypes.hpp" #include "database/graph_db_datatypes.hpp"
#include "glog/logging.h"
#include "mvcc/version_list.hpp" #include "mvcc/version_list.hpp"
#include "utils/algorithm.hpp" #include "utils/algorithm.hpp"
@ -89,9 +90,10 @@ class Edges {
* present in this iterator. */ * present in this iterator. */
void update_position() { void update_position() {
if (vertex_) { if (vertex_) {
position_ = std::find_if( position_ = std::find_if(position_,
position_, end_, end_, [v = this->vertex_](const Element &e) {
[v = this->vertex_](const Element &e) { return e.vertex == v; }); return e.vertex == v;
});
} }
if (edge_types_) { if (edge_types_) {
position_ = std::find_if(position_, end_, [this](const Element &e) { position_ = std::find_if(position_, end_, [this](const Element &e) {
@ -122,8 +124,7 @@ class Edges {
auto found = std::find_if( auto found = std::find_if(
storage_.begin(), storage_.end(), storage_.begin(), storage_.end(),
[edge](const Element &element) { return edge == element.edge; }); [edge](const Element &element) { return edge == element.edge; });
debug_assert(found != storage_.end(), DCHECK(found != storage_.end()) << "Removing an edge that is not present";
"Removing an edge that is not present");
*found = std::move(storage_.back()); *found = std::move(storage_.back());
storage_.pop_back(); storage_.pop_back();
} }

View File

@ -5,7 +5,7 @@
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include "utils/assert.hpp" #include "glog/logging.h"
// Value extraction template instantiations // Value extraction template instantiations
template <> template <>
@ -89,7 +89,7 @@ PropertyValue::PropertyValue(const PropertyValue &other) : type_(other.type_) {
return; return;
} }
permanent_fail("Unsupported PropertyValue::Type"); LOG(FATAL) << "Unsupported PropertyValue::Type";
} }
std::ostream &operator<<(std::ostream &os, const PropertyValue::Type type) { std::ostream &operator<<(std::ostream &os, const PropertyValue::Type type) {
@ -109,7 +109,7 @@ std::ostream &operator<<(std::ostream &os, const PropertyValue::Type type) {
case PropertyValue::Type::Map: case PropertyValue::Type::Map:
return os << "map"; return os << "map";
} }
permanent_fail("Unsupported PropertyValue::Type"); LOG(FATAL) << "Unsupported PropertyValue::Type";
} }
std::ostream &operator<<(std::ostream &os, const PropertyValue &value) { std::ostream &operator<<(std::ostream &os, const PropertyValue &value) {
@ -138,7 +138,7 @@ std::ostream &operator<<(std::ostream &os, const PropertyValue &value) {
} }
return os << "}"; return os << "}";
} }
permanent_fail("Unsupported PropertyValue::Type"); LOG(FATAL) << "Unsupported PropertyValue::Type";
} }
PropertyValue &PropertyValue::operator=(const PropertyValue &other) { PropertyValue &PropertyValue::operator=(const PropertyValue &other) {
@ -169,7 +169,7 @@ PropertyValue &PropertyValue::operator=(const PropertyValue &other) {
return *this; return *this;
} }
} }
permanent_fail("Unsupported PropertyValue::Type"); LOG(FATAL) << "Unsupported PropertyValue::Type";
} }
const PropertyValue PropertyValue::Null = PropertyValue(); const PropertyValue PropertyValue::Null = PropertyValue();
@ -194,5 +194,5 @@ PropertyValue::~PropertyValue() {
map_v.~shared_ptr<std::map<std::string, PropertyValue>>(); map_v.~shared_ptr<std::map<std::string, PropertyValue>>();
return; return;
} }
permanent_fail("Unsupported PropertyValue::Type"); LOG(FATAL) << "Unsupported PropertyValue::Type";
} }

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <cassert>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <memory> #include <memory>

View File

@ -1,8 +1,9 @@
#include "storage/record_accessor.hpp" #include "glog/logging.h"
#include "database/graph_db_accessor.hpp" #include "database/graph_db_accessor.hpp"
#include "storage/edge.hpp" #include "storage/edge.hpp"
#include "storage/record_accessor.hpp"
#include "storage/vertex.hpp" #include "storage/vertex.hpp"
#include "utils/assert.hpp"
template <typename TRecord> template <typename TRecord>
RecordAccessor<TRecord>::RecordAccessor(mvcc::VersionList<TRecord> &vlist, RecordAccessor<TRecord>::RecordAccessor(mvcc::VersionList<TRecord> &vlist,
@ -51,8 +52,8 @@ RecordAccessor<TRecord> &RecordAccessor<TRecord>::SwitchNew() {
// to the same value as it has now, and the amount of work is the // to the same value as it has now, and the amount of work is the
// same as just looking for a new_ record // same as just looking for a new_ record
if (!Reconstruct()) if (!Reconstruct())
debug_fail( DLOG(FATAL)
"RecordAccessor::SwitchNew - accessor invalid after Reconstruct"); << "RecordAccessor::SwitchNew - accessor invalid after Reconstruct";
} }
current_ = new_ ? new_ : old_; current_ = new_ ? new_ : old_;
return *this; return *this;
@ -72,14 +73,13 @@ bool RecordAccessor<TRecord>::Reconstruct() {
template <typename TRecord> template <typename TRecord>
TRecord &RecordAccessor<TRecord>::update() { TRecord &RecordAccessor<TRecord>::update() {
db_accessor().Update(*this); db_accessor().Update(*this);
debug_assert(new_ != nullptr, "RecordAccessor.new_ is null after update"); DCHECK(new_ != nullptr) << "RecordAccessor.new_ is null after update";
return *new_; return *new_;
} }
template <typename TRecord> template <typename TRecord>
const TRecord &RecordAccessor<TRecord>::current() const { const TRecord &RecordAccessor<TRecord>::current() const {
debug_assert(current_ != nullptr, DCHECK(current_ != nullptr) << "RecordAccessor.current_ pointer is nullptr";
"RecordAccessor.current_ pointer is nullptr");
return *current_; return *current_;
} }

View File

@ -5,6 +5,7 @@
#include "storage/property_value.hpp" #include "storage/property_value.hpp"
#include "utils/total_ordering.hpp" #include "utils/total_ordering.hpp"
#include "glog/logging.h"
#include "storage/property_value_store.hpp" #include "storage/property_value_store.hpp"
class GraphDbAccessor; class GraphDbAccessor;
@ -88,14 +89,14 @@ class RecordAccessor : public TotalOrdering<RecordAccessor<TRecord>> {
* not actual values inside RecordAccessors. * not actual values inside RecordAccessors.
*/ */
bool operator<(const RecordAccessor &other) const { bool operator<(const RecordAccessor &other) const {
debug_assert(db_accessor_ == other.db_accessor_, DCHECK(db_accessor_ == other.db_accessor_)
"Not in the same transaction."); << "Not in the same transaction.";
return vlist_ < other.vlist_; return vlist_ < other.vlist_;
} }
bool operator==(const RecordAccessor &other) const { bool operator==(const RecordAccessor &other) const {
debug_assert(db_accessor_ == other.db_accessor_, DCHECK(db_accessor_ == other.db_accessor_)
"Not in the same transaction."); << "Not in the same transaction.";
return vlist_ == other.vlist_; return vlist_ == other.vlist_;
} }

View File

@ -9,15 +9,16 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "threading/sync/lock_timeout_exception.hpp" #include "glog/logging.h"
#include "threading/sync/cpu_relax.hpp" #include "threading/sync/cpu_relax.hpp"
#include "threading/sync/lock_timeout_exception.hpp"
namespace sys { namespace sys {
inline int futex(void *addr1, int op, int val1, const struct timespec *timeout, inline int futex(void *addr1, int op, int val1, const struct timespec *timeout,
void *addr2, int val3) { void *addr2, int val3) {
return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3); return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
}; };
} } // namespace sys
class Futex { class Futex {
using futex_t = uint32_t; using futex_t = uint32_t;

View File

@ -1,8 +1,8 @@
#include "glog/logging.h"
#include "thread.hpp" #include "thread.hpp"
#include "utils/assert.hpp"
Thread::Thread(Thread &&other) { Thread::Thread(Thread &&other) {
debug_assert(thread_id == UNINITIALIZED, "Thread was initialized before."); DCHECK(thread_id == UNINITIALIZED) << "Thread was initialized before.";
thread_id = other.thread_id; thread_id = other.thread_id;
thread = std::move(other.thread); thread = std::move(other.thread);
} }

View File

@ -4,6 +4,7 @@
#include <limits> #include <limits>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "threading/sync/lockable.hpp" #include "threading/sync/lockable.hpp"
#include "threading/sync/spinlock.hpp" #include "threading/sync/spinlock.hpp"
#include "transactions/commit_log.hpp" #include "transactions/commit_log.hpp"
@ -63,12 +64,12 @@ class Engine : Lockable<SpinLock> {
auto guard = this->acquire_unique(); auto guard = this->acquire_unique();
auto *t = store_.get(id); auto *t = store_.get(id);
debug_assert(t != nullptr, DCHECK(t != nullptr) << "Transaction::advance on non-existing transaction";
"Transaction::advance on non-existing transaction");
if (t->cid_ == kMaxCommandId) if (t->cid_ == kMaxCommandId)
throw TransactionError( throw TransactionError(
"Reached maximum number of commands in this transaction."); "Reached maximum number of commands in this "
"transaction.");
t->cid_++; t->cid_++;
return *t; return *t;
@ -177,4 +178,4 @@ class Engine : Lockable<SpinLock> {
ConcurrentMap<transaction_id_t, transaction_id_t> lock_graph_; ConcurrentMap<transaction_id_t, transaction_id_t> lock_graph_;
std::atomic<transaction_id_t> counter_{0}; std::atomic<transaction_id_t> counter_{0};
}; };
} } // namespace tx

View File

@ -2,10 +2,10 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "storage/locking/lock_status.hpp" #include "storage/locking/lock_status.hpp"
#include "storage/locking/record_lock.hpp" #include "storage/locking/record_lock.hpp"
#include "transactions/type.hpp" #include "transactions/type.hpp"
#include "utils/assert.hpp"
namespace tx { namespace tx {
@ -19,7 +19,7 @@ class LockStore {
LockHolder(RecordLock *lock, const Transaction &tx, tx::Engine &engine) LockHolder(RecordLock *lock, const Transaction &tx, tx::Engine &engine)
: lock_(lock) { : lock_(lock) {
debug_assert(lock != nullptr, "Lock is nullptr."); DCHECK(lock != nullptr) << "Lock is nullptr.";
auto status = lock_->Lock(tx, engine); auto status = lock_->Lock(tx, engine);
if (status != LockStatus::Acquired) { if (status != LockStatus::Acquired) {
@ -64,4 +64,4 @@ class LockStore {
private: private:
std::vector<LockHolder> locks_; std::vector<LockHolder> locks_;
}; };
} } // namespace tx

View File

@ -4,9 +4,9 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "transactions/type.hpp" #include "transactions/type.hpp"
#include "utils/algorithm.hpp" #include "utils/algorithm.hpp"
#include "utils/assert.hpp"
namespace tx { namespace tx {
@ -42,9 +42,8 @@ class Snapshot {
*/ */
void insert(transaction_id_t id) { void insert(transaction_id_t id) {
transaction_ids_.push_back(id); transaction_ids_.push_back(id);
debug_assert( DCHECK(std::is_sorted(transaction_ids_.begin(), transaction_ids_.end()))
std::is_sorted(transaction_ids_.begin(), transaction_ids_.end()), << "Snapshot must be sorted";
"Snapshot must be sorted");
} }
/** Removes the given transaction id from this Snapshot. /** Removes the given transaction id from this Snapshot.
@ -58,12 +57,12 @@ class Snapshot {
} }
transaction_id_t front() const { transaction_id_t front() const {
debug_assert(transaction_ids_.size(), "Snapshot.front() on empty Snapshot"); DCHECK(transaction_ids_.size()) << "Snapshot.front() on empty Snapshot";
return transaction_ids_.front(); return transaction_ids_.front();
} }
transaction_id_t back() const { transaction_id_t back() const {
debug_assert(transaction_ids_.size(), "Snapshot.back() on empty Snapshot"); DCHECK(transaction_ids_.size()) << "Snapshot.back() on empty Snapshot";
return transaction_ids_.back(); return transaction_ids_.back();
} }
@ -88,4 +87,4 @@ class Snapshot {
private: private:
std::vector<transaction_id_t> transaction_ids_; std::vector<transaction_id_t> transaction_ids_;
}; };
} } // namespace tx

View File

@ -23,86 +23,3 @@
#define __handle_assert_message(message) \ #define __handle_assert_message(message) \
std::cerr << "ASSERT: " << message << std::endl; std::cerr << "ASSERT: " << message << std::endl;
#endif #endif
/**
* Always check that the condition is satisfied, otherwise abort the program.
*
* Unlike @c debug_assert, @c permanent_assert is always active. A good use-case
* for this type of assert is during unit testing, because assert has to be
* active regardless of the build type.
*
* @param condition Expression which has to evaluate to @c true.
* @param message Message that is to be displayed before aborting, if the
* evaluated @c condition is @c false.
*
* @sa permanent_fail
* @sa debug_assert
* @sa debug_fail
*/
#define permanent_assert(condition, message) \
if (!(condition)) { \
std::ostringstream s; \
s << message; \
__handle_assert_message(s.str()); \
std::abort(); \
}
/**
* Always abort the program with given message.
*
* Unlike @c debug_fail, @c permanent_fail is always active. This should be used
* like @c permanent_assert, but when the condition cannot be a simple
* expression.
*
* @param message Message to display before aborting.
*
* @sa permanent_assert
* @sa debug_assert
* @sa debug_fail
*/
#define permanent_fail(message) \
{ \
std::ostringstream s; \
s << message; \
__handle_assert_message(s.str()); \
std::abort(); \
}
/**
* @def debug_assert(condition, message)
* Check that the condition is satisfied, otherwise abort the program.
*
* This is like @c permanent_assert, but the @c NDEBUG define controls
* whether this assertion is active. With this define, @c debug_assert will do
* nothing. Therefore, this is more like the standard C @c assert facility and
* it should be used as such. For example, validating pre and post conditions of
* a function.
*
* @sa debug_fail
* @sa permanent_assert
* @sa permanent_fail
*/
/**
* @def debug_fail(message)
* Abort the program with given message.
*
* This is like @c permanent_fail, but the @c NDEBUG define controls
* whether this assertion is active. With this define, @c debug_fail will do
* nothing. This should be used like @c debug_assert, but when the condition
* cannot be a simple expression.
*
* @sa debug_assert
* @sa permanent_assert
* @sa permanent_fail
*/
#ifndef NDEBUG
#define debug_assert(condition, message) permanent_assert(condition, message)
#define debug_fail(message) permanent_fail(message)
#else
#define debug_assert(condition, message) \
{}
#define debug_fail(message) \
{}
#endif

View File

@ -25,7 +25,6 @@ namespace fs = std::experimental::filesystem;
#include <glog/logging.h> #include <glog/logging.h>
#include "utils/algorithm.hpp" #include "utils/algorithm.hpp"
#include "utils/assert.hpp"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
#include "utils/likely.hpp" #include "utils/likely.hpp"
#include "utils/underlying_cast.hpp" #include "utils/underlying_cast.hpp"
@ -45,7 +44,7 @@ void set_non_blocking(int fd) {
if (UNLIKELY(status == -1)) if (UNLIKELY(status == -1))
throw BasicException("Can't set NON_BLOCK flag to file descriptor"); throw BasicException("Can't set NON_BLOCK flag to file descriptor");
} }
} } // namespace linux_os
/** /**
* Goes from first to last item in a container, if an element satisfying the * Goes from first to last item in a container, if an element satisfying the
@ -149,8 +148,7 @@ struct FSEventBase {
struct WatchDescriptor : public FSEventBase { struct WatchDescriptor : public FSEventBase {
WatchDescriptor(const fs::path &directory, const FSEventType type) WatchDescriptor(const fs::path &directory, const FSEventType type)
: FSEventBase(directory, type) { : FSEventBase(directory, type) {
debug_assert(fs::is_directory(path), DCHECK(fs::is_directory(path)) << "The path parameter should be directory";
"The path parameter should be directory");
} }
}; };
@ -356,10 +354,10 @@ class FSWatcher {
// TODO: figure out why (it is not easy) // TODO: figure out why (it is not easy)
if (((p - buffer_) + in_event_length) > IN_BUFF_LEN) break; if (((p - buffer_) + in_event_length) > IN_BUFF_LEN) break;
// here should be an assertion // here should be an assertion
// debug_assert(in_event_length <= IN_BUFF_SLOT_LEN, // DCHECK(in_event_length <= IN_BUFF_SLOT_LEN) <<
// "Inotify event length cannot be bigger // "Inotify event length cannot be bigger
// than " // than "
// "Inotify slot length"); // "Inotify slot length";
// skip if in_event is undefined OR is equal to IN_IGNORED // skip if in_event is undefined OR is equal to IN_IGNORED
if ((in_event->len == 0 && in_event->mask == 0) || if ((in_event->len == 0 && in_event->mask == 0) ||
@ -471,4 +469,4 @@ class FSWatcher {
*/ */
char *buffer_[IN_BUFF_LEN]; char *buffer_[IN_BUFF_LEN];
}; };
} } // namespace utils

View File

@ -1,9 +1,10 @@
#pragma once #pragma once
#include <ext/aligned_buffer.h> #include <ext/aligned_buffer.h>
#include "glog/logging.h"
#include <cstring> #include <cstring>
#include <utility> #include <utility>
#include "utils/assert.hpp"
// Optional object storage. It maybe has and maybe // Optional object storage. It maybe has and maybe
// dosent have objet of type T. // dosent have objet of type T.
@ -85,7 +86,7 @@ class Option {
bool is_present() const { return initialized; } bool is_present() const { return initialized; }
T &get() noexcept { T &get() noexcept {
debug_assert(initialized, "Not initialized."); DCHECK(initialized) << "Not initialized.";
return *data._M_ptr(); return *data._M_ptr();
} }
@ -107,7 +108,7 @@ class Option {
} }
const T &get() const noexcept { const T &get() const noexcept {
debug_assert(initialized, "Not initialized."); DCHECK(initialized) << "Not initialized.";
return *data._M_ptr(); return *data._M_ptr();
} }
@ -148,7 +149,7 @@ class Option {
} }
T take() { T take() {
debug_assert(initialized, "Not initialized."); DCHECK(initialized) << "Not initialized.";
initialized = false; initialized = false;
return std::move(*data._M_ptr()); return std::move(*data._M_ptr());
} }

View File

@ -2,7 +2,7 @@
#include <utility> #include <utility>
#include "utils/assert.hpp" #include "glog/logging.h"
#include <ext/aligned_buffer.h> #include <ext/aligned_buffer.h>
@ -38,7 +38,7 @@ class Placeholder {
bool is_initialized() { return initialized; } bool is_initialized() { return initialized; }
T &get() noexcept { T &get() noexcept {
debug_assert(initialized, "Placeholder object not initialized"); DCHECK(initialized) << "Placeholder object not initialized";
return *data._M_ptr(); return *data._M_ptr();
} }
@ -46,7 +46,7 @@ class Placeholder {
* @return const reference to object. * @return const reference to object.
*/ */
const T &get() const noexcept { const T &get() const noexcept {
debug_assert(initialized, "Placeholder object not initialized"); DCHECK(initialized) << "Placeholder object not initialized";
return *data._M_ptr(); return *data._M_ptr();
} }
@ -56,7 +56,7 @@ class Placeholder {
* @param T& item reference to the item initialized in allocated memory * @param T& item reference to the item initialized in allocated memory
*/ */
void set(const T &item) { void set(const T &item) {
debug_assert(!initialized, "Placeholder object already initialized"); DCHECK(!initialized) << "Placeholder object already initialized";
new (data._M_addr()) T(item); new (data._M_addr()) T(item);
initialized = true; initialized = true;
} }
@ -67,7 +67,7 @@ class Placeholder {
* @param T&& rvalue reference to the item which is moved to allocated memory * @param T&& rvalue reference to the item which is moved to allocated memory
*/ */
void set(T &&item) { void set(T &&item) {
debug_assert(!initialized, "Placeholder object already initialized"); DCHECK(!initialized) << "Placeholder object already initialized";
new (data._M_addr()) T(std::move(item)); new (data._M_addr()) T(std::move(item));
initialized = true; initialized = true;
} }
@ -81,7 +81,7 @@ class Placeholder {
*/ */
template <class... Args> template <class... Args>
void emplace(Args &&... args) { void emplace(Args &&... args) {
debug_assert(!initialized, "Placeholder object already initialized"); DCHECK(!initialized) << "Placeholder object already initialized";
new (data._M_addr()) T(args...); new (data._M_addr()) T(args...);
initialized = true; initialized = true;
} }

View File

@ -27,7 +27,7 @@ namespace utils {
* in the [from, to) range. * in the [from, to) range.
*/ */
auto RandomIntGenerator(int from, int to) { auto RandomIntGenerator(int from, int to) {
permanent_assert(from < to, "Must have from < to"); CHECK(from < to) << "Must have from < to";
int range = to - from; int range = to - from;
return [from, range]() -> int { return rand() % range + from; }; return [from, range]() -> int { return rand() % range + from; };
} }
@ -119,8 +119,8 @@ class RandomGraphGenerator {
auto from = auto from =
dba.Transfer(vertices_from[rand() % vertices_from.size()]); dba.Transfer(vertices_from[rand() % vertices_from.size()]);
auto to = dba.Transfer(vertices_to[rand() % vertices_to.size()]); auto to = dba.Transfer(vertices_to[rand() % vertices_to.size()]);
debug_assert(from, "From not visible in current GraphDbAccessor"); DCHECK(from) << "From not visible in current GraphDbAccessor";
debug_assert(to, "From not visible in current GraphDbAccessor"); DCHECK(to) << "From not visible in current GraphDbAccessor";
dba.InsertEdge(from.value(), to.value(), edge_type); dba.InsertEdge(from.value(), to.value(), edge_type);
NotifyProgressListeners(); NotifyProgressListeners();
}, },
@ -195,7 +195,7 @@ class RandomGraphGenerator {
*/ */
void Map(std::function<void(GraphDbAccessor &)> f, int count, void Map(std::function<void(GraphDbAccessor &)> f, int count,
int thread_count, int elements_per_commit) { int thread_count, int elements_per_commit) {
debug_assert(thread_count > 0, "Can't work on less then 1 thread"); DCHECK(thread_count > 0) << "Can't work on less then 1 thread";
// split count across thread_count // split count across thread_count
int count_per_thread = count / thread_count; int count_per_thread = count / thread_count;
@ -228,4 +228,4 @@ class RandomGraphGenerator {
for (auto &thread : threads) thread.join(); for (auto &thread : threads) thread.join();
} }
}; };
} } // namespace utils

View File

@ -4,9 +4,10 @@
#include <chrono> #include <chrono>
#include <condition_variable> #include <condition_variable>
#include <ctime> #include <ctime>
#include <functional>
#include <thread> #include <thread>
#include "utils/assert.hpp" #include "glog/logging.h"
/** /**
* Class used to run scheduled function execution. * Class used to run scheduled function execution.
@ -25,8 +26,8 @@ class Scheduler {
template <typename TRep, typename TPeriod> template <typename TRep, typename TPeriod>
void Run(const std::chrono::duration<TRep, TPeriod> &pause, void Run(const std::chrono::duration<TRep, TPeriod> &pause,
const std::function<void()> &f) { const std::function<void()> &f) {
debug_assert(is_working_ == false, "Thread already running."); DCHECK(is_working_ == false) << "Thread already running.";
debug_assert(pause > std::chrono::seconds(0), "Pause is invalid."); DCHECK(pause > std::chrono::seconds(0)) << "Pause is invalid.";
is_working_ = true; is_working_ = true;
thread_ = std::thread([this, pause, f]() { thread_ = std::thread([this, pause, f]() {

View File

@ -1,3 +1,4 @@
#include <iostream>
#include <random> #include <random>
#include <thread> #include <thread>

View File

@ -11,7 +11,6 @@
#include "data_structures/concurrent/concurrent_map.hpp" #include "data_structures/concurrent/concurrent_map.hpp"
#include "data_structures/concurrent/concurrent_set.hpp" #include "data_structures/concurrent/concurrent_set.hpp"
#include "data_structures/concurrent/skiplist.hpp" #include "data_structures/concurrent/skiplist.hpp"
#include "utils/assert.hpp"
// NOTE: this file is highly coupled to data_structures // NOTE: this file is highly coupled to data_structures
// TODO: REFACTOR // TODO: REFACTOR
@ -44,8 +43,7 @@ template <typename S>
void check_present_same(typename S::Accessor &acc, size_t data, void check_present_same(typename S::Accessor &acc, size_t data,
std::vector<size_t> &owned) { std::vector<size_t> &owned) {
for (auto num : owned) { for (auto num : owned) {
permanent_assert(acc.find(num)->second == data, CHECK(acc.find(num)->second == data) << "My data is present and my";
"My data is present and my");
} }
} }
@ -61,8 +59,8 @@ template <typename S>
void check_size_list(S &acc, long long size) { void check_size_list(S &acc, long long size) {
// check size // check size
permanent_assert(acc.size() == size, CHECK(acc.size() == size)
"Size should be " << size << ", but size is " << acc.size()); << "Size should be " << size << ", but size is " << acc.size();
// check count // check count
@ -71,16 +69,16 @@ void check_size_list(S &acc, long long size) {
for ([[gnu::unused]] auto elem : acc) { for ([[gnu::unused]] auto elem : acc) {
++iterator_counter; ++iterator_counter;
} }
permanent_assert(static_cast<int64_t>(iterator_counter) == size, CHECK(static_cast<int64_t>(iterator_counter) == size)
"Iterator count should be " << size << ", but size is " << "Iterator count should be " << size << ", but size is "
<< iterator_counter); << iterator_counter;
} }
template <typename S> template <typename S>
void check_size(typename S::Accessor &acc, long long size) { void check_size(typename S::Accessor &acc, long long size) {
// check size // check size
permanent_assert(acc.size() == size, CHECK(acc.size() == size)
"Size should be " << size << ", but size is " << acc.size()); << "Size should be " << size << ", but size is " << acc.size();
// check count // check count
@ -89,9 +87,9 @@ void check_size(typename S::Accessor &acc, long long size) {
for ([[gnu::unused]] auto elem : acc) { for ([[gnu::unused]] auto elem : acc) {
++iterator_counter; ++iterator_counter;
} }
permanent_assert(static_cast<int64_t>(iterator_counter) == size, CHECK(static_cast<int64_t>(iterator_counter) == size)
"Iterator count should be " << size << ", but size is " << "Iterator count should be " << size << ", but size is "
<< iterator_counter); << iterator_counter;
} }
// Checks if order in list is maintened. It expects map // Checks if order in list is maintened. It expects map
@ -110,16 +108,14 @@ void check_order(typename S::Accessor &acc) {
void check_zero(size_t key_range, long array[], const char *str) { void check_zero(size_t key_range, long array[], const char *str) {
for (int i = 0; i < static_cast<int>(key_range); i++) { for (int i = 0; i < static_cast<int>(key_range); i++) {
permanent_assert(array[i] == 0, CHECK(array[i] == 0) << str << " doesn't hold it's guarantees. It has "
str << " doesn't hold it's guarantees. It has " << array[i] << array[i] << " extra elements.";
<< " extra elements.");
} }
} }
void check_set(DynamicBitset<> &db, std::vector<bool> &set) { void check_set(DynamicBitset<> &db, std::vector<bool> &set) {
for (int i = 0; i < static_cast<int>(set.size()); i++) { for (int i = 0; i < static_cast<int>(set.size()); i++) {
permanent_assert(!(set[i] ^ db.at(i)), CHECK(!(set[i] ^ db.at(i))) << "Set constraints aren't fullfilled.";
"Set constraints aren't fullfilled.");
} }
} }

View File

@ -15,7 +15,7 @@ constexpr size_t no_insert_for_one_delete = 1;
int main(int argc, char **argv) { int main(int argc, char **argv) {
google::InitGoogleLogging(argv[0]); google::InitGoogleLogging(argv[0]);
ConcurrentList<std::pair<int, int>> list; ConcurrentList<std::pair<int, int>> list;
permanent_assert(list.size() == 0, "The list isn't empty"); CHECK(list.size() == 0) << "The list isn't empty";
auto futures = auto futures =
run<std::pair<long long, long long>>(THREADS_NO, [&](auto index) mutable { run<std::pair<long long, long long>>(THREADS_NO, [&](auto index) mutable {
@ -47,7 +47,7 @@ int main(int argc, char **argv) {
} else { } else {
for (auto &v : list) { for (auto &v : list) {
if (v.first == num) { if (v.first == num) {
permanent_assert(v.second == data, "Data is invalid"); CHECK(v.second == data) << "Data is invalid";
break; break;
} }
} }
@ -69,7 +69,7 @@ int main(int argc, char **argv) {
sums -= e.second; sums -= e.second;
} }
permanent_assert(sums == 0, "Same values aren't present"); CHECK(sums == 0) << "Same values aren't present";
check_size_list<ConcurrentList<std::pair<int, int>>>(list, counters); check_size_list<ConcurrentList<std::pair<int, int>>>(list, counters);
std::this_thread::sleep_for(1s); std::this_thread::sleep_for(1s);

View File

@ -23,9 +23,8 @@ void test_lock(int) {
std::unique_lock<Futex> guard(futex); std::unique_lock<Futex> guard(futex);
x++; x++;
std::this_thread::sleep_for(std::chrono::milliseconds(dis(gen))); std::this_thread::sleep_for(std::chrono::milliseconds(dis(gen)));
permanent_assert(x == 1, CHECK(x == 1) << "Other thread shouldn't be able to "
"Other thread shouldn't be able to " "change the value of x";
"change the value of x");
x--; x--;
} }
std::this_thread::sleep_for(std::chrono::milliseconds(dis(gen))); std::this_thread::sleep_for(std::chrono::milliseconds(dis(gen)));

View File

@ -30,8 +30,8 @@ int main(int, char **argv) {
// get skiplist size // get skiplist size
{ {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
permanent_assert(accessor.size() == THREADS_NO * elems_per_thread, CHECK(accessor.size() == THREADS_NO * elems_per_thread)
"all elements in skiplist"); << "all elements in skiplist";
} }
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) { for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) {
@ -39,7 +39,7 @@ int main(int, char **argv) {
[&skiplist](size_t start, size_t end) { [&skiplist](size_t start, size_t end) {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
for (size_t elem_i = start; elem_i < end; ++elem_i) { for (size_t elem_i = start; elem_i < end; ++elem_i) {
permanent_assert(accessor.remove(elem_i) == true, ""); CHECK(accessor.remove(elem_i) == true) << "";
} }
}, },
thread_i * elems_per_thread, thread_i * elems_per_thread,
@ -53,8 +53,8 @@ int main(int, char **argv) {
// check size // check size
{ {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
permanent_assert(accessor.size() == 0, "Size should be 0, but size is " CHECK(accessor.size() == 0)
<< accessor.size()); << "Size should be 0, but size is " << accessor.size();
} }
// check count // check count
@ -65,11 +65,12 @@ int main(int, char **argv) {
++iterator_counter; ++iterator_counter;
cout << elem.first << " "; cout << elem.first << " ";
} }
permanent_assert(iterator_counter == 0, "deleted elements"); CHECK(iterator_counter == 0) << "deleted elements";
} }
{ {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
check_order<map_t>(accessor); check_order<map_t>(accessor);
} }
return 0;
} }

View File

@ -35,8 +35,8 @@ int main(int, char **argv) {
// get skiplist size // get skiplist size
{ {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
permanent_assert(accessor.size() == THREADS_NO * elems_per_thread, CHECK(accessor.size() == THREADS_NO * elems_per_thread)
"all elements in skiplist"); << "all elements in skiplist";
} }
for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) { for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) {
@ -44,7 +44,7 @@ int main(int, char **argv) {
[&skiplist](size_t start, size_t end) { [&skiplist](size_t start, size_t end) {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
for (size_t elem_i = start; elem_i < end; ++elem_i) { for (size_t elem_i = start; elem_i < end; ++elem_i) {
permanent_assert(accessor.remove(elem_i) == true, ""); CHECK(accessor.remove(elem_i) == true) << "";
} }
}, },
thread_i * elems_per_thread, thread_i * elems_per_thread,
@ -58,8 +58,8 @@ int main(int, char **argv) {
// check size // check size
{ {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
permanent_assert(accessor.size() == 0, "Size should be 0, but size is " CHECK(accessor.size() == 0)
<< accessor.size()); << "Size should be 0, but size is " << accessor.size();
} }
// check count // check count
@ -70,6 +70,7 @@ int main(int, char **argv) {
++iterator_counter; ++iterator_counter;
cout << elem.first << " "; cout << elem.first << " ";
} }
permanent_assert(iterator_counter == 0, "deleted elements"); CHECK(iterator_counter == 0) << "deleted elements";
} }
return 0;
} }

View File

@ -58,7 +58,8 @@ int main(int argc, char **argv) {
for (auto &e : accessor) { for (auto &e : accessor) {
sums -= e.second; sums -= e.second;
} }
permanent_assert(sums == 0, "Aproximetly Same values are present"); CHECK(sums == 0) << "Aproximetly Same values are present";
check_size<map_t>(accessor, counters); check_size<map_t>(accessor, counters);
check_order<map_t>(accessor); check_order<map_t>(accessor);
return 0;
} }

View File

@ -26,7 +26,7 @@ int main(int argc, char **argv) {
do { do {
if (owned.size() != 0 && rand_op()) { if (owned.size() != 0 && rand_op()) {
auto rem = rand() % owned.size(); auto rem = rand() % owned.size();
permanent_assert(acc.remove(owned[rem]), "Owned data removed"); CHECK(acc.remove(owned[rem])) << "Owned data removed";
owned.erase(owned.begin() + rem); owned.erase(owned.begin() + rem);
downcount--; downcount--;
} else { } else {
@ -46,4 +46,5 @@ int main(int argc, char **argv) {
} }
check_size<map_t>(accessor, count); check_size<map_t>(accessor, count);
check_order<map_t>(accessor); check_order<map_t>(accessor);
return 0;
} }

View File

@ -56,7 +56,8 @@ int main(int argc, char **argv) {
for (auto &e : accessor) { for (auto &e : accessor) {
sums -= e.second; sums -= e.second;
} }
permanent_assert(sums == 0, "Aproximetly Same values are present"); CHECK(sums == 0) << "Aproximetly Same values are present";
check_size<map_t>(accessor, counters); check_size<map_t>(accessor, counters);
check_order<map_t>(accessor); check_order<map_t>(accessor);
return 0;
} }

View File

@ -50,9 +50,9 @@ int main(int argc, char **argv) {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
for (int i = 0; i < key_range; i++) { for (int i = 0; i < key_range; i++) {
permanent_assert(set[i] == 0 || set[i] == 1 || CHECK(set[i] == 0 || set[i] == 1 ||
(set[i] == 1) ^ accessor.contains(std::to_string(i)), (set[i] == 1) ^ accessor.contains(std::to_string(i)))
"Set doesn't hold it's guarantees."); << "Set doesn't hold it's guarantees.";
} }
for (auto &e : accessor) { for (auto &e : accessor) {
@ -60,4 +60,5 @@ int main(int argc, char **argv) {
} }
check_zero(key_range, set, "Set"); check_zero(key_range, set, "Set");
return 0;
} }

View File

@ -43,8 +43,8 @@ int main(int argc, char **argv) {
} }
} else { } else {
auto value = acc.find(num); auto value = acc.find(num);
permanent_assert(value == acc.end() || value->second == data, CHECK(value == acc.end() || value->second == data)
"Data is invalid"); << "Data is invalid";
} }
} }
@ -62,7 +62,7 @@ int main(int argc, char **argv) {
for (auto &e : accessor) { for (auto &e : accessor) {
sums -= e.second; sums -= e.second;
} }
permanent_assert(sums == 0, "Same values aren't present"); CHECK(sums == 0) << "Same values aren't present";
check_size<map_t>(accessor, counters); check_size<map_t>(accessor, counters);
check_order<map_t>(accessor); check_order<map_t>(accessor);
} }

View File

@ -4,8 +4,9 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "threading/sync/spinlock.hpp" #include "threading/sync/spinlock.hpp"
#include "utils/assert.hpp"
int x = 0; int x = 0;
SpinLock lock; SpinLock lock;
@ -19,10 +20,8 @@ void test_lock() {
std::this_thread::sleep_for(25ms); std::this_thread::sleep_for(25ms);
permanent_assert( CHECK(x < 2) << "x always has to be less than 2 (other "
x < 2, "threads shouldn't be able to change the x simultaneously";
"x always has to be less than 2 (other "
"threads shouldn't be able to change the x simultaneously");
x--; x--;
} }
} }

View File

@ -1,8 +1,9 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "transactions/engine.hpp" #include "transactions/engine.hpp"
#include "utils/assert.hpp"
int main() { int main() {
// (try to) test correctness of the transaction life cycle // (try to) test correctness of the transaction life cycle
@ -41,5 +42,6 @@ int main() {
for (uint64_t i = 1; i <= THREADS * TRANSACTIONS; ++i) sum_actual += i; for (uint64_t i = 1; i <= THREADS * TRANSACTIONS; ++i) sum_actual += i;
std::cout << sum_computed << " " << sum_actual << std::endl; std::cout << sum_computed << " " << sum_actual << std::endl;
permanent_assert(sum_computed == sum_actual, "sums have to be the same"); CHECK(sum_computed == sum_actual) << "sums have to be the same";
return 0;
} }

View File

@ -142,7 +142,7 @@ class GraphState {
// Gets the ID of a random node that has the given label. // Gets the ID of a random node that has the given label.
int64_t RandomNode(const std::string &label) { int64_t RandomNode(const std::string &label) {
auto found = label_nodes_.find(label); auto found = label_nodes_.find(label);
permanent_assert(found != label_nodes_.end(), "Label not found"); CHECK(found != label_nodes_.end()) << "Label not found";
return found->second[rand_(gen_) * found->second.size()]; return found->second[rand_(gen_) * found->second.size()];
} }
@ -167,7 +167,7 @@ class ValueGenerator {
std::unordered_map<std::string, query::TypedValue> props; std::unordered_map<std::string, query::TypedValue> props;
if (config.is_null()) return props; if (config.is_null()) return props;
permanent_assert(config.is_object(), "Properties config must be a dict"); CHECK(config.is_object()) << "Properties config must be a dict";
for (auto it = config.begin(); it != config.end(); it++) { for (auto it = config.begin(); it != config.end(); it++) {
auto value = MakeValue(it.value()); auto value = MakeValue(it.value());
if (value) props.emplace(it.key(), *value); if (value) props.emplace(it.key(), *value);
@ -193,7 +193,7 @@ class ValueGenerator {
else if (type == "randstring") else if (type == "randstring")
return TypedValue(RandString(param)); return TypedValue(RandString(param));
else else
permanent_fail("Unknown value type"); LOG(FATAL) << "Unknown value type";
} else } else
return Primitive(config); return Primitive(config);
} }
@ -204,7 +204,7 @@ class ValueGenerator {
if (config.is_number_float()) return config.get<double>(); if (config.is_number_float()) return config.get<double>();
if (config.is_boolean()) return config.get<bool>(); if (config.is_boolean()) return config.get<bool>();
permanent_fail("Unsupported primitive type"); LOG(FATAL) << "Unsupported primitive type";
} }
int64_t Counter(const std::string &name) { int64_t Counter(const std::string &name) {
@ -218,12 +218,11 @@ class ValueGenerator {
} }
int64_t RandInt(const json &range) { int64_t RandInt(const json &range) {
permanent_assert(range.is_array() && range.size() == 2, CHECK(range.is_array() && range.size() == 2)
"RandInt value gen config must be a list with 2 elements"); << "RandInt value gen config must be a list with 2 elements";
auto from = MakeValue(range[0])->ValueInt(); auto from = MakeValue(range[0])->ValueInt();
auto to = MakeValue(range[1])->ValueInt(); auto to = MakeValue(range[1])->ValueInt();
permanent_assert(from < to, CHECK(from < to) << "RandInt lower range must be lesser then upper range";
"RandInt lower range must be lesser then upper range");
return (int64_t)(rand_(gen_) * (to - from)) + from; return (int64_t)(rand_(gen_) * (to - from)) + from;
} }
@ -244,9 +243,8 @@ class ValueGenerator {
bool Bernoulli(double p) { return rand_(gen_) < p; } bool Bernoulli(double p) { return rand_(gen_) < p; }
std::experimental::optional<TypedValue> Optional(const json &config) { std::experimental::optional<TypedValue> Optional(const json &config) {
permanent_assert( CHECK(config.is_array() && config.size() == 2)
config.is_array() && config.size() == 2, << "Optional value gen config must be a list with 2 elements";
"Optional value gen config must be a list with 2 elements");
return Bernoulli(config[0]) ? MakeValue(config[1]) return Bernoulli(config[0]) ? MakeValue(config[1])
: std::experimental::nullopt; : std::experimental::nullopt;
} }
@ -285,18 +283,16 @@ int main(int argc, char **argv) {
// Create nodes // Create nodes
const auto &nodes_config = config["nodes"]; const auto &nodes_config = config["nodes"];
permanent_assert( CHECK(nodes_config.is_array() && nodes_config.size() > 0)
nodes_config.is_array() && nodes_config.size() > 0, << "Generator config must have 'nodes' array with at least one element";
"Generator config must have 'nodes' array with at least one element");
for (const auto &node_config : config["nodes"]) { for (const auto &node_config : config["nodes"]) {
permanent_assert(node_config.is_object(), "Node config must be a dict"); CHECK(node_config.is_object()) << "Node config must be a dict";
for (int i = 0; i < node_config["count"]; i++) { for (int i = 0; i < node_config["count"]; i++) {
const auto &labels_config = node_config["labels"]; const auto &labels_config = node_config["labels"];
permanent_assert(labels_config.is_array(), CHECK(labels_config.is_array()) << "Must provide an array of node labels";
"Must provide an array of node labels"); CHECK(node_config.size() > 0)
permanent_assert(node_config.size() > 0, << "Node labels array must contain at lest one element";
"Node labels array must contain at lest one element");
auto node_bolt_id = writer.WriteNode( auto node_bolt_id = writer.WriteNode(
labels_config, labels_config,
value_generator.MakeProperties(node_config["properties"])); value_generator.MakeProperties(node_config["properties"]));
@ -308,7 +304,7 @@ int main(int argc, char **argv) {
// Create edges // Create edges
for (const auto &edge_config : config["edges"]) { for (const auto &edge_config : config["edges"]) {
permanent_assert(edge_config.is_object(), "Edge config must be a dict"); CHECK(edge_config.is_object()) << "Edge config must be a dict";
const std::string &from = edge_config["from"]; const std::string &from = edge_config["from"];
const std::string &to = edge_config["to"]; const std::string &to = edge_config["to"];
for (int i = 0; i < edge_config["count"]; i++) for (int i = 0; i < edge_config["count"]; i++)

View File

@ -7,10 +7,11 @@
#include <iostream> #include <iostream>
#include <thread> #include <thread>
#include "glog/logging.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include "utils/assert.hpp"
#include "utils/random/xorshift128plus.hpp" #include "utils/random/xorshift128plus.hpp"
static thread_local Xorshift128plus rnd; static thread_local Xorshift128plus rnd;
@ -44,7 +45,7 @@ int main(void) {
auto max = std::accumulate( auto max = std::accumulate(
buckets.begin(), buckets.end(), 0u, buckets.begin(), buckets.end(), 0u,
[](auto& acc, auto& x) { return std::max(acc, x.load()); }); [](auto& acc, auto& x) { return std::max(acc, x.load()); });
debug_assert(max != 0u, "max is 0."); DCHECK(max != 0u) << "max is 0.";
std::cout << std::fixed; std::cout << std::fixed;

View File

@ -125,7 +125,7 @@ class GraphSession {
Execute(fmt::format("UNWIND RANGE(1, {}) AS r CREATE (n:{} {{id: " Execute(fmt::format("UNWIND RANGE(1, {}) AS r CREATE (n:{} {{id: "
"counter(\"vertex{}\")}}) RETURN min(n.id)", "counter(\"vertex{}\")}}) RETURN min(n.id)",
vertices_count, indexed_label_, id_)); vertices_count, indexed_label_, id_));
permanent_assert(ret.records.size() == 1, "Vertices creation failed!"); CHECK(ret.records.size() == 1) << "Vertices creation failed!";
uint64_t min_id = ret.records[0][0].ValueInt(); uint64_t min_id = ret.records[0][0].ValueInt();
for (uint64_t i = 0; i < vertices_count; ++i) { for (uint64_t i = 0; i < vertices_count; ++i) {
vertices_.insert(min_id + i); vertices_.insert(min_id + i);
@ -164,9 +164,8 @@ class GraphSession {
void CreateEdges(uint64_t edges_count) { void CreateEdges(uint64_t edges_count) {
if (edges_count == 0) return; if (edges_count == 0) return;
auto edges_per_node = (double)edges_count / vertices_.size(); auto edges_per_node = (double)edges_count / vertices_.size();
permanent_assert( CHECK(std::abs(edges_per_node - (int64_t)edges_per_node) < 0.0001)
std::abs(edges_per_node - (int64_t)edges_per_node) < 0.0001, << "Edges per node not a whole number";
"Edges per node not a whole number");
auto ret = Execute(fmt::format( auto ret = Execute(fmt::format(
"MATCH (a:{0}) WITH a " "MATCH (a:{0}) WITH a "
@ -176,7 +175,7 @@ class GraphSession {
"min(e.id), count(e)", "min(e.id), count(e)",
indexed_label_, (int64_t)edges_per_node - 1, vertices_.size(), id_)); indexed_label_, (int64_t)edges_per_node - 1, vertices_.size(), id_));
permanent_assert(ret.records.size() == 1, "Failed to create edges"); CHECK(ret.records.size() == 1) << "Failed to create edges";
uint64_t min_id = ret.records[0][0].ValueInt(); uint64_t min_id = ret.records[0][0].ValueInt();
uint64_t count = ret.records[0][1].ValueInt(); uint64_t count = ret.records[0][1].ValueInt();
for (uint64_t i = 0; i < count; ++i) { for (uint64_t i = 0; i < count; ++i) {
@ -361,9 +360,8 @@ int main(int argc, char **argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]); google::InitGoogleLogging(argv[0]);
permanent_assert(FLAGS_vertex_count > 0, CHECK(FLAGS_vertex_count > 0) << "Vertex count must be greater than 0!";
"Vertex count must be greater than 0!"); CHECK(FLAGS_edge_count > 0) << "Edge count must be greater than 0!";
permanent_assert(FLAGS_edge_count > 0, "Edge count must be greater than 0!");
LOG(INFO) << "Starting Memgraph long running test"; LOG(INFO) << "Starting Memgraph long running test";

View File

@ -19,43 +19,36 @@ TEST(ConcurrentMapSkiplist, Mix) {
auto accessor = skiplist.access(); auto accessor = skiplist.access();
// insert 10 // insert 10
permanent_assert(accessor.insert(1, 10).second == true, "add first element"); EXPECT_TRUE(accessor.insert(1, 10).second);
// try insert 10 again (should fail) // try insert 10 again (should fail)
permanent_assert(accessor.insert(1, 10).second == false, EXPECT_FALSE(accessor.insert(1, 10).second);
"add the same element, should fail");
// insert 20 // insert 20
permanent_assert(accessor.insert(2, 20).second == true, EXPECT_TRUE(accessor.insert(2, 20).second);
"insert new unique element");
print_skiplist(accessor); print_skiplist(accessor);
// value at key 3 shouldn't exist // value at key 3 shouldn't exist
permanent_assert((accessor.find(3) == accessor.end()) == true, EXPECT_TRUE(accessor.find(3) == accessor.end());
"try to find element which doesn't exist");
// value at key 2 should exist // value at key 2 should exist
permanent_assert((accessor.find(2) != accessor.end()) == true, EXPECT_TRUE(accessor.find(2) != accessor.end());
"find iterator");
// at key 2 is 20 (true) // at key 2 is 20 (true)
permanent_assert(accessor.find(2)->second == 20, "find element"); EXPECT_EQ(accessor.find(2)->second, 20);
// removed existing (1) // removed existing (1)
permanent_assert(accessor.remove(1) == true, "try to remove element"); EXPECT_TRUE(accessor.remove(1));
// removed non-existing (3) // removed non-existing (3)
permanent_assert(accessor.remove(3) == false, EXPECT_FALSE(accessor.remove(3));
"try to remove element which doesn't exist");
// insert (1, 10) // insert (1, 10)
permanent_assert(accessor.insert(1, 10).second == true, EXPECT_TRUE(accessor.insert(1, 10).second);
"insert unique element");
// insert (4, 40) // insert (4, 40)
permanent_assert(accessor.insert(4, 40).second == true, EXPECT_TRUE(accessor.insert(4, 40).second);
"insert unique element");
print_skiplist(accessor); print_skiplist(accessor);
} }

View File

@ -16,32 +16,38 @@ TEST(ConcurrentSet, Mix) {
auto accessor = set.access(); auto accessor = set.access();
permanent_assert(accessor.insert(1).second == true, // added non-existing 1? (true)
"added non-existing 1? (true)"); EXPECT_TRUE(accessor.insert(1).second);
permanent_assert(accessor.insert(1).second == false, // added already existing 1? (false)
"added already existing 1? (false)"); EXPECT_FALSE(accessor.insert(1).second);
permanent_assert(accessor.insert(2).second == true, // added non-existing 2? (true)
"added non-existing 2? (true)"); EXPECT_TRUE(accessor.insert(2).second);
permanent_assert(accessor.find(3) == accessor.end(), // item 3 doesn't exist? (true)
"item 3 doesn't exist? (true)"); EXPECT_EQ(accessor.find(3), accessor.end());
permanent_assert(accessor.contains(3) == false, "item 3 exists? (false)"); // item 3 exists? (false)
EXPECT_FALSE(accessor.contains(3));
permanent_assert(accessor.find(2) != accessor.end(), "item 2 exists? (true)"); // item 2 exists? (true)
EXPECT_NE(accessor.find(2), accessor.end());
permanent_assert(*accessor.find(2) == 2, "find item 2"); // find item 2
EXPECT_EQ(*accessor.find(2), 2);
permanent_assert(accessor.remove(1) == true, "removed existing 1? (true)"); // removed existing 1? (true)
EXPECT_TRUE(accessor.remove(1));
permanent_assert(accessor.remove(3) == false, // try to remove non existing element
"try to remove non existing element"); EXPECT_FALSE(accessor.remove(3));
permanent_assert(accessor.insert(1).second == true, "add 1 again"); // add 1 again
EXPECT_TRUE(accessor.insert(1).second);
permanent_assert(accessor.insert(4).second == true, "add 4"); // add 4
EXPECT_TRUE(accessor.insert(4).second);
print_skiplist(accessor); print_skiplist(accessor);
} }

View File

@ -2,13 +2,13 @@
#include <experimental/filesystem> #include <experimental/filesystem>
#include "gflags/gflags.h" #include "gflags/gflags.h"
#include "glog/logging.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "communication/bolt/v1/decoder/decoder.hpp" #include "communication/bolt/v1/decoder/decoder.hpp"
#include "database/dbms.hpp" #include "database/dbms.hpp"
#include "durability/file_reader_buffer.hpp" #include "durability/file_reader_buffer.hpp"
#include "durability/recovery.hpp" #include "durability/recovery.hpp"
#include "utils/assert.hpp"
DECLARE_int32(snapshot_cycle_sec); DECLARE_int32(snapshot_cycle_sec);
@ -88,8 +88,7 @@ void TakeSnapshot(Dbms &dbms, int snapshot_max_retained_) {
std::string GetLatestSnapshot() { std::string GetLatestSnapshot() {
std::vector<fs::path> files = std::vector<fs::path> files =
GetFilesFromDir(SNAPSHOTS_RECOVERY_DEFAULT_DB_DIR); GetFilesFromDir(SNAPSHOTS_RECOVERY_DEFAULT_DB_DIR);
permanent_assert(static_cast<int>(files.size()) == 1, CHECK(static_cast<int>(files.size()) == 1) << "No snapshot files in folder.";
"No snapshot files in folder.");
std::sort(files.rbegin(), files.rend()); std::sort(files.rbegin(), files.rend());
return files[0]; return files[0];
} }
@ -180,8 +179,7 @@ TEST_F(RecoveryTest, TestEncodingAndDecoding) {
edges.push_back(edge); edges.push_back(edge);
edge_count++; edge_count++;
} }
permanent_assert(static_cast<int>(edges.size()) == 2, CHECK(static_cast<int>(edges.size()) == 2) << "There should be two edges.";
"There should be two edges.");
EXPECT_EQ(edge_count, 2); EXPECT_EQ(edge_count, 2);
EXPECT_TRUE(edges[0].to() == edges[1].to()); EXPECT_TRUE(edges[0].to() == edges[1].to());

View File

@ -2,10 +2,10 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "glog/logging.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "data_structures/concurrent/skiplist.hpp" #include "data_structures/concurrent/skiplist.hpp"
#include "utils/assert.hpp"
/* The following tests validate the SkipList::position_and_count estimation /* The following tests validate the SkipList::position_and_count estimation
* functionality. That function has a tunable speed vs. accuracy. The tests * functionality. That function has a tunable speed vs. accuracy. The tests
@ -25,7 +25,7 @@ auto SkiplistRange(int count) {
auto Median(std::vector<int> &elements) { auto Median(std::vector<int> &elements) {
auto elem_size = elements.size(); auto elem_size = elements.size();
debug_assert(elem_size > 0, "Provide some elements to get median!"); DCHECK(elem_size > 0) << "Provide some elements to get median!";
std::sort(elements.begin(), elements.end()); std::sort(elements.begin(), elements.end());
if (elem_size % 2) if (elem_size % 2)
return elements[elem_size / 2]; return elements[elem_size / 2];