From: Hansong Zhang Date: Fri, 15 Jan 2021 05:58:27 +0000 (-0800) Subject: Introduce MultiPriorityQueue X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ec12c83bb325e44af1aafff6b2d93c55754f52f6;p=android-x86%2Fsystem-bt.git Introduce MultiPriorityQueue ACL and L2cap needs to prioritize some link/channels in some cases. A traditional priority queue requires predefined comparison, which can be hard for our use case (PacketBuilder). Instead, we specify the priority value when we push to a queue. Test: bluetooth_test_gd Tag: #gd-refactor Bug: 141555841 Change-Id: I33414b4bf81e9f63c88d8627376b565f5c5bb6de --- diff --git a/gd/common/Android.bp b/gd/common/Android.bp index 5c66da439..c17699232 100644 --- a/gd/common/Android.bp +++ b/gd/common/Android.bp @@ -17,6 +17,7 @@ filegroup { "init_flags_test.cc", "list_map_test.cc", "lru_cache_test.cc", + "multi_priority_queue_test.cc", "numbers_test.cc", "strings_test.cc", ], diff --git a/gd/common/multi_priority_queue.h b/gd/common/multi_priority_queue.h new file mode 100644 index 000000000..dd4785b75 --- /dev/null +++ b/gd/common/multi_priority_queue.h @@ -0,0 +1,69 @@ +/****************************************************************************** + * + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#pragma once + +#include +#include + +namespace bluetooth { +namespace common { + +/** + * A queue implementation which supports items with multiple priorities. + * Items with greater priority value will be dequeued first. + * When Enqueuing, the user can specify the priority (0 by default). + * This can be used by ACL or L2CAP lower queue end sender to prioritize some link or channel, used by A2DP. + */ +template +class MultiPriorityQueue { + static_assert(NUM_PRIORITY_LEVELS > 1); + + public: + // Get the front item with the highest priority. Queue must be non-empty. + T& front() { + return queues_[next_to_dequeue_.top()].front(); + } + + [[nodiscard]] bool empty() const { + return next_to_dequeue_.empty(); + } + + [[nodiscard]] size_t size() const { + return next_to_dequeue_.size(); + } + + // Push the item with specified priority + void push(const T& t, int priority = 0) { + queues_[priority].push(t); + next_to_dequeue_.push(priority); + } + + // Pop the item in the front + void pop() { + queues_[next_to_dequeue_.top()].pop(); + next_to_dequeue_.pop(); + } + + private: + std::array, NUM_PRIORITY_LEVELS> queues_; + std::priority_queue next_to_dequeue_; +}; + +} // namespace common +} // namespace bluetooth diff --git a/gd/common/multi_priority_queue_test.cc b/gd/common/multi_priority_queue_test.cc new file mode 100644 index 000000000..66775258a --- /dev/null +++ b/gd/common/multi_priority_queue_test.cc @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include + +#include "common/multi_priority_queue.h" + +namespace bluetooth { +namespace common { + +TEST(MultiPriorityQueueTest, without_high_priority_item) { + common::MultiPriorityQueue q; + EXPECT_TRUE(q.empty()); + q.push(0); + q.push(1, 0); + q.push(2); + EXPECT_EQ(q.size(), 3); + for (int i = 0; i < 3; i++) { + EXPECT_EQ(q.front(), i); + q.pop(); + } + EXPECT_TRUE(q.empty()); +} + +TEST(MultiPriorityQueueTest, with_high_priority_item) { + common::MultiPriorityQueue q; + q.push(1); + q.push(2); + q.push(0, 1); + for (int i = 0; i < 3; i++) { + EXPECT_EQ(q.front(), i); + q.pop(); + } +} + +TEST(MultiPriorityQueueTest, with_multiple_priority_item) { + common::MultiPriorityQueue q; + q.push(1, 1); + q.push(0, 2); + q.push(2, 0); + for (int i = 0; i < 3; i++) { + EXPECT_EQ(q.front(), i); + q.pop(); + } +} + +} // namespace common +} // namespace bluetooth