diff --git a/chatterino.pro b/chatterino.pro index 97afa8ac9..eddc634d6 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -95,6 +95,7 @@ include(lib/wintoast.pri) include(lib/signals.pri) include(lib/settings.pri) include(lib/serialize.pri) +include(lib/lrucache.pri) include(lib/winsdk.pri) include(lib/rapidjson.pri) include(lib/qtkeychain.pri) diff --git a/lib/lrucache.pri b/lib/lrucache.pri new file mode 100644 index 000000000..1d5b67628 --- /dev/null +++ b/lib/lrucache.pri @@ -0,0 +1 @@ +INCLUDEPATH += $$PWD/lrucache/ diff --git a/lib/lrucache/LICENSE b/lib/lrucache/LICENSE new file mode 100644 index 000000000..bc39bb831 --- /dev/null +++ b/lib/lrucache/LICENSE @@ -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. diff --git a/lib/lrucache/lrucache/lrucache.hpp b/lib/lrucache/lrucache/lrucache.hpp new file mode 100644 index 000000000..9e5e2850d --- /dev/null +++ b/lib/lrucache/lrucache/lrucache.hpp @@ -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 +#include +#include +#include + +namespace cache { + +template +class lru_cache { +public: + typedef typename std::pair key_value_pair_t; + typedef typename std::list::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 _cache_items_list; + std::unordered_map _cache_items_map; + size_t _max_size; +}; + +} // namespace cache + +#endif /* _LRUCACHE_HPP_INCLUDED_ */ + diff --git a/resources/licenses/lrucache.txt b/resources/licenses/lrucache.txt new file mode 100644 index 000000000..bc39bb831 --- /dev/null +++ b/resources/licenses/lrucache.txt @@ -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. diff --git a/resources/resources_autogenerated.qrc b/resources/resources_autogenerated.qrc index f219f15ba..393bea73e 100644 --- a/resources/resources_autogenerated.qrc +++ b/resources/resources_autogenerated.qrc @@ -49,6 +49,7 @@ licenses/boost_boost.txt licenses/emoji-data-source.txt licenses/libcommuni_BSD3.txt + licenses/lrucache.txt licenses/openssl.txt licenses/pajlada_settings.txt licenses/pajlada_signals.txt diff --git a/src/common/ChannelChatters.cpp b/src/common/ChannelChatters.cpp index 3657aeeec..c69144d4e 100644 --- a/src/common/ChannelChatters.cpp +++ b/src/common/ChannelChatters.cpp @@ -7,6 +7,7 @@ namespace chatterino { ChannelChatters::ChannelChatters(Channel &channel) : channel_(channel) + , chatterColors_(ChannelChatters::maxChatterColorCount) { } @@ -72,22 +73,23 @@ void ChannelChatters::setChatters(UsernameSet &&set) 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()); - if (search == chatterColors->end()) + auto lowerUser = user.toLower(); + + if (!chatterColors->exists(lowerUser)) { // Returns an invalid color so we can decide not to override `textColor` return QColor(); } - return search->second; + return QColor::fromRgb(chatterColors->get(lowerUser)); } void ChannelChatters::setUserColor(const QString &user, const QColor &color) { const auto chatterColors = this->chatterColors_.access(); - chatterColors->insert_or_assign(user.toLower(), color); + chatterColors->put(user.toLower(), color.rgb()); } } // namespace chatterino diff --git a/src/common/ChannelChatters.hpp b/src/common/ChannelChatters.hpp index a65dfe0d6..c873f8559 100644 --- a/src/common/ChannelChatters.hpp +++ b/src/common/ChannelChatters.hpp @@ -3,6 +3,9 @@ #include "common/Channel.hpp" #include "common/UniqueAccess.hpp" #include "common/UsernameSet.hpp" +#include "util/QStringHash.hpp" + +#include "lrucache/lrucache.hpp" namespace chatterino { @@ -22,11 +25,13 @@ public: void setUserColor(const QString &user, const QColor &color); private: + static constexpr int maxChatterColorCount = 5000; + Channel &channel_; // maps 2 char prefix to set of names UniqueAccess chatters_; - UniqueAccess> chatterColors_; + UniqueAccess> chatterColors_; // combines multiple joins/parts into one message UniqueAccess joinedUsers_; diff --git a/src/widgets/settingspages/AboutPage.cpp b/src/widgets/settingspages/AboutPage.cpp index 961e6f74d..33b38a5a2 100644 --- a/src/widgets/settingspages/AboutPage.cpp +++ b/src/widgets/settingspages/AboutPage.cpp @@ -124,6 +124,9 @@ AboutPage::AboutPage() addLicense(form.getElement(), "QtKeychain", "https://github.com/frankosterfeld/qtkeychain", ":/licenses/qtkeychain.txt"); + addLicense(form.getElement(), "lrucache", + "https://github.com/lamerman/cpp-lru-cache", + ":/licenses/lrucache.txt"); } auto attributions = layout.emplace("Attributions...");