home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / src / io / buffer / cache.c < prev    next >
C/C++ Source or Header  |  2004-09-21  |  5KB  |  197 lines

  1. /* common functions for cache management. These functions are shared
  2.  * by all cache policies.
  3.  */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6.  
  7. #include "internal.h"
  8. #include "state.h"
  9. #include "flags.h"
  10. #include "cache.h"
  11. #include "ncac-lru.h"
  12.  
  13. /*
  14.  * lookup_cache_item: Given the index of an extent, look up whether this 
  15.  * extent is cached or not.
  16.  *     Cached: retured the extent 
  17.  *     NOT cached: return NULL.
  18.  */
  19. struct extent * lookup_cache_item(struct inode *mapping, unsigned long index)
  20. {
  21.     struct extent *extent;
  22.  
  23.     extent = radix_tree_lookup(&mapping->page_tree, index);
  24.  
  25.     return extent;
  26. }
  27.  
  28. /* ==================================================================
  29.  * add an item into the cache:                                      *
  30.  * (1) add an item into the radix tree (add_cache_item_no_policy).  *
  31.  * (2) add an item into the cache (add_cache_item_with_policy).     *
  32.  * ==================================================================
  33.  */
  34.  
  35. /* add_cache_item_no_policy(): add an extent into the cache tree.
  36.  * Each inode has a cache tree, protected by its "lock". 
  37.  * NOT cache policy related.
  38.  */
  39. static inline int add_cache_item_no_policy(struct extent *extent, 
  40.          struct inode *mapping, unsigned long index)
  41. {
  42.     int error;
  43.  
  44.     error = radix_tree_insert(&mapping->page_tree, index, extent); 
  45.     if ( !error ) {
  46.         list_add(&extent->list, &mapping->clean_pages);
  47.         extent->mapping = mapping;
  48.         extent->index = index;
  49.         mapping->nrpages++;
  50.     }
  51.     return error;
  52. }
  53.  
  54. /* add an item into a cache list with certain policy.
  55.  * Current implementation is related to LRU. This function is
  56.  * cache policy related.
  57.  */
  58. static inline void add_cache_item_with_policy(struct extent *extent, int cache_policy)
  59. {
  60.     struct cache_stack *cache_stack = NULL;
  61.  
  62.     cache_stack = get_extent_cache_stack(extent);
  63.  
  64.     switch (cache_policy) {
  65.         case LRU_POLICY:
  66.             LRU_add_cache_item(cache_stack, extent);
  67.             break;
  68.  
  69.         default:
  70.             NCAC_error("unknown cache policy");
  71.             break;
  72.     }
  73. }
  74.  
  75. /* add an extent into the cache. */
  76. int add_cache_item(struct extent *extent, struct inode *mapping,
  77.             unsigned long index, int policy)
  78. {
  79.     /* 1. bookkeeping in the radix tree */
  80.     int ret = add_cache_item_no_policy(extent, mapping, index);
  81.  
  82.     /* 2. put into cache list with respect to the cache policy */ 
  83.     if (ret == 0){
  84.         add_cache_item_with_policy(extent, policy);
  85.         return ret;
  86.     }
  87.     return ret;    
  88. }
  89.  
  90. /* ==================================================================
  91.  *                remove an item from the cache:                    *
  92.  * (1) remove it from the radix tree (remove_cache_item_no_policy). *
  93.  * (2) remove it from its cache list.(remove_cache_item_with_policy)*
  94.  * (3) add this item into the free extent list (add_free_extent_list_item    *
  95.  * ================================================================== 
  96.  */
  97.  
  98. static void remove_cache_item_no_policy(struct extent *extent)
  99. {
  100.     struct inode *mapping = extent->mapping;
  101.  
  102.     radix_tree_delete(&mapping->page_tree, extent->index);
  103.  
  104.     /* get this back if the "list" field is used */
  105.     //list_del(&page->list);
  106.     extent->mapping = NULL;
  107. }
  108.  
  109. static void remove_cache_item_with_policy(struct extent *victim, int policy)
  110. {
  111.     struct cache_stack *cache;
  112.  
  113.     cache = get_extent_cache_stack(victim);
  114.     if ( NULL == cache ){
  115.         NCAC_error("extent cache stack is NULL");
  116.         return;
  117.     }
  118.     switch (policy){
  119.         case LRU_POLICY:
  120.             LRU_remove_cache_item(cache, victim);
  121.             break;
  122.         default:
  123.             NCAC_error("unknown cache policy");
  124.             break;
  125.     }
  126. }
  127.  
  128. void remove_cache_item(struct extent *extent, int policy)
  129. {
  130.  
  131.     remove_cache_item_with_policy(extent, policy);
  132.     remove_cache_item_no_policy(extent);
  133. }
  134.  
  135. struct extent * get_free_extent_list_item(struct list_head *list)
  136. {
  137.     struct extent *new;
  138.     struct list_head *delete;
  139.  
  140.     if ( list_empty(list) ) return NULL;
  141.  
  142.     delete = list->next;
  143.     list_del_init(delete);
  144.  
  145.     new = list_entry(delete->prev, struct extent, list);
  146.  
  147.     return new;
  148. }
  149.  
  150.  
  151. /* shrink_cache: shrink a cache with expected number of extents. The
  152.  * real number of extents which have been shrinked is returned by
  153.  * "scanned". This number might be less than "expected". All shrinked
  154.  * extents are returned into the extent free list.
  155.  * Different cache policies take their own ways to do shrink.
  156.  */
  157. int shrink_cache(struct cache_stack *cache_stack, 
  158.                  unsigned int expected, 
  159.                  int policy, 
  160.                  unsigned int *shrinked)
  161. {
  162.     int ret=-1;
  163.  
  164.     switch (policy){
  165.         case LRU_POLICY:
  166.             ret = LRU_shrink_cache(cache_stack, expected, shrinked);
  167.             break;
  168.  
  169.         case ARC_POLICY: 
  170.             ret = LRU_shrink_cache(cache_stack, expected, shrinked);
  171.             break;
  172.         
  173.         default:
  174.             NCAC_error("unknown cache policy");
  175.             break;
  176.     }
  177.     return ret;
  178. }
  179.  
  180.  
  181. int is_extent_discardable(struct extent *victim)
  182. {
  183.     if ( PageClean(victim) && 0 == victim->reads && 0 == victim->writes ) 
  184.         return 1;
  185.     else 
  186.         return 0;
  187. }
  188.  
  189. /* hit_cache_item: cache hit, change the position according to the policy */
  190. void hit_cache_item(struct extent *extent, int cache_policy)
  191. {
  192.     remove_cache_item_with_policy(extent, cache_policy);
  193.     add_cache_item_with_policy(extent, cache_policy);
  194.     return;
  195. }
  196.  
  197.