使用LRU算法进行控制QHash容器的内容数量。

#ifndef QHASHLRUCACHE_H
#define QHASHLRUCACHE_H

#include <QHash>
#include <QList>

namespace MY_NAMESPACE {
    template <typename Key, typename T>
    class QHashLRUCache {
      public:
        QHashLRUCache(qsizetype maxCost = 100, qsizetype delSize = 1) : m_maxCost(maxCost), m_delSize(delSize) {
            Q_ASSERT_X(m_maxCost > 0, "QHashLRUCache:Constructor", "capacity mush larger than 0");
            Q_ASSERT_X(m_delSize > 0, "QHashLRUCache:Constructor", "delSize mush larger than 0");
            Q_ASSERT_X(m_delSize <= m_maxCost, "QHashLRUCache:Constructor", "delSize mush less than capacity");
        }
        ~QHashLRUCache() { clear(); }

        inline typename QHash<Key, T>::iterator begin() {
            auto it = m_hash.begin();
            if (it == m_hash.end()) {
                return it;
            }

            auto key = it.key();
            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline typename QHash<Key, T>::const_iterator begin() const {
            auto it = m_hash.begin();
            if (it == m_hash.end()) {
                return it;
            }

            auto key = it.key();
            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline qsizetype capacity() const { return m_hash.capacity(); }

        inline typename QHash<Key, T>::const_iterator cbegin() const {
            auto it = m_hash.cbegin();
            if (it == m_hash.cend()) {
                return it;
            }

            auto key = it.key();
            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline typename QHash<Key, T>::const_iterator cend() const { return m_hash.cend(); }
        inline void clear() {
            m_lruList.clear();
            m_hash.clear();
        }
        inline typename QHash<Key, T>::const_iterator constBegin() const {
            auto it = m_hash.constBegin();
            if (it == m_hash.constEnd()) {
                return it;
            }

            auto key = it.key();
            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline typename QHash<Key, T>::const_iterator constEnd() const { return m_hash.constEnd(); }
        inline typename QHash<Key, T>::const_iterator constFind(const Key& key) const {
            auto it = m_hash.constFind(key);
            if (it == m_hash.constEnd()) {
                return it;
            }

            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline typename QHash<Key, T>::const_key_value_iterator constKeyValueBegin() const {
            auto it = m_hash.constKeyValueBegin();
            if (it == m_hash.constKeyValueEnd()) {
                return it;
            }

            auto key = it->first;
            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline typename QHash<Key, T>::const_key_value_iterator constKeyValueEnd() const {
            return m_hash.constKeyValueEnd();
        }
        inline bool contains(const Key& key) const { return m_hash.contains(key); }
        inline qsizetype count(const Key& key) const { return m_hash.count(key); }
        inline qsizetype count() const { return m_hash.count(); }
        template <typename... Args>
        inline typename QHash<Key, T>::iterator emplace(const Key& key, Args&&... args) {
            return m_hash.emplace(key, args...);
        }
        template <typename... Args>
        inline typename QHash<Key, T>::iterator emplace(Key&& key, Args&&... args) {
            return m_hash.emplace(key, args...);
        }
        inline bool empty() const { return m_hash.empty(); }
        inline typename QHash<Key, T>::iterator end() { return m_hash.end(); }
        inline typename QHash<Key, T>::const_iterator end() const { return m_hash.end(); }
        inline typename QHash<Key, T>::iterator erase(typename QHash<Key, T>::const_iterator pos) {
            Q_ASSERT(pos != constEnd());
            auto key = pos.key();
            m_lruList.removeAll(key);

            return m_hash.erase(pos);
        }
        inline typename QHash<Key, T>::iterator find(const Key& key) {
            auto it = m_hash.find(key);
            if (it == m_hash.end()) {
                return it;
            }

            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline typename QHash<Key, T>::const_iterator find(const Key& key) const {
            auto it = m_hash.find(key);
            if (it == m_hash.end()) {
                return it;
            }

            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline typename QHash<Key, T>::iterator insert(const Key& key, const T& value) {
            if (m_hash.contains(key)) {
                m_lruList.removeAll(key);
            } else {
                if (m_hash.size() >= m_maxCost) {
                    for (int i = 0; i < m_delSize; ++i) {
                        m_hash.remove(m_lruList.at(i));
                    }
                    m_lruList.remove(0, m_delSize);
                }
            }
            m_lruList.append(key);
            return m_hash.insert(key, value);
        }

        inline bool isEmpty() const { return m_hash.isEmpty(); }
        inline Key key(const T& value, const Key& defaultKey = Key()) const {
            auto key = m_hash.key(value, defaultKey);

            if (m_hash.contains(key)) {
                m_lruList.removeAll(key);
                m_lruList.append(key);
            }

            return key;
        }
        inline typename QHash<Key, T>::key_iterator keyBegin() const {
            auto it = m_hash.keyBegin();
            if (it == m_hash.keyEnd()) {
                return it;
            }

            auto key = *it;
            m_lruList.removeAll(key);
            m_lruList.append(key);

            return it;
        }
        inline typename QHash<Key, T>::key_iterator keyEnd() const { return m_hash.keyEnd(); }
        inline typename QHash<Key, T>::key_value_iterator keyValueBegin() {
            auto it = m_hash.keyValueBegin();
            if (it == m_hash.keyValueEnd()) {
                return it;
            }

            auto key = it->first;
            m_lruList.removeAll(key);
            m_lruList.append(key);
            return it;
        }
        inline typename QHash<Key, T>::const_key_value_iterator keyValueBegin() const {
            auto it = m_hash.keyValueBegin();
            if (it == m_hash.keyValueEnd()) {
                return it;
            }

            auto key = it->first;
            m_lruList.removeAll(key);
            m_lruList.append(key);
            return it;
        }
        inline typename QHash<Key, T>::key_value_iterator keyValueEnd() { return m_hash.keyValueEnd(); }
        inline typename QHash<Key, T>::const_key_value_iterator keyValueEnd() const { return m_hash.keyValueEnd(); }
        inline QList<Key> keys() const { return m_hash.keys(); }
        inline QList<Key> keys(const T& value) const { return m_hash.keys(); }
        inline float load_factor() const { return m_hash.load_factor(); }
        inline bool remove(const Key& key) {
            auto rst = m_hash.remove(key);
            if (rst == false) {
                return rst;
            }

            m_lruList.removeAll(key);
            return rst;
        }
        inline void reserve(qsizetype size) { m_hash.reserve(size); }
        inline qsizetype size() const { return m_hash.size(); }
        inline void squeeze() { return m_hash.squeeze(); }
        inline T take(const Key& key) {
            if (m_hash.contains(key)) {
                m_lruList.removeAll(key);
            }
            return m_hash.take(key);
        }
        inline T value(const Key& key, const T& defaultValue = T()) const {
            if (m_hash.contains(key)) {
                m_lruList.removeAll(key);
                m_lruList.append(key);
            }

            return m_hash.value(key, defaultValue);
        }
        inline QList<T> values() const { return m_hash.values(); }
        inline bool operator!=(const QHash<Key, T>& other) const { return m_hash != other; }
        inline bool operator==(const QHash<Key, T>& other) const { return m_hash == other; }
        inline T& operator[](const Key& key) {
            if (m_hash.contains(key)) {
                m_lruList.removeAll(key);
            } else {
                if (m_hash.size() >= m_maxCost) {
                    for (int i = 0; i < m_delSize; ++i) {
                        m_hash.remove(m_lruList.at(i));
                    }
                    m_lruList.remove(0, m_delSize);
                }
            }
            m_lruList.append(key);

            return m_hash[key];
        }
        inline const T operator[](const Key& key) const {
            if (m_hash.contains(key)) {
                m_lruList.removeAll(key);
                m_lruList.append(key);
            }

            return m_hash[key];
        }

      private:
        QHash<Key, T> m_hash;
        mutable QList<Key> m_lruList;
        int m_maxCost;
        int m_delSize;
    };

}  // namespace MY_NAMESPACE

#endif  // QHASHLRUCACHE_H

点墨
26 声望3 粉丝

全栈前端开发工程师