使用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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。