예제 #1
0
int do_gc(LRU_list_t * plru)
{
  return LRU_gc_invalid(plru, NULL);
}
예제 #2
0
/**
 *
 * 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 */
예제 #3
0
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 */