diff --git a/format.clang-format b/.clang-format similarity index 98% rename from format.clang-format rename to .clang-format index fa5dbcb08..0e21026ee 100644 --- a/format.clang-format +++ b/.clang-format @@ -20,7 +20,7 @@ AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: true BinPackArguments: true BinPackParameters: true -BraceWrapping: +BraceWrapping: AfterClass: true AfterControlStatement: false AfterEnum: true @@ -46,7 +46,7 @@ DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] -IncludeCategories: +IncludeCategories: - Regex: '^"(llvm|llvm-c|clang|clang-c)/' Priority: 2 - Regex: '^(<|"(gtest|isl|json)/)' @@ -87,4 +87,3 @@ Standard: "C++11" TabWidth: 8 UseTab: Never ... - diff --git a/.gitignore b/.gitignore index f81f13db7..320fbc5c7 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ memgraph *.session.yaml tags .gdb_history +Testing/ diff --git a/src/data_structures/concurrent/concurrent_map.hpp b/src/data_structures/concurrent/concurrent_map.hpp index c9d9064e7..3a8d34bef 100644 --- a/src/data_structures/concurrent/concurrent_map.hpp +++ b/src/data_structures/concurrent/concurrent_map.hpp @@ -5,37 +5,46 @@ using std::pair; -template class ConcurrentMap { +template +class ConcurrentMap +{ class Item : public TotalOrdering, public TotalOrdering, public TotalOrdering, - public pair { - public: + public pair + { +public: using pair::pair; - friend constexpr bool operator<(const Item &lhs, const Item &rhs) { + friend constexpr bool operator<(const Item &lhs, const Item &rhs) + { std::pair *a; return lhs.first < rhs.first; } - friend constexpr bool operator==(const Item &lhs, const Item &rhs) { + friend constexpr bool operator==(const Item &lhs, const Item &rhs) + { return lhs.first == rhs.first; } - friend constexpr bool operator<(const K &lhs, const Item &rhs) { + friend constexpr bool operator<(const K &lhs, const Item &rhs) + { return lhs < rhs.first; } - friend constexpr bool operator==(const K &lhs, const Item &rhs) { + friend constexpr bool operator==(const K &lhs, const Item &rhs) + { return lhs == rhs.first; } - friend constexpr bool operator<(const Item &lhs, const K &rhs) { + friend constexpr bool operator<(const Item &lhs, const K &rhs) + { return lhs.first < rhs; } - friend constexpr bool operator==(const Item &lhs, const K &rhs) { + friend constexpr bool operator==(const Item &lhs, const K &rhs) + { return lhs.first == rhs; } }; @@ -44,16 +53,17 @@ template class ConcurrentMap { typedef typename SkipList::Iterator list_it; typedef typename SkipList::ConstIterator list_it_con; -public: + public: ConcurrentMap() {} friend class Accessor; - class Accessor { + class Accessor + { friend class ConcurrentMap; Accessor(list *skiplist) : accessor(skiplist->access()) {} - public: +public: Accessor(const Accessor &) = delete; Accessor(Accessor &&other) : accessor(std::move(other.accessor)) {} @@ -72,15 +82,18 @@ public: list_it_con cend() const { return accessor.cend(); } - std::pair insert(const K &key, const T &data) { + std::pair insert(const K &key, const T &data) + { return accessor.insert(Item(key, data)); } - std::pair insert(const K &key, T &&data) { + std::pair insert(const K &key, T &&data) + { return accessor.insert(Item(key, std::forward(data))); } - std::pair insert(K &&key, T &&data) { + std::pair insert(K &&key, T &&data) + { return accessor.insert(Item(std::forward(key), std::forward(data))); } @@ -94,7 +107,7 @@ public: size_t size() const { return accessor.size(); } - private: +private: typename list::Accessor accessor; }; @@ -102,6 +115,6 @@ public: const Accessor access() const { return Accessor(&skiplist); } -private: + private: list skiplist; }; diff --git a/src/data_structures/concurrent/skiplist.hpp b/src/data_structures/concurrent/skiplist.hpp index eec501a53..06dc45150 100644 --- a/src/data_structures/concurrent/skiplist.hpp +++ b/src/data_structures/concurrent/skiplist.hpp @@ -94,8 +94,9 @@ * and deletion of nodes. */ template -class SkipList : private Lockable { -public: +class SkipList : private Lockable +{ + public: // computes the height for the new node from the interval [1...H] // with p(k) = (1/2)^k for all k from the interval static thread_local FastBinomial rnd; @@ -106,8 +107,10 @@ public: * FULLY_LINKED is used to mark the node as fully inserted, i.e. linked * at all layers in the skiplist up to the node height */ - struct Flags { - enum node_flags : uint8_t { + struct Flags + { + enum node_flags : uint8_t + { MARKED = 0x01, FULLY_LINKED = 0x10, }; @@ -120,12 +123,13 @@ public: void set_fully_linked() { flags.fetch_or(FULLY_LINKED); } - private: +private: std::atomic flags{0}; }; - class Node : Lockable { - public: + class Node : Lockable + { +public: friend class SkipList; const uint8_t height; @@ -135,17 +139,20 @@ public: const T &value() const { return data.get(); } - static Node *sentinel(uint8_t height) { + static Node *sentinel(uint8_t height) + { // we have raw memory and we need to construct an object // of type Node on it return new (allocate(height)) Node(height); } - static Node *create(const T &item, uint8_t height) { + static Node *create(const T &item, uint8_t height) + { return create(item, height); } - static Node *create(T &&item, uint8_t height) { + static Node *create(T &&item, uint8_t height) + { auto node = allocate(height); // we have raw memory and we need to construct an object @@ -153,7 +160,8 @@ public: return new (node) Node(std::forward(item), height); } - static void destroy(Node *node) { + static void destroy(Node *node) + { node->~Node(); std::free(node); } @@ -162,8 +170,9 @@ public: void forward(size_t level, Node *next) { tower[level].store(next); } - private: - Node(uint8_t height) : height(height) { +private: + Node(uint8_t height) : height(height) + { // here we assume, that the memory for N towers (N = height) has // been allocated right after the Node structure so we need to // initialize that memory @@ -171,16 +180,19 @@ public: new (&tower[i]) std::atomic{nullptr}; } - Node(T &&data, uint8_t height) : Node(height) { + Node(T &&data, uint8_t height) : Node(height) + { this->data.set(std::forward(data)); } - ~Node() { + ~Node() + { for (auto i = 0; i < height; ++i) tower[i].~atomic(); } - static Node *allocate(uint8_t height) { + static Node *allocate(uint8_t height) + { // [ Node ][Node*][Node*][Node*]...[Node*] // | | | | | // | 0 1 2 height-1 @@ -205,33 +217,39 @@ public: std::atomic tower[0]; }; -public: - template class IteratorBase : public Crtp { - protected: + public: + template + class IteratorBase : public Crtp + { +protected: IteratorBase(Node *node) : node(node) {} Node *node{nullptr}; - public: +public: IteratorBase() = default; IteratorBase(const IteratorBase &) = default; - T &operator*() { + T &operator*() + { assert(node != nullptr); return node->value(); } - T *operator->() { + T *operator->() + { assert(node != nullptr); return &node->value(); } - operator T &() { + operator T &() + { assert(node != nullptr); return node->value(); } - It &operator++() { + It &operator++() + { assert(node != nullptr); node = node->forward(0); return this->derived(); @@ -239,18 +257,20 @@ public: It &operator++(int) { return operator++(); } - friend bool operator==(const It &a, const It &b) { + friend bool operator==(const It &a, const It &b) + { return a.node == b.node; } friend bool operator!=(const It &a, const It &b) { return !(a == b); } }; - class ConstIterator : public IteratorBase { + class ConstIterator : public IteratorBase + { friend class SkipList; ConstIterator(Node *node) : IteratorBase(node) {} - public: +public: ConstIterator() = default; ConstIterator(const ConstIterator &) = default; @@ -261,18 +281,20 @@ public: operator const T &() { return IteratorBase::operator T &(); } }; - class Iterator : public IteratorBase { + class Iterator : public IteratorBase + { friend class SkipList; Iterator(Node *node) : IteratorBase(node) {} - public: +public: Iterator() = default; Iterator(const Iterator &) = default; }; SkipList() : header(Node::sentinel(H)) {} - ~SkipList() { + ~SkipList() + { // Someone could be using this map through an Accessor. Node *now = header; header = nullptr; @@ -286,25 +308,28 @@ public: friend class Accessor; - class Accessor { + class Accessor + { friend class SkipList; - Accessor(SkipList *skiplist) : skiplist(skiplist) { + Accessor(SkipList *skiplist) : skiplist(skiplist) + { assert(skiplist != nullptr); skiplist->gc.add_ref(); } - public: +public: Accessor(const Accessor &) = delete; - Accessor(Accessor &&other) : skiplist(other.skiplist) { + Accessor(Accessor &&other) : skiplist(other.skiplist) + { other.skiplist = nullptr; } - ~Accessor() { - if (skiplist == nullptr) - return; + ~Accessor() + { + if (skiplist == nullptr) return; skiplist->gc.release_ref(); } @@ -321,33 +346,43 @@ public: ConstIterator cend() const { return skiplist->cend(); } - std::pair insert(const T &item) { + std::pair insert(const T &item) + { return skiplist->insert(item, preds, succs); } - std::pair insert(T &&item) { + std::pair insert(T &&item) + { return skiplist->insert(std::forward(item), preds, succs); } - template ConstIterator find(const K &item) const { + template + ConstIterator find(const K &item) const + { return static_cast(*skiplist).find(item); } - template Iterator find(const K &item) { + template + Iterator find(const K &item) + { return skiplist->find(item); } - template bool contains(const K &item) const { + template + bool contains(const K &item) const + { return this->find(item) != this->end(); } - template bool remove(const K &item) { + template + bool remove(const K &item) + { return skiplist->remove(item, preds, succs); } size_t size() const { return skiplist->size(); } - private: +private: SkipList *skiplist; Node *preds[H], *succs[H]; }; @@ -356,7 +391,7 @@ public: const Accessor access() const { return Accessor(this); } -private: + private: using guard_t = std::unique_lock; Iterator begin() { return Iterator(header->forward(0)); } @@ -373,23 +408,33 @@ private: size_t size() const { return count.load(); } - template bool greater(const K &item, const Node *const node) { + template + bool greater(const K &item, const Node *const node) + { return node && item > node->value(); } - template bool less(const K &item, const Node *const node) { + template + bool less(const K &item, const Node *const node) + { return (node == nullptr) || item < node->value(); } - template ConstIterator find(const K &item) const { + template + ConstIterator find(const K &item) const + { return const_cast(this)->find_node(item); } - template Iterator find(const K &item) { + template + Iterator find(const K &item) + { return find_node(item); } - template It find_node(const K &item) { + template + It find_node(const K &item) + { Node *node, *pred = header; int h = static_cast(pred->height) - 1; @@ -399,8 +444,7 @@ private: } // if we overshoot at every layer, item doesn't exist - if (h < 0) - return It(); + if (h < 0) return It(); // the item is farther to the right, continue going right as long // as the key is greater than the current node's key @@ -408,14 +452,14 @@ private: pred = node, node = node->forward(h); // check if we have a hit. if not, we need to descend down again - if (!less(item, node) && !node->flags.is_marked()) - return It(node); + if (!less(item, node) && !node->flags.is_marked()) return It(node); } } template int find_path(Node *from, int start, const K &item, Node *preds[], - Node *succs[]) { + Node *succs[]) + { int level_found = -1; Node *pred = from; @@ -425,8 +469,7 @@ private: while (greater(item, node)) pred = node, node = pred->forward(level); - if (level_found == -1 && !less(item, node)) - level_found = level; + if (level_found == -1 && !less(item, node)) level_found = level; preds[level] = pred; succs[level] = node; @@ -437,7 +480,8 @@ private: template bool lock_nodes(uint8_t height, guard_t guards[], Node *preds[], - Node *succs[]) { + Node *succs[]) + { Node *prepred, *pred, *succ = nullptr; bool valid = true; @@ -456,7 +500,8 @@ private: return valid; } - std::pair insert(T &&data, Node *preds[], Node *succs[]) { + std::pair insert(T &&data, Node *preds[], Node *succs[]) + { while (true) { // TODO: before here was data.first auto level = find_path(header, H - 1, data, preds, succs); @@ -464,8 +509,7 @@ private: if (level != -1) { auto found = succs[level]; - if (found->flags.is_marked()) - continue; + if (found->flags.is_marked()) continue; while (!found->flags.is_fully_linked()) usleep(250); @@ -479,8 +523,7 @@ private: // try to acquire the locks for predecessors up to the height of // the new node. release the locks and try again if someone else // has the locks - if (!lock_nodes(height, guards, preds, succs)) - continue; + if (!lock_nodes(height, guards, preds, succs)) continue; // you have the locks, create a new node auto new_node = Node::create(std::forward(data), height); @@ -503,12 +546,15 @@ private: } } - bool ok_delete(Node *node, int level) { + bool ok_delete(Node *node, int level) + { return node->flags.is_fully_linked() && node->height - 1 == level && !node->flags.is_marked(); } - template bool remove(const K &item, Node *preds[], Node *succs[]) { + template + bool remove(const K &item, Node *preds[], Node *succs[]) + { Node *node = nullptr; guard_t node_guard; bool marked = false; @@ -525,8 +571,7 @@ private: height = node->height; node_guard = node->acquire_unique(); - if (node->flags.is_marked()) - return false; + if (node->flags.is_marked()) return false; node->flags.set_marked(); marked = true; @@ -534,8 +579,7 @@ private: guard_t guards[H]; - if (!lock_nodes(height, guards, preds, succs)) - continue; + if (!lock_nodes(height, guards, preds, succs)) continue; for (int level = height - 1; level >= 0; --level) preds[level]->forward(level, node->forward(level)); diff --git a/src/data_structures/concurrent/skiplist_gc.hpp b/src/data_structures/concurrent/skiplist_gc.hpp index 7faf96008..b1701b60f 100644 --- a/src/data_structures/concurrent/skiplist_gc.hpp +++ b/src/data_structures/concurrent/skiplist_gc.hpp @@ -8,8 +8,9 @@ #include "threading/sync/spinlock.hpp" template -class SkiplistGC : public LazyGC, lock_t> { -public: +class SkiplistGC : public LazyGC, lock_t> +{ + public: // release_ref method should be called by a thread // when the thread finish it job over object // which has to be lazy cleaned @@ -17,7 +18,8 @@ public: // are going to be deleted // the only problem with this approach is that // GC may never be called, but for now we can deal with that - void release_ref() { + void release_ref() + { std::vector local_freelist; // take freelist if there is no more threads @@ -47,6 +49,6 @@ public: void collect(T *node) { freelist.add(node); } -private: + private: FreeList freelist; }; diff --git a/src/memory/lazy_gc.hpp b/src/memory/lazy_gc.hpp index 8484f8796..fd9ca312a 100644 --- a/src/memory/lazy_gc.hpp +++ b/src/memory/lazy_gc.hpp @@ -8,17 +8,19 @@ #include "utils/crtp.hpp" template -class LazyGC : public Crtp, public Lockable { -public: +class LazyGC : public Crtp, public Lockable +{ + public: // add_ref method should be called by a thread // when the thread has to do something over // object which has to be lazy cleaned when // the thread finish it job - void add_ref() { + void add_ref() + { auto lock = this->acquire_unique(); ++count; } -protected: + protected: size_t count{0}; }; diff --git a/src/storage/edges.hpp b/src/storage/edges.hpp index 8349f9b2f..09c85ffdf 100644 --- a/src/storage/edges.hpp +++ b/src/storage/edges.hpp @@ -4,25 +4,26 @@ #include "data_structures/concurrent/concurrent_map.hpp" #include "edge_accessor.hpp" -class Edges { -public: - Edge::Accessor find(tx::Transaction &t, const Id &id) { +class Edges +{ + public: + Edge::Accessor find(tx::Transaction &t, const Id &id) + { auto edges_accessor = edges.access(); auto edges_iterator = edges_accessor.find(id); - if (edges_iterator == edges_accessor.end()) - return Edge::Accessor(); + if (edges_iterator == edges_accessor.end()) return Edge::Accessor(); // find edge auto edge = edges_iterator->second.find(t); - if (edge == nullptr) - return Edge::Accessor(); + if (edge == nullptr) return Edge::Accessor(); return Edge::Accessor(edge, &edges_iterator->second, this); } - Edge::Accessor insert(tx::Transaction &t) { + Edge::Accessor insert(tx::Transaction &t) + { // get next vertex id auto next = counter.next(std::memory_order_acquire); @@ -40,7 +41,7 @@ public: return Edge::Accessor(edge, &inserted_edge_record->second, this); } -private: + private: ConcurrentMap edges; AtomicCounter counter; }; diff --git a/src/storage/indexes/index.hpp b/src/storage/indexes/index.hpp index 850835bd5..4b24e65a3 100644 --- a/src/storage/indexes/index.hpp +++ b/src/storage/indexes/index.hpp @@ -7,13 +7,16 @@ #include "storage/indexes/index_record_collection.hpp" #include "storage/label/label.hpp" -template class Index { -public: +template +class Index +{ + public: using container_t = ConcurrentMap; Index() : index(std::make_unique()) {} - auto update(const Label &label, VertexIndexRecord &&index_record) { + auto update(const Label &label, VertexIndexRecord &&index_record) + { auto accessor = index->access(); auto label_ref = label_ref_t(label); @@ -27,7 +30,8 @@ public: record_collection.add(std::forward(index_record)); } - VertexIndexRecordCollection &find(const Label &label) { + VertexIndexRecordCollection &find(const Label &label) + { // TODO: accessor should be outside? // bacause otherwise GC could delete record that has just be returned auto label_ref = label_ref_t(label); @@ -35,6 +39,6 @@ public: return (*accessor.find(label_ref)).second; } -private: + private: std::unique_ptr index; }; diff --git a/src/storage/vertices.cpp b/src/storage/vertices.cpp index 4f4075845..5ea95768b 100644 --- a/src/storage/vertices.cpp +++ b/src/storage/vertices.cpp @@ -1,22 +1,22 @@ #include "storage/vertices.hpp" -const Vertex::Accessor Vertices::find(tx::Transaction &t, const Id &id) { +const Vertex::Accessor Vertices::find(tx::Transaction &t, const Id &id) +{ auto vertices_accessor = vertices.access(); auto vertices_iterator = vertices_accessor.find(id); - if (vertices_iterator == vertices_accessor.end()) - return Vertex::Accessor(); + if (vertices_iterator == vertices_accessor.end()) return Vertex::Accessor(); // find vertex auto vertex = vertices_iterator->second.find(t); - if (vertex == nullptr) - return Vertex::Accessor(); + if (vertex == nullptr) return Vertex::Accessor(); return Vertex::Accessor(vertex, &vertices_iterator->second, this); } -Vertex::Accessor Vertices::insert(tx::Transaction &t) { +Vertex::Accessor Vertices::insert(tx::Transaction &t) +{ // get next vertex id auto next = counter.next(); @@ -36,10 +36,12 @@ Vertex::Accessor Vertices::insert(tx::Transaction &t) { } void Vertices::update_label_index(const Label &label, - VertexIndexRecord &&index_record) { + VertexIndexRecord &&index_record) +{ label_index.update(label, std::forward(index_record)); } -VertexIndexRecordCollection &Vertices::find_label_index(const Label &label) { +VertexIndexRecordCollection &Vertices::find_label_index(const Label &label) +{ return label_index.find(label); } diff --git a/src/utils/total_ordering.hpp b/src/utils/total_ordering.hpp index c59d4ea86..4200fc046 100644 --- a/src/utils/total_ordering.hpp +++ b/src/utils/total_ordering.hpp @@ -1,19 +1,25 @@ #pragma once -template struct TotalOrdering { - friend constexpr bool operator!=(const Derived &a, const Other &b) { +template +struct TotalOrdering +{ + friend constexpr bool operator!=(const Derived &a, const Other &b) + { return !(a == b); } - friend constexpr bool operator<=(const Derived &a, const Other &b) { + friend constexpr bool operator<=(const Derived &a, const Other &b) + { return a < b || a == b; } - friend constexpr bool operator>(const Derived &a, const Other &b) { + friend constexpr bool operator>(const Derived &a, const Other &b) + { return !(a <= b); } - friend constexpr bool operator>=(const Derived &a, const Other &b) { + friend constexpr bool operator>=(const Derived &a, const Other &b) + { return !(a < b); } }; diff --git a/tests/concurrent/common.h b/tests/concurrent/common.h index aed251592..a8cf44b4a 100644 --- a/tests/concurrent/common.h +++ b/tests/concurrent/common.h @@ -19,26 +19,30 @@ using skiplist_t = ConcurrentMap; using namespace std::chrono_literals; // Returns uniform random size_t generator from range [0,n> -auto rand_gen(size_t n) { +auto rand_gen(size_t n) +{ std::default_random_engine generator; std::uniform_int_distribution distribution(0, n - 1); return std::bind(distribution, generator); } // Returns random bool generator with distribution of 1 true for n false. -auto rand_gen_bool(size_t n = 1) { +auto rand_gen_bool(size_t n = 1) +{ auto gen = rand_gen(n + 1); return [=]() mutable { return gen() == 0; }; } // Checks for all owned.second keys if there data is owned.first. void check_present_same(skiplist_t::Accessor &acc, - std::pair> &owned) { + std::pair> &owned) +{ check_present_same(acc, owned.first, owned.second); } // Checks for all owned keys if there data is data. void check_present_same(skiplist_t::Accessor &acc, size_t data, - std::vector &owned) { + std::vector &owned) +{ for (auto num : owned) { permanent_assert(acc.find(num)->second == data, "My data is present and my"); @@ -46,7 +50,8 @@ void check_present_same(skiplist_t::Accessor &acc, size_t data, } // Checks if reported size and traversed size are equal to given size. -void check_size(const skiplist_t::Accessor &acc, long long size) { +void check_size(const skiplist_t::Accessor &acc, long long size) +{ // check size permanent_assert(acc.size() == size, @@ -70,7 +75,8 @@ void check_size(const skiplist_t::Accessor &acc, long long size) { template std::vector>> run(size_t threads_no, skiplist_t &skiplist, - std::function f) { + std::function f) +{ std::vector>> futures; for (size_t thread_i = 0; thread_i < threads_no; ++thread_i) { @@ -84,7 +90,9 @@ run(size_t threads_no, skiplist_t &skiplist, } // Collects all data from futures. -template auto collect(std::vector> &collect) { +template +auto collect(std::vector> &collect) +{ std::vector collection; for (auto &fut : collect) { collection.push_back(fut.get()); @@ -96,7 +104,8 @@ template auto collect(std::vector> &collect) { // downcounts. template auto insert_try(skiplist_t::Accessor &acc, size_t &downcount, - std::vector &owned) { + std::vector &owned) +{ return [&](K key, D data) mutable { if (acc.insert(key, data).second) { downcount--; @@ -106,7 +115,8 @@ auto insert_try(skiplist_t::Accessor &acc, size_t &downcount, } // Helper function. -int parseLine(char *line) { +int parseLine(char *line) +{ // This assumes that a digit will be found and the line ends in " Kb". int i = strlen(line); const char *p = line; @@ -118,7 +128,8 @@ int parseLine(char *line) { } // Returns currentlz used memory in kB. -int currently_used_memory() { // Note: this value is in KB! +int currently_used_memory() +{ // Note: this value is in KB! FILE *file = fopen("/proc/self/status", "r"); int result = -1; char line[128]; @@ -137,7 +148,8 @@ int currently_used_memory() { // Note: this value is in KB! // function // is aproximately equal to memory usage after function. Memory usage is thread // senstive so no_threads spawned in function is necessary. -void memory_check(size_t no_threads, std::function f) { +void memory_check(size_t no_threads, std::function f) +{ long long start = currently_used_memory(); f(); long long leaked = diff --git a/tests/concurrent/linkedlist.cpp b/tests/concurrent/linkedlist.cpp index 4ef5de29f..a05d29647 100644 --- a/tests/concurrent/linkedlist.cpp +++ b/tests/concurrent/linkedlist.cpp @@ -10,51 +10,51 @@ using std::endl; template void test_concurrent_list_access(list_type &list, std::size_t size) { - // test concurrent access - for (int i = 0; i < 1000000; ++i) { + // test concurrent access + for (int i = 0; i < 1000000; ++i) { - std::thread t1([&list] { - list.push_front(1); - list.pop_front(); - }); + std::thread t1([&list] { + list.push_front(1); + list.pop_front(); + }); - std::thread t2([&list] { - list.push_front(2); - list.pop_front(); - }); + std::thread t2([&list] { + list.push_front(2); + list.pop_front(); + }); - t1.join(); - t2.join(); + t1.join(); + t2.join(); - assert(list.size() == size); - } + assert(list.size() == size); + } } int main() { - LinkedList list; + LinkedList list; - // push & pop operations - list.push_front(10); - list.push_front(20); - auto a = list.front(); - assert(a == 20); - list.pop_front(); - a = list.front(); - assert(a == 10); - list.pop_front(); - assert(list.size() == 0); + // push & pop operations + list.push_front(10); + list.push_front(20); + auto a = list.front(); + assert(a == 20); + list.pop_front(); + a = list.front(); + assert(a == 10); + list.pop_front(); + assert(list.size() == 0); - // concurrent test - LinkedList concurrent_list; - concurrent_list.push_front(1); - concurrent_list.push_front(1); - std::list no_concurrent_list; - no_concurrent_list.push_front(1); - no_concurrent_list.push_front(1); - - test_concurrent_list_access(concurrent_list, 2); - // test_concurrent_list_access(no_concurrent_list, 2); + // concurrent test + LinkedList concurrent_list; + concurrent_list.push_front(1); + concurrent_list.push_front(1); + std::list no_concurrent_list; + no_concurrent_list.push_front(1); + no_concurrent_list.push_front(1); - return 0; + test_concurrent_list_access(concurrent_list, 2); + // test_concurrent_list_access(no_concurrent_list, 2); + + return 0; } diff --git a/tests/concurrent/skiplist.cpp b/tests/concurrent/skiplist.cpp index d08938dbb..97b4ea84f 100644 --- a/tests/concurrent/skiplist.cpp +++ b/tests/concurrent/skiplist.cpp @@ -3,7 +3,8 @@ #define THREADS_NO 1 constexpr size_t elems_per_thread = 16e5; -int main() { +int main() +{ memory_check(THREADS_NO, [&] { ds::static_array threads; skiplist_t skiplist; @@ -33,15 +34,15 @@ int main() { } for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) { - threads[thread_i] = std::thread( - [&skiplist](size_t start, size_t end) { - auto accessor = skiplist.access(); - for (size_t elem_i = 0; elem_i < elems_per_thread; ++elem_i) { - permanent_assert(accessor.remove(elem_i) == true, ""); - } - }, - thread_i * elems_per_thread, - thread_i * elems_per_thread + elems_per_thread); + threads[thread_i] = std::thread( + [&skiplist](size_t start, size_t end) { + auto accessor = skiplist.access(); + for (size_t elem_i = 0; elem_i < elems_per_thread; ++elem_i) { + permanent_assert(accessor.remove(elem_i) == true, ""); + } + }, + thread_i * elems_per_thread, + thread_i * elems_per_thread + elems_per_thread); } // wait all threads for (auto &thread : threads) { diff --git a/tests/concurrent/sl_insert.cpp b/tests/concurrent/sl_insert.cpp index ba3497567..20b77ed1f 100644 --- a/tests/concurrent/sl_insert.cpp +++ b/tests/concurrent/sl_insert.cpp @@ -7,7 +7,8 @@ constexpr size_t key_range = elems_per_thread * THREADS_NO * 2; // This test checks insert_unique method under pressure. // Test checks for missing data and changed/overwriten data. -int main() { +int main() +{ memory_check(THREADS_NO, [] { skiplist_t skiplist; diff --git a/tests/concurrent/sl_insert_competetive.cpp b/tests/concurrent/sl_insert_competetive.cpp index f884f1212..be964b545 100644 --- a/tests/concurrent/sl_insert_competetive.cpp +++ b/tests/concurrent/sl_insert_competetive.cpp @@ -8,7 +8,8 @@ constexpr size_t key_range = elems_per_thread * THREADS_NO * 2; // Threads will try to insert keys in the same order. // This will force threads to compete intensly with each other. // Test checks for missing data and changed/overwriten data. -int main() { +int main() +{ memory_check(THREADS_NO, [] { skiplist_t skiplist; diff --git a/tests/concurrent/sl_memory.cpp b/tests/concurrent/sl_memory.cpp index 02521b652..cdfaf78ed 100644 --- a/tests/concurrent/sl_memory.cpp +++ b/tests/concurrent/sl_memory.cpp @@ -5,7 +5,8 @@ constexpr size_t elements = 2e6; // Test for simple memory leaks -int main() { +int main() +{ memory_check(THREADS_NO, [] { skiplist_t skiplist; diff --git a/tests/concurrent/sl_remove_competetive.cpp b/tests/concurrent/sl_remove_competetive.cpp index d0bfbab56..2efd4ffd5 100644 --- a/tests/concurrent/sl_remove_competetive.cpp +++ b/tests/concurrent/sl_remove_competetive.cpp @@ -10,7 +10,8 @@ constexpr size_t no_insert_for_one_delete = 2; // Threads will try to insert and remove keys aproximetly in the same order. // This will force threads to compete intensly with each other. // Calls of remove method are interleaved with insert calls. -int main() { +int main() +{ memory_check(THREADS_NO, [] { skiplist_t skiplist; diff --git a/tests/concurrent/sl_remove_disjoint.cpp b/tests/concurrent/sl_remove_disjoint.cpp index 34b47321e..48fb8d4a5 100644 --- a/tests/concurrent/sl_remove_disjoint.cpp +++ b/tests/concurrent/sl_remove_disjoint.cpp @@ -8,7 +8,8 @@ constexpr size_t no_insert_for_one_delete = 1; // This test checks remove method under pressure. // Each thread removes it's own data. So removes are disjoint. // Calls of remove method are interleaved with insert calls. -int main() { +int main() +{ memory_check(THREADS_NO, [] { skiplist_t skiplist; diff --git a/tests/concurrent/sl_remove_joint.cpp b/tests/concurrent/sl_remove_joint.cpp index 6a7d7fd9e..b1d0f4ba9 100644 --- a/tests/concurrent/sl_remove_joint.cpp +++ b/tests/concurrent/sl_remove_joint.cpp @@ -10,7 +10,8 @@ constexpr size_t no_insert_for_one_delete = 2; // This test checks remove method under pressure. // Each thread removes random data. So removes are joint. // Calls of remove method are interleaved with insert calls. -int main() { +int main() +{ memory_check(THREADS_NO, [] { skiplist_t skiplist; diff --git a/tests/concurrent/sl_simulation.cpp b/tests/concurrent/sl_simulation.cpp index 86e467df8..839fc28ad 100644 --- a/tests/concurrent/sl_simulation.cpp +++ b/tests/concurrent/sl_simulation.cpp @@ -12,7 +12,8 @@ constexpr size_t no_insert_for_one_delete = 1; // Each thread makes a series of finds interleaved with method which change. // Exact ratio of finds per change and insert per delete can be regulated with // no_find_per_change and no_insert_for_one_delete. -int main() { +int main() +{ memory_check(THREADS_NO, [] { skiplist_t skiplist;