2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <gtest/gtest.h>
32 #include <cds/container/fcqueue.h>
40 template<int DefaultSize = 10000>
42 static std::vector<int> pop_buff;
46 explicit HeavyValue(int new_value = 0, size_t new_bufer_size = DefaultSize)
48 buffer_size(new_bufer_size)
51 if( buffer_size != pop_buff.size() ){
52 pop_buff.resize(buffer_size);
55 HeavyValue(const HeavyValue &other)
57 buffer_size(other.buffer_size)
61 void operator=(const int& new_value)
65 bool operator==(const int new_value) const
67 return value == new_value;
69 void working(const HeavyValue &other) {
70 for (size_t i = 0; i < buffer_size; ++i)
71 pop_buff[i] = static_cast<int>(std::sqrt(other.pop_buff[i]));
75 template<int DefaultSize>
76 std::vector<int> HeavyValue< DefaultSize >::pop_buff = {};
78 class FCQueue: public ::testing::Test
81 template <class Queue>
84 typedef typename Queue::value_type value_type;
87 const size_t nSize = 100;
89 ASSERT_TRUE( q.empty());
90 ASSERT_EQ( q.size(), 0u );
93 for ( size_t i = 0; i < nSize; ++i ) {
94 ASSERT_TRUE( q.enqueue( static_cast<value_type>(i)));
95 ASSERT_EQ( q.size(), i + 1 );
97 ASSERT_FALSE( q.empty());
98 ASSERT_EQ( q.size(), nSize );
100 for ( size_t i = 0; i < nSize; ++i ) {
102 ASSERT_TRUE( q.dequeue( it ));
103 ASSERT_EQ( it, static_cast<value_type>( i ));
104 ASSERT_EQ( q.size(), nSize - i - 1 );
106 ASSERT_TRUE( q.empty());
107 ASSERT_EQ( q.size(), 0u );
110 for ( size_t i = 0; i < nSize; ++i ) {
111 ASSERT_TRUE( q.push( static_cast<value_type>(i)));
112 ASSERT_EQ( q.size(), i + 1 );
114 ASSERT_FALSE( q.empty());
115 ASSERT_EQ( q.size(), nSize );
117 for ( size_t i = 0; i < nSize; ++i ) {
119 ASSERT_TRUE( q.pop( it ));
120 ASSERT_EQ( it, static_cast<value_type>( i ));
121 ASSERT_EQ( q.size(), nSize - i - 1 );
123 ASSERT_TRUE( q.empty());
124 ASSERT_EQ( q.size(), 0u );
127 for ( size_t i = 0; i < nSize; ++i ) {
128 ASSERT_TRUE( q.push( static_cast<value_type>( i )));
130 ASSERT_FALSE( q.empty());
131 ASSERT_EQ( q.size(), nSize );
134 ASSERT_TRUE( q.empty());
135 ASSERT_EQ( q.size(), 0u );
137 // pop from empty queue
139 ASSERT_FALSE( q.pop( it ));
140 ASSERT_EQ( it, static_cast<value_type>( nSize * 2 ));
141 ASSERT_TRUE( q.empty());
142 ASSERT_EQ( q.size(), 0u );
144 ASSERT_FALSE( q.dequeue( it ));
145 ASSERT_EQ( it, static_cast<value_type>( nSize * 2 ));
146 ASSERT_TRUE( q.empty());
147 ASSERT_EQ( q.size(), 0u );
150 template <class Queue>
151 void test_string( Queue& q )
157 const size_t nSize = sizeof( str ) / sizeof( str[0] );
160 for ( size_t i = 0; i < nSize; ++i ) {
161 std::string s = str[i];
162 ASSERT_FALSE( s.empty());
163 ASSERT_TRUE( q.enqueue( std::move( s )));
164 ASSERT_FALSE( s.empty());
165 ASSERT_EQ( q.size(), i + 1 );
167 ASSERT_FALSE( q.empty());
168 ASSERT_EQ( q.size(), nSize );
170 for ( size_t i = 0; i < nSize; ++i ) {
172 ASSERT_TRUE( q.pop( s ));
173 ASSERT_EQ( q.size(), nSize - i - 1 );
174 ASSERT_EQ( s, str[i] );
176 ASSERT_TRUE( q.empty());
177 ASSERT_EQ( q.size(), 0u );
181 TEST_F( FCQueue, std_deque )
183 typedef cds::container::FCQueue<int> queue_type;
189 TEST_F( FCQueue, std_deque_move )
191 typedef cds::container::FCQueue<std::string> queue_type;
197 TEST_F( FCQueue, std_empty_wait_strategy )
199 typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
200 cds::container::fcqueue::make_traits<
201 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::empty >
209 TEST_F( FCQueue, std_deque_heavy_value )
211 typedef HeavyValue<> ValueType;
212 typedef cds::container::FCQueue<ValueType> queue_type;
218 TEST_F( FCQueue, std_empty_wait_strategy_heavy_value )
220 typedef HeavyValue<> ValueType;
221 typedef cds::container::FCQueue<ValueType, std::queue< ValueType, std::deque<ValueType>>,
222 cds::container::fcqueue::make_traits<
223 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::empty >
231 TEST_F( FCQueue, std_single_mutex_single_condvar_heavy_value )
233 typedef HeavyValue<> ValueType;
234 typedef cds::container::FCQueue<ValueType, std::queue< ValueType, std::deque<ValueType>>,
235 cds::container::fcqueue::make_traits<
236 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<> >
244 TEST_F( FCQueue, std_single_mutex_multi_condvar_heavy_value )
246 typedef HeavyValue<> ValueType;
247 typedef cds::container::FCQueue<ValueType, std::queue< ValueType, std::deque<ValueType>>,
248 cds::container::fcqueue::make_traits<
249 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<> >
257 TEST_F( FCQueue, std_multi_mutex_multi_condvar_heavy_value )
259 typedef HeavyValue<> ValueType;
260 typedef cds::container::FCQueue<ValueType, std::queue< ValueType, std::deque<ValueType>>,
261 cds::container::fcqueue::make_traits<
262 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<> >
270 TEST_F( FCQueue, std_single_mutex_single_condvar )
272 typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
273 cds::container::fcqueue::make_traits<
274 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<>>
282 TEST_F( FCQueue, std_deque_elimination )
284 typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
285 cds::container::fcqueue::make_traits<
286 cds::opt::enable_elimination< true >
294 TEST_F( FCQueue, std_deque_elimination_single_mutex_multi_condvar )
296 typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
297 cds::container::fcqueue::make_traits<
298 cds::opt::enable_elimination< true >
299 , cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<2>>
307 TEST_F( FCQueue, std_deque_elimination_move )
309 typedef cds::container::FCQueue<std::string, std::queue< std::string, std::deque<std::string>>,
310 cds::container::fcqueue::make_traits<
311 cds::opt::enable_elimination< true >
319 TEST_F( FCQueue, std_deque_elimination_move_multi_mutex_multi_condvar )
321 typedef cds::container::FCQueue<std::string, std::queue< std::string, std::deque<std::string>>,
322 cds::container::fcqueue::make_traits<
323 cds::opt::enable_elimination< true >
324 , cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<>>
332 TEST_F( FCQueue, std_deque_mutex )
334 typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
335 cds::container::fcqueue::make_traits<
336 cds::opt::lock_type< std::mutex >
344 TEST_F( FCQueue, std_list )
346 typedef cds::container::FCQueue<int, std::queue< int, std::list<int>>> queue_type;
352 TEST_F( FCQueue, std_list_move )
354 typedef cds::container::FCQueue<std::string, std::queue< std::string, std::list<std::string>>> queue_type;
360 TEST_F( FCQueue, std_list_empty_wait_strategy )
362 typedef cds::container::FCQueue<int, std::queue< int, std::list<int> >,
363 cds::container::fcqueue::make_traits<
364 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::empty >
372 TEST_F( FCQueue, std_list_single_mutex_single_condvar )
374 typedef cds::container::FCQueue<int, std::queue< int, std::list<int> >,
375 cds::container::fcqueue::make_traits<
376 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<5>>
384 TEST_F( FCQueue, std_list_elimination )
386 typedef cds::container::FCQueue<int, std::queue< int, std::list<int> >,
387 cds::container::fcqueue::make_traits<
388 cds::opt::enable_elimination< true >
396 TEST_F( FCQueue, std_list_elimination_multi_mutex_multi_condvar )
398 typedef cds::container::FCQueue<int, std::queue< int, std::list<int> >,
399 cds::container::fcqueue::make_traits<
400 cds::opt::enable_elimination< true >
401 ,cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<5>>
409 TEST_F( FCQueue, std_list_elimination_move )
411 typedef cds::container::FCQueue<std::string, std::queue< std::string, std::list<std::string> >,
412 cds::container::fcqueue::make_traits<
413 cds::opt::enable_elimination< true >
421 TEST_F( FCQueue, std_list_mutex )
423 typedef cds::container::FCQueue<int, std::queue<int, std::list<int> >,
424 cds::container::fcqueue::make_traits<
425 cds::opt::lock_type< std::mutex >