proxygen
PriorityMPMCQueueTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
19 
20 using namespace folly;
21 
22 TEST(PriorityMPMCQueue, BasicOps) {
23  // With just one priority, this should behave like a normal MPMCQueue
24  PriorityMPMCQueue<size_t> queue(1, 10);
25  EXPECT_TRUE(queue.isEmpty());
26  EXPECT_EQ(1, queue.getNumPriorities());
27 
28  queue.write(9);
29  queue.write(8);
30 
31  EXPECT_FALSE(queue.isEmpty());
32  EXPECT_EQ(2, queue.size());
33  EXPECT_EQ(2, queue.sizeGuess());
34 
35  size_t item;
36  queue.read(item);
37  EXPECT_EQ(9, item);
38  EXPECT_FALSE(queue.isEmpty());
39  EXPECT_EQ(1, queue.size());
40  EXPECT_EQ(1, queue.sizeGuess());
41 
42  queue.read(item);
43  EXPECT_EQ(8, item);
44  EXPECT_TRUE(queue.isEmpty());
45  EXPECT_EQ(0, queue.size());
46  EXPECT_EQ(0, queue.sizeGuess());
47 }
48 
49 TEST(PriorityMPMCQueue, TestPriorities) {
50  PriorityMPMCQueue<size_t> queue(3, 10);
51  EXPECT_TRUE(queue.isEmpty());
52  EXPECT_EQ(3, queue.getNumPriorities());
53 
54  // This should go to the lowpri queue, as we only
55  // have 3 priorities
56  queue.writeWithPriority(5, 50);
57  // unqualified writes should be mid-pri
58  queue.write(3);
59  queue.writeWithPriority(6, 2);
60  queue.writeWithPriority(1, 0);
61  queue.write(4);
62  queue.writeWithPriority(2, 0);
63 
64  EXPECT_FALSE(queue.isEmpty());
65  EXPECT_EQ(6, queue.size());
66  EXPECT_EQ(6, queue.sizeGuess());
67 
68  size_t item;
69  for (int i = 1; i <= 6; i++) {
70  queue.read(item);
71  EXPECT_EQ(i, item);
72  EXPECT_EQ(6 - i, queue.size());
73  EXPECT_EQ(6 - i, queue.sizeGuess());
74  }
75 }
76 
77 TEST(PriorityMPMCQueue, TestReadWithPriority) {
78  PriorityMPMCQueue<size_t> queue(3, 10);
79  EXPECT_TRUE(queue.isEmpty());
80  EXPECT_EQ(3, queue.getNumPriorities());
81 
82  queue.writeWithPriority(2, 2);
83  queue.writeWithPriority(1, 1);
84  queue.writeWithPriority(0, 0);
85 
86  EXPECT_FALSE(queue.isEmpty());
87  EXPECT_EQ(3, queue.size());
88  EXPECT_EQ(3, queue.sizeGuess());
89 
90  size_t item;
91  for (int i = 0; i < 3; i++) {
92  EXPECT_TRUE(queue.readWithPriority(item, i));
93  EXPECT_EQ(i, item);
94  EXPECT_FALSE(queue.readWithPriority(item, i));
95  }
96 }
97 
98 TEST(PriorityMPMCQueue, TestWriteWithPriorityAndTimeout) {
99  PriorityMPMCQueue<size_t> queue(5, 1);
100  EXPECT_TRUE(queue.isEmpty());
101  EXPECT_EQ(5, queue.getNumPriorities());
102 
103  const auto timeout = std::chrono::milliseconds{30};
104  for (int i = 0; i < 5; i++) {
105  auto time_before = std::chrono::steady_clock::now();
106  EXPECT_TRUE(queue.writeWithPriority(i, i, timeout));
107  auto time_after = std::chrono::steady_clock::now();
108  EXPECT_LE(time_after - time_before, timeout);
109  }
110 
111  // check writeWithPriority will wait for at least timeout if the queue is
112  // full.
113  auto time_before = std::chrono::steady_clock::now();
114  EXPECT_FALSE(queue.writeWithPriority(5, 0, timeout));
115  auto time_after = std::chrono::steady_clock::now();
116  EXPECT_GE(time_after - time_before, timeout);
117 
118  EXPECT_FALSE(queue.isEmpty());
119  EXPECT_EQ(5, queue.size());
120  EXPECT_EQ(5, queue.sizeGuess());
121 
122  size_t item;
123  for (int i = 0; i < 5; i++) {
124  queue.read(item);
125  EXPECT_EQ(i, item);
126  EXPECT_EQ(4 - i, queue.size());
127  EXPECT_EQ(4 - i, queue.sizeGuess());
128  }
129 }
#define EXPECT_LE(val1, val2)
Definition: gtest.h:1928
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::chrono::steady_clock::time_point now()
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
#define EXPECT_GE(val1, val2)
Definition: gtest.h:1932
bool writeWithPriority(T &&item, size_t priority)
bool readWithPriority(T &item, size_t priority)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
bool isEmpty() const
Returns true if there are no items available for dequeue.
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST(SequencedExecutor, CPUThreadPoolExecutor)