mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
added limit to cached username colors (#2515)
This commit is contained in:
parent
1090524dec
commit
8a4ffc5f5b
|
@ -95,6 +95,7 @@ include(lib/wintoast.pri)
|
||||||
include(lib/signals.pri)
|
include(lib/signals.pri)
|
||||||
include(lib/settings.pri)
|
include(lib/settings.pri)
|
||||||
include(lib/serialize.pri)
|
include(lib/serialize.pri)
|
||||||
|
include(lib/lrucache.pri)
|
||||||
include(lib/winsdk.pri)
|
include(lib/winsdk.pri)
|
||||||
include(lib/rapidjson.pri)
|
include(lib/rapidjson.pri)
|
||||||
include(lib/qtkeychain.pri)
|
include(lib/qtkeychain.pri)
|
||||||
|
|
1
lib/lrucache.pri
Normal file
1
lib/lrucache.pri
Normal file
|
@ -0,0 +1 @@
|
||||||
|
INCLUDEPATH += $$PWD/lrucache/
|
27
lib/lrucache/LICENSE
Normal file
27
lib/lrucache/LICENSE
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2014, lamerman
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of lamerman nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
72
lib/lrucache/lrucache/lrucache.hpp
Normal file
72
lib/lrucache/lrucache/lrucache.hpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* File: lrucache.hpp
|
||||||
|
* Author: Alexander Ponomarev
|
||||||
|
*
|
||||||
|
* Created on June 20, 2013, 5:09 PM
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LRUCACHE_HPP_INCLUDED_
|
||||||
|
#define _LRUCACHE_HPP_INCLUDED_
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <list>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace cache {
|
||||||
|
|
||||||
|
template<typename key_t, typename value_t>
|
||||||
|
class lru_cache {
|
||||||
|
public:
|
||||||
|
typedef typename std::pair<key_t, value_t> key_value_pair_t;
|
||||||
|
typedef typename std::list<key_value_pair_t>::iterator list_iterator_t;
|
||||||
|
|
||||||
|
lru_cache(size_t max_size) :
|
||||||
|
_max_size(max_size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void put(const key_t& key, const value_t& value) {
|
||||||
|
auto it = _cache_items_map.find(key);
|
||||||
|
_cache_items_list.push_front(key_value_pair_t(key, value));
|
||||||
|
if (it != _cache_items_map.end()) {
|
||||||
|
_cache_items_list.erase(it->second);
|
||||||
|
_cache_items_map.erase(it);
|
||||||
|
}
|
||||||
|
_cache_items_map[key] = _cache_items_list.begin();
|
||||||
|
|
||||||
|
if (_cache_items_map.size() > _max_size) {
|
||||||
|
auto last = _cache_items_list.end();
|
||||||
|
last--;
|
||||||
|
_cache_items_map.erase(last->first);
|
||||||
|
_cache_items_list.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const value_t& get(const key_t& key) {
|
||||||
|
auto it = _cache_items_map.find(key);
|
||||||
|
if (it == _cache_items_map.end()) {
|
||||||
|
throw std::range_error("There is no such key in cache");
|
||||||
|
} else {
|
||||||
|
_cache_items_list.splice(_cache_items_list.begin(), _cache_items_list, it->second);
|
||||||
|
return it->second->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exists(const key_t& key) const {
|
||||||
|
return _cache_items_map.find(key) != _cache_items_map.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return _cache_items_map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::list<key_value_pair_t> _cache_items_list;
|
||||||
|
std::unordered_map<key_t, list_iterator_t> _cache_items_map;
|
||||||
|
size_t _max_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cache
|
||||||
|
|
||||||
|
#endif /* _LRUCACHE_HPP_INCLUDED_ */
|
||||||
|
|
27
resources/licenses/lrucache.txt
Normal file
27
resources/licenses/lrucache.txt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2014, lamerman
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of lamerman nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -49,6 +49,7 @@
|
||||||
<file>licenses/boost_boost.txt</file>
|
<file>licenses/boost_boost.txt</file>
|
||||||
<file>licenses/emoji-data-source.txt</file>
|
<file>licenses/emoji-data-source.txt</file>
|
||||||
<file>licenses/libcommuni_BSD3.txt</file>
|
<file>licenses/libcommuni_BSD3.txt</file>
|
||||||
|
<file>licenses/lrucache.txt</file>
|
||||||
<file>licenses/openssl.txt</file>
|
<file>licenses/openssl.txt</file>
|
||||||
<file>licenses/pajlada_settings.txt</file>
|
<file>licenses/pajlada_settings.txt</file>
|
||||||
<file>licenses/pajlada_signals.txt</file>
|
<file>licenses/pajlada_signals.txt</file>
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace chatterino {
|
||||||
|
|
||||||
ChannelChatters::ChannelChatters(Channel &channel)
|
ChannelChatters::ChannelChatters(Channel &channel)
|
||||||
: channel_(channel)
|
: channel_(channel)
|
||||||
|
, chatterColors_(ChannelChatters::maxChatterColorCount)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,22 +73,23 @@ void ChannelChatters::setChatters(UsernameSet &&set)
|
||||||
|
|
||||||
const QColor ChannelChatters::getUserColor(const QString &user)
|
const QColor ChannelChatters::getUserColor(const QString &user)
|
||||||
{
|
{
|
||||||
const auto chatterColors = this->chatterColors_.accessConst();
|
const auto chatterColors = this->chatterColors_.access();
|
||||||
|
|
||||||
const auto search = chatterColors->find(user.toLower());
|
auto lowerUser = user.toLower();
|
||||||
if (search == chatterColors->end())
|
|
||||||
|
if (!chatterColors->exists(lowerUser))
|
||||||
{
|
{
|
||||||
// Returns an invalid color so we can decide not to override `textColor`
|
// Returns an invalid color so we can decide not to override `textColor`
|
||||||
return QColor();
|
return QColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
return search->second;
|
return QColor::fromRgb(chatterColors->get(lowerUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelChatters::setUserColor(const QString &user, const QColor &color)
|
void ChannelChatters::setUserColor(const QString &user, const QColor &color)
|
||||||
{
|
{
|
||||||
const auto chatterColors = this->chatterColors_.access();
|
const auto chatterColors = this->chatterColors_.access();
|
||||||
chatterColors->insert_or_assign(user.toLower(), color);
|
chatterColors->put(user.toLower(), color.rgb());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#include "common/Channel.hpp"
|
#include "common/Channel.hpp"
|
||||||
#include "common/UniqueAccess.hpp"
|
#include "common/UniqueAccess.hpp"
|
||||||
#include "common/UsernameSet.hpp"
|
#include "common/UsernameSet.hpp"
|
||||||
|
#include "util/QStringHash.hpp"
|
||||||
|
|
||||||
|
#include "lrucache/lrucache.hpp"
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
@ -22,11 +25,13 @@ public:
|
||||||
void setUserColor(const QString &user, const QColor &color);
|
void setUserColor(const QString &user, const QColor &color);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr int maxChatterColorCount = 5000;
|
||||||
|
|
||||||
Channel &channel_;
|
Channel &channel_;
|
||||||
|
|
||||||
// maps 2 char prefix to set of names
|
// maps 2 char prefix to set of names
|
||||||
UniqueAccess<UsernameSet> chatters_;
|
UniqueAccess<UsernameSet> chatters_;
|
||||||
UniqueAccess<std::map<QString, QColor>> chatterColors_;
|
UniqueAccess<cache::lru_cache<QString, QRgb>> chatterColors_;
|
||||||
|
|
||||||
// combines multiple joins/parts into one message
|
// combines multiple joins/parts into one message
|
||||||
UniqueAccess<QStringList> joinedUsers_;
|
UniqueAccess<QStringList> joinedUsers_;
|
||||||
|
|
|
@ -124,6 +124,9 @@ AboutPage::AboutPage()
|
||||||
addLicense(form.getElement(), "QtKeychain",
|
addLicense(form.getElement(), "QtKeychain",
|
||||||
"https://github.com/frankosterfeld/qtkeychain",
|
"https://github.com/frankosterfeld/qtkeychain",
|
||||||
":/licenses/qtkeychain.txt");
|
":/licenses/qtkeychain.txt");
|
||||||
|
addLicense(form.getElement(), "lrucache",
|
||||||
|
"https://github.com/lamerman/cpp-lru-cache",
|
||||||
|
":/licenses/lrucache.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto attributions = layout.emplace<QGroupBox>("Attributions...");
|
auto attributions = layout.emplace<QGroupBox>("Attributions...");
|
||||||
|
|
Loading…
Reference in a new issue