vcglib/wrap/gcache/provider.h

81 lines
2.2 KiB
C
Raw Normal View History

2011-03-11 17:14:54 +01:00
#ifndef GCACHE_PROVIDER_H
#define GCACHE_PROVIDER_H
#include <wrap/system/multithreading/mt.h>
2011-03-11 17:14:54 +01:00
#include "dheap.h"
#include "door.h"
#include "token.h"
/* this cache system enforce the rule that the items in a cache are always in all the cache below */
/* two mechanism to remove tokens from the cache:
1) set token count to something low
2) set maximum number of tokens in the provider
*/
2011-11-26 19:08:30 +01:00
/** Base class for Cache and last cache in the GCache system.
2011-03-11 17:14:54 +01:00
You should never interact with this class.
*/
template <typename Token>
class Provider: public mt::thread {
2011-03-11 17:14:54 +01:00
public:
///holds the resources in this cache but not in the cache above
2011-11-26 19:08:30 +01:00
PtrDHeap<Token> heap;
2011-03-11 17:14:54 +01:00
///tokens above this number will be scheduled for deletion
int max_tokens;
///signals we need to rebuild heap.
2011-11-26 19:08:30 +01:00
bool heap_dirty;
///lock this before manipulating heap.
mt::mutex heap_lock;
2011-03-11 17:14:54 +01:00
///signals (to next cache!) priorities have changed or something is available
2011-11-26 19:08:30 +01:00
QDoor check_queue;
2011-03-11 17:14:54 +01:00
Provider(): max_tokens(-1), heap_dirty(false) {}
virtual ~Provider() {}
/// [should be protected, do not use] called in controller thread!
2011-03-11 17:14:54 +01:00
void pushPriorities() {
mt::mutexlocker locker(&heap_lock);
2011-03-11 17:14:54 +01:00
for(int i = 0; i < heap.size(); i++)
heap[i].pushPriority();
2011-03-11 17:14:54 +01:00
heap_dirty = true;
check_queue.open();
}
/// assumes heap lock is locked, runs in cache thread [should be protected, do not use]
void rebuild() {
if(!this->heap_dirty) return;
this->heap.rebuild();
this->heap_dirty = false;
2011-03-11 17:14:54 +01:00
//remove OUTSIDE tokens from bottom of heap
if(max_tokens != -1) {
while(this->heap.size() > max_tokens) {
Token &t = this->heap.min();
t.count = Token::OUTSIDE;
this->heap.popMin();
}
}
}
///ensure no locked item are to be removed [should be protected, do not use]
template <class FUNCTOR> void flush(FUNCTOR functor) {
int count = 0;
mt::mutexlocker locker(&(this->heap_lock));
2011-03-11 17:14:54 +01:00
for(int k = 0; k < this->heap.size(); k++) {
Token *token = &this->heap[k];
if(functor(token)) { //drop it
token->count = Token::OUTSIDE;
} else
this->heap.at(count++) = token;
}
this->heap.resize(count);
this->heap_dirty = true;
}
};
2011-11-26 19:08:30 +01:00
#endif