diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ee22cc4dc..f712ae4f4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### NEXT - Node: Update TypeScript to v6 ([PR #1790](https://github.com/versatica/mediasoup/pull/1790)). +- Worker: `SeqManager`, use `std::vector` rather than `std::set` ([1807](https://github.com/versatica/mediasoup/pull/1807)). ### 3.19.22 diff --git a/worker/include/RTC/SeqManager.hpp b/worker/include/RTC/SeqManager.hpp index f15d4a5949..084ef79761 100644 --- a/worker/include/RTC/SeqManager.hpp +++ b/worker/include/RTC/SeqManager.hpp @@ -3,7 +3,7 @@ #include "common.hpp" #include // std::numeric_limits -#include +#include namespace RTC { @@ -53,7 +53,7 @@ namespace RTC T maxInput{ 0 }; T maxDropped{ 0 }; T maxForwarded{ 0 }; - std::set dropped; + std::vector dropped; }; } // namespace RTC diff --git a/worker/src/RTC/SeqManager.cpp b/worker/src/RTC/SeqManager.cpp index 75591a9bb6..41d98fdbb7 100644 --- a/worker/src/RTC/SeqManager.cpp +++ b/worker/src/RTC/SeqManager.cpp @@ -63,9 +63,15 @@ namespace RTC { this->maxInput = input; this->maxDropped = input; - // Insert input in the last position. - // Explicitly insert at the end, which is more performant. - this->dropped.insert(this->dropped.end(), input); + // Insert input in sorted order, if not present. + const SeqLowerThan seqLowerThan; + const auto it = + std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + + if (it == this->dropped.end() || *it != input) + { + this->dropped.insert(it, input); + } ClearDropped(); } @@ -74,7 +80,15 @@ namespace RTC // Allows for properly accounting for out of order drops until an input is forwarded. else if (this->maxInput == this->maxDropped && SeqManager::IsSeqHigherThan(input, this->maxForwarded)) { - this->dropped.insert(input); + // Insert input in sorted order, if not present. + const SeqLowerThan seqLowerThan; + const auto it = + std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + + if (it == this->dropped.end() || *it != input) + { + this->dropped.insert(it, input); + } ClearDropped(); } @@ -112,22 +126,24 @@ namespace RTC { goto done; } - // This input was dropped. - else if (this->dropped.find(input) != this->dropped.end()) - { - MS_DEBUG_DEV("trying to send a dropped input"); - - return false; - } - // There are dropped inputs, calculate 'base' for this input. else { - auto droppedCount = this->dropped.size(); + const SeqLowerThan seqLowerThan; + const auto it = + std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); - // Get the first dropped input which is higher than or equal 'input'. - auto it = this->dropped.lower_bound(input); + if (it != this->dropped.end() && !seqLowerThan(input, *it) && !seqLowerThan(*it, input)) + { + MS_DEBUG_DEV("trying to send a dropped input"); + + return false; + } + + // There are dropped inputs, calculate 'base' for this input. + auto droppedCount = std::distance( + this->dropped.begin(), + std::lower_bound(this->dropped.begin(), this->dropped.end(), input, SeqLowerThan())); - droppedCount -= std::distance(it, this->dropped.end()); base = (this->base - droppedCount) & SeqManager::MaxValue; } @@ -191,19 +207,16 @@ namespace RTC const size_t previousDroppedSize = this->dropped.size(); - for (auto it = this->dropped.begin(); it != this->dropped.end();) - { - auto value = *it; - - if (SeqManager::IsSeqHigherThan(value, this->maxInput)) - { - it = this->dropped.erase(it); - } - else - { - break; - } - } + // Cleanup dropped values. + this->dropped.erase( + this->dropped.begin(), + std::find_if( + this->dropped.begin(), + this->dropped.end(), + [this](T value) + { + return !SeqManager::IsSeqHigherThan(value, this->maxInput); + })); // Adapt base. this->base = (this->base - (previousDroppedSize - this->dropped.size())) & SeqManager::MaxValue;