include/simdb/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
233 / 233
100.0%
Branches:
102 / 190
53.7%
Functions:
46 / 46
100.0%

utils/ConcurrentQueue.hpp
Line Branch Exec Source
1 // <ConcurrentQueue.hpp> -*- C++ -*-
2
3 #pragma once
4
5 #include "simdb/Assert.hpp"
6 #include <deque>
7 #include <functional>
8 #include <mutex>
9
10 namespace simdb {
11
12 /*!
13 * \class ConcurrentQueue<T>
14 *
15 * \brief Thread-safe wrapper around std::queue
16 */
17 template <typename T> class ConcurrentQueue
18 {
19 public:
20 /// \brief Construct.
21 52 ConcurrentQueue()
22 52 {
23 // Get size() code coverage
24
22/110
simdb::ConcurrentQueue<DummyDataWindowBytes>::ConcurrentQueue():
✓ Branch 4 → 5 taken 2 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 2 times.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<DummyData>::ConcurrentQueue():
✓ Branch 4 → 5 taken 1 time.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 1 time.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<simdb::argos::NotifEntry>::ConcurrentQueue():
✓ Branch 4 → 5 taken 11 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 11 times.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<simdb::argos::CollectionEntries>::ConcurrentQueue():
✓ Branch 4 → 5 taken 5 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 5 times.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<simdb::argos::CompressedCollectionEntries>::ConcurrentQueue():
✓ Branch 4 → 5 taken 5 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 5 times.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<std::shared_ptr<simdb::pipeline::AsyncDatabaseTask> >::ConcurrentQueue():
✓ Branch 4 → 5 taken 9 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 9 times.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> > >::ConcurrentQueue():
✓ Branch 4 → 5 taken 5 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 5 times.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::ConcurrentQueue():
✓ Branch 4 → 5 taken 1 time.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 1 time.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<std::vector<char, std::allocator<char> > >::ConcurrentQueue():
✓ Branch 4 → 5 taken 6 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 6 times.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<std::vector<double, std::allocator<double> > >::ConcurrentQueue():
✓ Branch 4 → 5 taken 6 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 6 times.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
simdb::ConcurrentQueue<int>::ConcurrentQueue():
✓ Branch 4 → 5 taken 1 time.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 16 taken 1 time.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 14 → 15 not taken.
52 simdb_assert(size() == 0);
25 52 }
26
27 /// \brief Push an item to the back of the queue.
28 22683 void push(const T& item)
29 {
30
1/1
✓ Branch 2 → 3 taken 22683 times.
22683 std::lock_guard<std::mutex> guard(mutex_);
31
1/1
✓ Branch 3 → 4 taken 22683 times.
22683 queue_.push_back(item);
32 22683 }
33
34 /// \brief Push an item to the back of the queue (move version).
35 44702 void emplace(T&& item)
36 {
37
9/9
simdb::ConcurrentQueue<DummyDataWindowBytes>::emplace(DummyDataWindowBytes&&):
✓ Branch 2 → 3 taken 2000 times.
simdb::ConcurrentQueue<DummyData>::emplace(DummyData&&):
✓ Branch 2 → 3 taken 9999 times.
simdb::ConcurrentQueue<simdb::argos::NotifEntry>::emplace(simdb::argos::NotifEntry&&):
✓ Branch 2 → 3 taken 1 time.
simdb::ConcurrentQueue<simdb::argos::CollectionEntries>::emplace(simdb::argos::CollectionEntries&&):
✓ Branch 2 → 3 taken 3005 times.
simdb::ConcurrentQueue<simdb::argos::CompressedCollectionEntries>::emplace(simdb::argos::CompressedCollectionEntries&&):
✓ Branch 2 → 3 taken 3005 times.
simdb::ConcurrentQueue<std::shared_ptr<simdb::pipeline::AsyncDatabaseTask> >::emplace(std::shared_ptr<simdb::pipeline::AsyncDatabaseTask>&&):
✓ Branch 2 → 3 taken 4 times.
simdb::ConcurrentQueue<std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> > >::emplace(std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> >&&):
✓ Branch 2 → 3 taken 3005 times.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::emplace(std::vector<DummyData, std::allocator<DummyData> >&&):
✓ Branch 2 → 3 taken 1000 times.
simdb::ConcurrentQueue<std::vector<char, std::allocator<char> > >::emplace(std::vector<char, std::allocator<char> >&&):
✓ Branch 2 → 3 taken 22683 times.
44702 std::lock_guard<std::mutex> guard(mutex_);
38
9/9
simdb::ConcurrentQueue<DummyDataWindowBytes>::emplace(DummyDataWindowBytes&&):
✓ Branch 4 → 5 taken 2000 times.
simdb::ConcurrentQueue<DummyData>::emplace(DummyData&&):
✓ Branch 4 → 5 taken 9999 times.
simdb::ConcurrentQueue<simdb::argos::NotifEntry>::emplace(simdb::argos::NotifEntry&&):
✓ Branch 4 → 5 taken 1 time.
simdb::ConcurrentQueue<simdb::argos::CollectionEntries>::emplace(simdb::argos::CollectionEntries&&):
✓ Branch 4 → 5 taken 3005 times.
simdb::ConcurrentQueue<simdb::argos::CompressedCollectionEntries>::emplace(simdb::argos::CompressedCollectionEntries&&):
✓ Branch 4 → 5 taken 3005 times.
simdb::ConcurrentQueue<std::shared_ptr<simdb::pipeline::AsyncDatabaseTask> >::emplace(std::shared_ptr<simdb::pipeline::AsyncDatabaseTask>&&):
✓ Branch 4 → 5 taken 4 times.
simdb::ConcurrentQueue<std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> > >::emplace(std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> >&&):
✓ Branch 4 → 5 taken 3005 times.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::emplace(std::vector<DummyData, std::allocator<DummyData> >&&):
✓ Branch 4 → 5 taken 1000 times.
simdb::ConcurrentQueue<std::vector<char, std::allocator<char> > >::emplace(std::vector<char, std::allocator<char> >&&):
✓ Branch 4 → 5 taken 22683 times.
44702 queue_.emplace_back(std::move(item));
39 44702 }
40
41 /// \brief Construct an item on the back of the queue.
42 ///
43 /// \param args Forwarding arguments for the <T> constructor.
44 template <typename... Args> void emplace(Args&&... args)
45 {
46 std::lock_guard<std::mutex> guard(mutex_);
47 queue_.emplace_back(std::forward<Args>(args)...);
48 }
49
50 /// \brief Get the item at the front of the queue.
51 ///
52 /// \param item Output argument for the popped item.
53 ///
54 /// \return Returns true if successful, or false if there
55 /// was no data in the queue.
56 105657 bool try_pop(T& item)
57 {
58
10/10
simdb::ConcurrentQueue<DummyDataWindowBytes>::try_pop(DummyDataWindowBytes&):
✓ Branch 2 → 3 taken 9027 times.
simdb::ConcurrentQueue<DummyData>::try_pop(DummyData&):
✓ Branch 2 → 3 taken 17941 times.
simdb::ConcurrentQueue<simdb::argos::NotifEntry>::try_pop(simdb::argos::NotifEntry&):
✓ Branch 2 → 3 taken 3362 times.
simdb::ConcurrentQueue<simdb::argos::CollectionEntries>::try_pop(simdb::argos::CollectionEntries&):
✓ Branch 2 → 3 taken 3072 times.
simdb::ConcurrentQueue<simdb::argos::CompressedCollectionEntries>::try_pop(simdb::argos::CompressedCollectionEntries&):
✓ Branch 2 → 3 taken 3356 times.
simdb::ConcurrentQueue<std::shared_ptr<simdb::pipeline::AsyncDatabaseTask> >::try_pop(std::shared_ptr<simdb::pipeline::AsyncDatabaseTask>&):
✓ Branch 2 → 3 taken 17 times.
simdb::ConcurrentQueue<std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> > >::try_pop(std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> >&):
✓ Branch 2 → 3 taken 3032 times.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::try_pop(std::vector<DummyData, std::allocator<DummyData> >&):
✓ Branch 2 → 3 taken 5033 times.
simdb::ConcurrentQueue<std::vector<char, std::allocator<char> > >::try_pop(std::vector<char, std::allocator<char> >&):
✓ Branch 2 → 3 taken 38024 times.
simdb::ConcurrentQueue<std::vector<double, std::allocator<double> > >::try_pop(std::vector<double, std::allocator<double> >&):
✓ Branch 2 → 3 taken 22793 times.
105657 std::lock_guard<std::mutex> guard(mutex_);
59
20/20
simdb::ConcurrentQueue<DummyDataWindowBytes>::try_pop(DummyDataWindowBytes&):
✓ Branch 4 → 5 taken 7027 times.
✓ Branch 4 → 6 taken 2000 times.
simdb::ConcurrentQueue<DummyData>::try_pop(DummyData&):
✓ Branch 4 → 5 taken 7942 times.
✓ Branch 4 → 6 taken 9999 times.
simdb::ConcurrentQueue<simdb::argos::NotifEntry>::try_pop(simdb::argos::NotifEntry&):
✓ Branch 4 → 5 taken 3361 times.
✓ Branch 4 → 6 taken 1 time.
simdb::ConcurrentQueue<simdb::argos::CollectionEntries>::try_pop(simdb::argos::CollectionEntries&):
✓ Branch 4 → 5 taken 67 times.
✓ Branch 4 → 6 taken 3005 times.
simdb::ConcurrentQueue<simdb::argos::CompressedCollectionEntries>::try_pop(simdb::argos::CompressedCollectionEntries&):
✓ Branch 4 → 5 taken 351 times.
✓ Branch 4 → 6 taken 3005 times.
simdb::ConcurrentQueue<std::shared_ptr<simdb::pipeline::AsyncDatabaseTask> >::try_pop(std::shared_ptr<simdb::pipeline::AsyncDatabaseTask>&):
✓ Branch 4 → 5 taken 13 times.
✓ Branch 4 → 6 taken 4 times.
simdb::ConcurrentQueue<std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> > >::try_pop(std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> >&):
✓ Branch 4 → 5 taken 27 times.
✓ Branch 4 → 6 taken 3005 times.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::try_pop(std::vector<DummyData, std::allocator<DummyData> >&):
✓ Branch 4 → 5 taken 4033 times.
✓ Branch 4 → 6 taken 1000 times.
simdb::ConcurrentQueue<std::vector<char, std::allocator<char> > >::try_pop(std::vector<char, std::allocator<char> >&):
✓ Branch 4 → 5 taken 15341 times.
✓ Branch 4 → 6 taken 22683 times.
simdb::ConcurrentQueue<std::vector<double, std::allocator<double> > >::try_pop(std::vector<double, std::allocator<double> >&):
✓ Branch 4 → 5 taken 110 times.
✓ Branch 4 → 6 taken 22683 times.
105657 if (queue_.empty())
60 {
61 38272 return false;
62 }
63 67385 std::swap(item, queue_.front());
64 67385 queue_.pop_front();
65 67385 return true;
66 105657 }
67
68 /// \brief Get the number of items in this queue.
69 53 size_t size() const
70 {
71
11/11
simdb::ConcurrentQueue<DummyDataWindowBytes>::size() const:
✓ Branch 2 → 3 taken 2 times.
simdb::ConcurrentQueue<DummyData>::size() const:
✓ Branch 2 → 3 taken 1 time.
simdb::ConcurrentQueue<simdb::argos::NotifEntry>::size() const:
✓ Branch 2 → 3 taken 11 times.
simdb::ConcurrentQueue<simdb::argos::CollectionEntries>::size() const:
✓ Branch 2 → 3 taken 5 times.
simdb::ConcurrentQueue<simdb::argos::CompressedCollectionEntries>::size() const:
✓ Branch 2 → 3 taken 5 times.
simdb::ConcurrentQueue<std::shared_ptr<simdb::pipeline::AsyncDatabaseTask> >::size() const:
✓ Branch 2 → 3 taken 9 times.
simdb::ConcurrentQueue<std::unique_ptr<simdb::argos::Ledger, std::default_delete<simdb::argos::Ledger> > >::size() const:
✓ Branch 2 → 3 taken 5 times.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::size() const:
✓ Branch 2 → 3 taken 1 time.
simdb::ConcurrentQueue<std::vector<char, std::allocator<char> > >::size() const:
✓ Branch 2 → 3 taken 6 times.
simdb::ConcurrentQueue<std::vector<double, std::allocator<double> > >::size() const:
✓ Branch 2 → 3 taken 6 times.
simdb::ConcurrentQueue<int>::size() const:
✓ Branch 2 → 3 taken 2 times.
53 std::lock_guard<std::mutex> guard(mutex_);
72 106 return queue_.size();
73 53 }
74
75 /// \brief Check for empty
76 42869 bool empty() const
77 {
78
1/1
✓ Branch 2 → 3 taken 42869 times.
42869 std::lock_guard<std::mutex> guard(mutex_);
79 85738 return queue_.empty();
80 42869 }
81
82 /// \brief Invoke a callback function to peek into this queue's
83 /// items. This will be invoked until the callback returns TRUE
84 /// or until we have iterated over all queue items.
85 39292 bool snoop(const std::function<bool(const T& queue_item)>& cb) const
86 {
87
3/3
simdb::ConcurrentQueue<DummyDataWindowBytes>::snoop(std::function<bool (DummyDataWindowBytes const&)> const&) const:
✓ Branch 2 → 3 taken 19393 times.
simdb::ConcurrentQueue<DummyData>::snoop(std::function<bool (DummyData const&)> const&) const:
✓ Branch 2 → 3 taken 9999 times.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::snoop(std::function<bool (std::vector<DummyData, std::allocator<DummyData> > const&)> const&) const:
✓ Branch 2 → 3 taken 9900 times.
39292 std::lock_guard<std::mutex> guard(mutex_);
88
6/6
simdb::ConcurrentQueue<DummyDataWindowBytes>::snoop(std::function<bool (DummyDataWindowBytes const&)> const&) const:
✓ Branch 11 → 5 taken 67812 times.
✓ Branch 11 → 12 taken 17841 times.
simdb::ConcurrentQueue<DummyData>::snoop(std::function<bool (DummyData const&)> const&) const:
✓ Branch 11 → 5 taken 2238 times.
✓ Branch 11 → 12 taken 9970 times.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::snoop(std::function<bool (std::vector<DummyData, std::allocator<DummyData> > const&)> const&) const:
✓ Branch 11 → 5 taken 2542 times.
✓ Branch 11 → 12 taken 9719 times.
110122 for (const auto& item : queue_)
89 {
90
9/9
simdb::ConcurrentQueue<DummyDataWindowBytes>::snoop(std::function<bool (DummyDataWindowBytes const&)> const&) const:
✓ Branch 6 → 7 taken 67812 times.
✓ Branch 7 → 8 taken 1552 times.
✓ Branch 7 → 9 taken 66260 times.
simdb::ConcurrentQueue<DummyData>::snoop(std::function<bool (DummyData const&)> const&) const:
✓ Branch 6 → 7 taken 2238 times.
✓ Branch 7 → 8 taken 29 times.
✓ Branch 7 → 9 taken 2209 times.
simdb::ConcurrentQueue<std::vector<DummyData, std::allocator<DummyData> > >::snoop(std::function<bool (std::vector<DummyData, std::allocator<DummyData> > const&)> const&) const:
✓ Branch 6 → 7 taken 2542 times.
✓ Branch 7 → 8 taken 181 times.
✓ Branch 7 → 9 taken 2361 times.
72592 if (cb(item))
91 {
92 1762 return true;
93 }
94 }
95 37530 return false;
96 39292 }
97
98 private:
99 /// Mutex for thread safety.
100 mutable std::mutex mutex_;
101
102 /// FIFO queue to hold the data. A deque is used to support snooping.
103 std::deque<T> queue_;
104 };
105
106 } // namespace simdb
107