17#include <QtCore/QSharedPointer>
18#include <QtCore/QDebug>
22template <
class Key,
class T>
33template <
class Key,
class T>
40template <
class Key,
class T>
74template <
class Key,
class T,
class EvPolicy = QCache3QDefaultEvictionPolicy<Key,T> >
82 inline explicit Node() :
q(0),
n(0),
p(0), pop(0), cost(0) {}
96 inline explicit Queue() :
f(0), l(0), cost(0), pop(0),
size(0) {}
113 inline ~QCache3Q() {
clear();
delete q1_;
delete q2_;
delete q3_;
delete q1_evicted_; }
115 inline int maxCost()
const {
return maxCost_; }
121 inline int totalCost()
const {
return q1_->cost + q2_->cost + q3_->cost; }
139 int maxCost_, minRecent_, maxOldPopular_;
140 int hitCount_, missCount_, promote_;
143 void unlink(
Node *
n);
144 void link_front(
Node *
n, Queue *
q);
152template <
class Key,
class T,
class EvPolicy>
155 qDebug(
"\n=== cache %p ===",
this);
156 qDebug(
"hits: %d (%.2f%%)\tmisses: %d\tfill: %.2f%%", hitCount_,
157 100.0 *
float(hitCount_) / (
float(hitCount_ + missCount_)),
159 100.0 *
float(totalCost()) /
float(maxCost()));
160 qDebug(
"q1g: size=%d, pop=%llu", q1_evicted_->size, q1_evicted_->pop);
161 qDebug(
"q1: cost=%d, size=%d, pop=%llu", q1_->cost, q1_->size, q1_->pop);
162 qDebug(
"q2: cost=%d, size=%d, pop=%llu", q2_->cost, q2_->size, q2_->pop);
163 qDebug(
"q3: cost=%d, size=%d, pop=%llu", q3_->cost, q3_->size, q3_->pop);
166template <
class Key,
class T,
class EvPolicy>
168 : q1_(new Queue), q2_(new Queue), q3_(new Queue), q1_evicted_(new Queue),
169 maxCost_(maxCost), minRecent_(minRecent), maxOldPopular_(maxOldPopular),
170 hitCount_(0), missCount_(0), promote_(0)
173 minRecent_ = maxCost_ / 3;
174 if (maxOldPopular_ < 0)
175 maxOldPopular_ = maxCost_ / 5;
178template <
class Key,
class T,
class EvPolicy>
181 Q_ASSERT(queueNumber >= 1 && queueNumber <= 4);
182 Queue *
queue = queueNumber == 1 ? q1_ :
183 queueNumber == 2 ? q2_ :
184 queueNumber == 3 ? q3_ :
186 for (Node *node =
queue->f; node; node = node->n)
190template <
class Key,
class T,
class EvPolicy>
194 Q_ASSERT(queueNumber >= 1 && queueNumber <= 4);
195 int bufferSize =
keys.size();
199 Queue *
queue = queueNumber == 1 ? q1_ :
200 queueNumber == 2 ? q2_ :
201 queueNumber == 3 ? q3_ :
203 for (
int i = 0;
i<bufferSize; ++
i) {
204 Node *node =
new Node;
207 node->cost = costs[
i];
208 link_front(node,
queue);
209 lookup_[
keys[
i]] = node;
214template <
class Key,
class T,
class EvPolicy>
218 minRecent_ = minRecent;
219 maxOldPopular_ = maxOldPopular;
221 minRecent_ = maxCost_ / 3;
222 if (maxOldPopular_ < 0)
223 maxOldPopular_ = maxCost_ / 5;
227template <
class Key,
class T,
class EvPolicy>
230 if (
cost > maxCost_) {
234 if (lookup_.contains(
key)) {
235 Node *
n = lookup_[
key];
237 n->q->cost -=
n->cost;
241 if (
n->q == q1_evicted_) {
242 if (
n->pop > (
uint)promote_) {
247 }
else if (
n->q != q1_) {
269template <
class Key,
class T,
class EvPolicy>
272 while (q1_evicted_->f) {
273 Node *
n = q1_evicted_->f;
281 EvPolicy::aboutToBeRemoved(
n->k,
n->v);
288 EvPolicy::aboutToBeRemoved(
n->k,
n->v);
295 EvPolicy::aboutToBeRemoved(
n->k,
n->v);
302template <
class Key,
class T,
class EvPolicy>
316 n->q->cost -=
n->cost;
321template <
class Key,
class T,
class EvPolicy>
338template <
class Key,
class T,
class EvPolicy>
341 while (q1_evicted_->size > (q1_->size + q2_->size + q3_->size) * 4) {
342 Node *
n = q1_evicted_->l;
344 lookup_.remove(
n->k);
348 while ((q1_->cost + q2_->cost + q3_->cost) > maxCost_) {
349 if (q3_->cost > maxOldPopular_) {
352 EvPolicy::aboutToBeEvicted(
n->k,
n->v);
353 lookup_.remove(
n->k);
355 }
else if (q1_->cost > minRecent_) {
358 EvPolicy::aboutToBeEvicted(
n->k,
n->v);
361 link_front(
n, q1_evicted_);
365 if (q2_->size &&
n->pop > (q2_->pop / q2_->size)) {
368 EvPolicy::aboutToBeEvicted(
n->k,
n->v);
371 link_front(
n, q1_evicted_);
377template <
class Key,
class T,
class EvPolicy>
380 if (!lookup_.contains(
key)) {
383 Node *
n = lookup_[
key];
385 if (
n->q != q1_evicted_ && !force)
386 EvPolicy::aboutToBeRemoved(
n->k,
n->v);
391template <
class Key,
class T,
class EvPolicy>
394 return lookup_.keys();
397template <
class Key,
class T,
class EvPolicy>
400 if (!lookup_.contains(
key)) {
407 Node *
n = me->lookup_[
key];
416 me->link_front(
n, q2_);
419 }
else if (
n->q != q1_evicted_) {
424 me->link_front(
n,
q);
433template <
class Key,
class T,
class EvPolicy>
void aboutToBeEvicted(const Key &key, QSharedPointer< T > obj)
void aboutToBeRemoved(const Key &key, QSharedPointer< T > obj)
QSharedPointer< T > operator[](const Key &key) const
QCache3Q(int maxCost=0, int minRecent=-1, int maxOldPopular=-1)
void deserializeQueue(int queueNumber, const QList< Key > &keys, const QList< QSharedPointer< T > > &values, const QList< int > &costs)
bool insert(const Key &key, QSharedPointer< T > object, int cost=1)
void remove(const Key &key, bool force=false)
QSharedPointer< T > object(const Key &key) const
void setMaxCost(int maxCost, int minRecent=-1, int maxOldPopular=-1)
QList< Key > keys() const
void serializeQueue(int queueNumber, QList< QSharedPointer< T > > &buffer)
Combined button and popup list for selecting options.
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble q
static qsizetype cost(const QPixmap &pixmap)
unsigned long long quint64