fix: take indices to messages as a hint (#5683)

This commit is contained in:
nerix
2024-11-02 13:11:59 +01:00
committed by GitHub
parent ecfb35c9b7
commit 5f76f5b755
7 changed files with 246 additions and 27 deletions
+66 -2
View File
@@ -8,6 +8,7 @@
#include <mutex>
#include <optional>
#include <shared_mutex>
#include <utility>
#include <vector>
namespace chatterino {
@@ -212,9 +213,10 @@ public:
*
* @param[in] index the index of the item to replace
* @param[in] replacement the item to put in place of the item at index
* @param[out] prev (optional) the item located at @a index before replacing
* @return true if a replacement took place
*/
bool replaceItem(size_t index, const T &replacement)
bool replaceItem(size_t index, const T &replacement, T *prev = nullptr)
{
std::unique_lock lock(this->mutex_);
@@ -223,10 +225,46 @@ public:
return false;
}
this->buffer_[index] = replacement;
if (prev)
{
*prev = std::exchange(this->buffer_[index], replacement);
}
else
{
this->buffer_[index] = replacement;
}
return true;
}
/**
* @brief Replace the needle with the given item
*
* @param hint A hint on where the needle _might_ be
* @param[in] needle the item to search for
* @param[in] replacement the item to replace needle with
* @return the index of the replaced item, or -1 if no replacement took place
*/
int replaceItem(size_t hint, const T &needle, const T &replacement)
{
std::unique_lock lock(this->mutex_);
if (hint < this->buffer_.size() && this->buffer_[hint] == needle)
{
this->buffer_[hint] = replacement;
return static_cast<int>(hint);
}
for (size_t i = 0; i < this->buffer_.size(); ++i)
{
if (this->buffer_[i] == needle)
{
this->buffer_[i] = replacement;
return static_cast<int>(i);
}
}
return -1;
}
/**
* @brief Inserts the given item before another item
*
@@ -315,6 +353,32 @@ public:
return std::nullopt;
}
/**
* @brief Find an item with a hint
*
* @param hint A hint on where the needle _might_ be
* @param predicate that will used to find the item
* @return the item and its index or none if it's not found
*/
std::optional<std::pair<size_t, T>> find(size_t hint, auto &&predicate)
{
std::unique_lock lock(this->mutex_);
if (hint < this->buffer_.size() && predicate(this->buffer_[hint]))
{
return std::pair{hint, this->buffer_[hint]};
};
for (size_t i = 0; i < this->buffer_.size(); i++)
{
if (predicate(this->buffer_[i]))
{
return std::pair{i, this->buffer_[i]};
}
}
return std::nullopt;
}
/**
* @brief Returns the first item matching a predicate, checking in reverse
*