00001 #ifndef GCACHE_PROVIDER_H 00002 #define GCACHE_PROVIDER_H 00003 00004 #include <wrap/system/multithreading/mt.h> 00005 #include "dheap.h" 00006 #include "door.h" 00007 00008 #include "token.h" 00009 00010 /* this cache system enforce the rule that the items in a cache are always in all the cache below */ 00011 /* two mechanism to remove tokens from the cache: 00012 1) set token count to something low 00013 2) set maximum number of tokens in the provider 00014 */ 00015 00020 namespace vcg { 00021 00022 template <typename Token> 00023 class Provider: public mt::thread { 00024 public: 00026 PtrDHeap<Token> heap; 00028 int max_tokens; 00030 bool heap_dirty; 00032 mt::mutex heap_lock; 00034 QDoor check_queue; 00035 00036 Provider(): max_tokens(-1), heap_dirty(false) {} 00037 virtual ~Provider() {} 00038 00040 void pushPriorities() { 00041 mt::mutexlocker locker(&heap_lock); 00042 for(int i = 0; i < heap.size(); i++) 00043 heap[i].pushPriority(); 00044 00045 heap_dirty = true; 00046 check_queue.open(); 00047 } 00049 void rebuild() { 00050 if(!this->heap_dirty) return; 00051 00052 this->heap.rebuild(); 00053 this->heap_dirty = false; 00054 00055 //remove OUTSIDE tokens from bottom of heap 00056 if(max_tokens != -1) { 00057 while(this->heap.size() > max_tokens) { 00058 Token &t = this->heap.min(); 00059 t.count = Token::OUTSIDE; 00060 this->heap.popMin(); 00061 } 00062 } 00063 } 00064 00066 template <class FUNCTOR> void flush(FUNCTOR functor) { 00067 int count = 0; 00068 mt::mutexlocker locker(&(this->heap_lock)); 00069 for(int k = 0; k < this->heap.size(); k++) { 00070 Token *token = &this->heap[k]; 00071 if(functor(token)) { //drop it 00072 token->count = Token::OUTSIDE; 00073 } else 00074 this->heap.at(count++) = token; 00075 } 00076 this->heap.resize(count); 00077 this->heap_dirty = true; 00078 } 00079 }; 00080 00081 } //namespace 00082 #endif