int do_gc(LRU_list_t * plru) { return LRU_gc_invalid(plru, NULL); }
/** * * cache_inode_gc: Perform garbbage collection on the ressources managed by a client. * * Perform garbbage collection on the ressources managed by a client. * * @param ht [INOUT] the hashtable used to stored the cache_inode entries. * @param pclient [INOUT] ressource allocated by the client for the nfs management. * @param pstatus [OUT] returned status. * * @return CACHE_INODE_SUCCESS if operation is a success \n * @return CACHE_INODE_LRU_ERROR if allocation error occured when validating the entry * * @see HashTable_GetSize * @see LRU_invalidate_by_function * @see LRU_gc_invalid * */ cache_inode_status_t cache_inode_gc(hash_table_t * ht, cache_inode_client_t * pclient, cache_inode_status_t * pstatus) { cache_inode_param_gc_t gcparam; unsigned int hash_size; unsigned int invalid_before_gc = 0; unsigned int invalid_after_gc = 0; /* Set the return default to CACHE_INODE_SUCCESS */ *pstatus = CACHE_INODE_SUCCESS; /* Is this time to gc ? */ if(pclient->call_since_last_gc < cache_inode_gc_policy.nb_call_before_gc) return *pstatus; if(time(NULL) - pclient->time_of_last_gc < (int)(cache_inode_gc_policy.run_interval)) return *pstatus; /* Actual GC will be made */ pclient->call_since_last_gc = 0; pclient->time_of_last_gc = time(NULL); LogInfo(COMPONENT_CACHE_INODE_GC, "Checking if garbage collection is needed"); /* 1st ; we get the hash table size to see if garbage is required */ hash_size = HashTable_GetSize(ht); if(hash_size > cache_inode_gc_policy.hwmark_nb_entries) { /* * Garbage collection is made in several steps * 1- Set the oldest entry as invalid and garbage their contents * 2- Free the invalid entry in the LRU * * Behaviour: - A DIR_BEGINNING is garbaged with all its DIR_CONTINUE associated * - A directory is garbaged when all its entries are garbaged * */ gcparam.ht = ht; gcparam.pclient = pclient; gcparam.nb_to_be_purged = hash_size - cache_inode_gc_policy.lwmark_nb_entries; /* try to purge until lw mark is reached */ LogInfo(COMPONENT_CACHE_INODE_GC, "Garbage collection started (to be purged=%u, LRU size=%u)", pclient->lru_gc->nb_entry, gcparam.nb_to_be_purged); invalid_before_gc = pclient->lru_gc->nb_invalid; if(LRU_invalidate_by_function (pclient->lru_gc, cache_inode_gc_function, (void *)&gcparam) != LRU_LIST_SUCCESS) { *pstatus = CACHE_INODE_LRU_ERROR; return *pstatus; } invalid_after_gc = pclient->lru_gc->nb_invalid; /* Removes the LRU entries and put them back to the pool */ if(LRU_gc_invalid(pclient->lru_gc, NULL) != LRU_LIST_SUCCESS) { *pstatus = CACHE_INODE_LRU_ERROR; return *pstatus; } LogInfo(COMPONENT_CACHE_INODE_GC, "Garbage collection finished, %u entries removed", invalid_after_gc - invalid_before_gc); *pstatus = CACHE_INODE_SUCCESS; } else { /* no garbage is required, just gets ride of the invalid in tyhe LRU list */ /* Removes the LRU entries and put them back to the pool */ if(LRU_gc_invalid(pclient->lru_gc, NULL) != LRU_LIST_SUCCESS) { *pstatus = CACHE_INODE_LRU_ERROR; return *pstatus; } else *pstatus = CACHE_INODE_SUCCESS; } return *pstatus; } /* cache_inode_gc */
int main(int argc, char *argv[]) { SetDefaultLogging("TEST"); SetNamePgm("test_lru"); LRU_list_t *plru; LRU_parameter_t param; LRU_entry_t *entry = NULL; LRU_entry_t *kept_entry = NULL; LRU_status_t status = 0; int i = 0; char strtab[MAXTEST][10]; param.nb_entry_prealloc = PREALLOC; param.entry_to_str = print_entry; param.clean_entry = clean_entry; param.lp_name = "Test"; BuddyInit(NULL); if((plru = LRU_Init(param, &status)) == NULL) { LogTest("Test FAILED: Bad Init"); exit(1); } for(i = 0; i < MAXTEST; i++) { LogTest("Added entry %d", i); sprintf(strtab[i], "%d", i); if((entry = LRU_new_entry(plru, &status)) == NULL) { LogTest("Test FAILED: bad entry add, status = %d", status); exit(1); } entry->buffdata.pdata = strtab[i]; entry->buffdata.len = strlen(strtab[i]); if(i == KEPT_ENTRY) kept_entry = entry; } /* printing the table */ LRU_Print(plru); LRU_invalidate(plru, kept_entry); if(isFullDebug(COMPONENT_LRU)) LRU_Print(plru); if(LRU_gc_invalid(plru, NULL) != LRU_LIST_SUCCESS) { LogTest("Test FAILED: bad gc"); exit(1); } LRU_Print(plru); /* Tous les tests sont ok */ LogTest("\n-----------------------------------------"); LogTest("Test succeeded: all tests pass successfully"); exit(0); } /* main */