static int lf_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { lru_touch(path); return 0; }
END_TEST START_TEST(touch) { lru_t *lru; lru_item_t * one; lru = lru_create(); one = lru_insert(lru, "one", 3, "one", 3, NULL); lru_insert(lru, "two", 3, "two", 3, NULL); lru_insert(lru, "three", 5, "three", 5, NULL); lru_touch(lru, one); fail_unless(one == (lru_item_t*)lru->list->head->data); lru_destroy(lru); }
struct lruhash_entry *lruhash_lookup(struct lruhash *table, hashvalue_t hash, void *key) { struct lruhash_entry *entry; struct lruhash_bucket *bucket; lock_basic_lock(&table->lock); bucket = &table->array[hash & table->size_mask]; if((entry=bucket_find_entry(table, bucket, hash, key))) { lru_touch(table, entry); lock_basic_lock(&entry->lock); } lock_basic_unlock(&table->lock); return entry; }
void lruhash_insert(struct lruhash *table, hashvalue_t hash, struct lruhash_entry *entry, void *data) { struct lruhash_bucket *bucket; struct lruhash_entry *found, *reclaimlist=NULL; size_t need_size; need_size = table->sizefunc(entry->key, data); //find bucket lock_basic_lock(&table->lock); bucket = &table->array[hash & table->size_mask]; //see if entry exists if(!(found=bucket_find_entry(table, bucket, hash, entry->key))) { //if not found: add to bucket entry->overflow_next = bucket->overflow_list; bucket->overflow_list = entry; lru_front(table, entry); table->num++; table->space_used += need_size; } else { //if found: update data table->space_used += need_size - (*table->sizefunc)(found->key, found->data); (*table->delkeyfunc)(entry->key); lru_touch(table, found); lock_basic_lock(&found->lock); (*table->deldatafunc)(found->data); found->data = data; lock_basic_unlock(&found->lock); } if(table->space_used > table->space_max) reclaim_space(table, &reclaimlist); if(table->num >= table->size) table_grow(table); lock_basic_unlock(&table->lock); //del reclaim without lock while(reclaimlist) { struct lruhash_entry *n = reclaimlist->overflow_next; void *d = reclaimlist->data; (*table->delkeyfunc)(reclaimlist->key); (*table->deldatafunc)(d); reclaimlist = n; } }
bool Cache::cacheNewImage( fim::Image* ni ) { #ifdef FIM_CACHE_DEBUG std::cout << "going to cache: "<< ni << "\n"; #endif /* acca' nun stimm'a'ppazzia' */ if(!ni)return false; this->imageCache[ni->getKey()]=ni; this->reverseCache[ni]= ni->getKey(); lru_touch( ni->getKey() ); usageCounter[ ni->getKey()]=0; // we yet don't assume any usage setGlobalVariable(FIM_VID_CACHED_IMAGES,cached_elements()); return true; }
/******************************************************************************* * font_cache_get ******************************************************************************/ struct font_cache_entry* font_cache_get( struct font_cache* fcache, unsigned short char_code, bool cache_only, void (*callback) (struct font_cache_entry* p, void *callback_data), void *callback_data) { struct font_cache_entry* p; int insertion_point; int index_to_replace; /* check bounds */ p = lru_data(&fcache->_lru, fcache->_index[0]); if( char_code < p->_char_code ) insertion_point = -1; else { p = lru_data(&fcache->_lru, fcache->_index[fcache->_capacity - 1]); if( char_code > p->_char_code ) { insertion_point = fcache->_capacity - 1; } else { if( search(fcache, char_code, fcache->_size - 1, &insertion_point)) { short lru_handle = fcache->_index[insertion_point]; p = lru_data(&fcache->_lru, lru_handle); if (p->_char_code == char_code) { lru_touch(&fcache->_lru, lru_handle); return lru_data(&fcache->_lru, lru_handle); } } else { p = lru_data(&fcache->_lru, fcache->_index[insertion_point+1]); if ( char_code > p->_char_code ) insertion_point++; } } } /* not found */ if (cache_only) return NULL; /* find index to replace */ short lru_handle_to_replace = fcache->_lru._head; p = lru_data(&fcache->_lru, lru_handle_to_replace); search(fcache, p->_char_code, fcache->_size - 1, &index_to_replace); if (insertion_point < index_to_replace) { /* shift memory up */ memmove(fcache->_index + insertion_point + 2, fcache->_index + insertion_point + 1, (index_to_replace - insertion_point - 1) * sizeof(short)); /* add to index */ fcache->_index[insertion_point + 1] = lru_handle_to_replace; } else if (insertion_point > index_to_replace) { /* shift memory down */ memmove(fcache->_index + index_to_replace, fcache->_index + index_to_replace + 1, (insertion_point - index_to_replace) * sizeof(short)); /* add to index */ fcache->_index[insertion_point] = lru_handle_to_replace; } /* load new entry into cache */ lru_touch(&fcache->_lru, lru_handle_to_replace); if (fcache->_size < fcache->_capacity) fcache->_size++; p->_char_code = char_code; /* fill bitmap */ callback(p, callback_data); return p; }
int main(int argc, char **argv) { lru_init(10); lru_touch("/some_item"); return fuse_main(argc, argv, &filesystem_operations, NULL); }
static int lf_open(const char *path, struct fuse_file_info *fi) { lru_touch(path); return 0; }
Image * Cache::useCachedImage(cache_key_t key) { /* * the calling function needs an image, so calls this method. * if we already have the desired image and it is already used, * a clone is built and returned. * * if we have an unused master, we return it. * * then declare this image as used and increase a relative counter. * * a freeImage action will do the converse operation (and delete). * if the image is not already cached, it is loaded, if possible. * * so, if there is no such image, NULL is returned * */ #ifdef FIM_CACHE_DEBUG std::cout << " useCachedImage(\""<<key.first<<","<<key.second<<"\")\n"; #endif Image * image=NULL; if(!is_in_cache(key)) { /* * no Image cached at all for this filename * */ image = loadNewImage(key); if(!image)return NULL; // bad luck! usageCounter[key]=1; setGlobalVariable(FIM_VID_CACHE_STATUS,getReport().c_str()); return image; // usageCounter[key]=0; } else { /* * at least one copy of this filename image is in cache * */ image=getCachedImage(key);// in this way we update the LRU cache :) if(!image) { // critical error #ifdef FIM_CACHE_DEBUG cout << "critical internal cache error!\n"; #endif setGlobalVariable(FIM_VID_CACHE_STATUS,getReport().c_str()); return NULL; } if( used_image( key ) ) { // if the image was already used, cloning occurs // image = image->getClone(); // EVIL !! try { #ifdef FIM_CACHE_DEBUG Image * oi=image; #endif image = new Image(*image); // cloning #ifdef FIM_CACHE_DEBUG std::cout << " cloned image: \"" <<image->getName()<< "\" "<< image << " from \""<<oi->getName() <<"\" " << oi << "\n"; #endif } catch(FimException e) { /* we will survive :P */ image = NULL; /* we make sure no taint remains */ // if( e != FIM_E_NO_IMAGE )throw FIM_E_TRAGIC; /* hope this never occurs :P */ } if(!image)return NULL; //means that cloning failed. clone_pool.insert(image); // we have a clone cloneUsageCounter[image]=1; } lru_touch( key ); // if loading and eventual cloning succeeded, we count the image as used of course usageCounter[key]++; setGlobalVariable(FIM_VID_CACHE_STATUS,getReport().c_str()); return image; //so, it could be a clone.. } }