Publié vendredi 28 mars 2008 12:54 par Luke77

Une partie de Cache - Cache / Partie 2

Et nous revoilà pour la seconde partie de ce post consacré au Cache tant décrié ;-) .

Afin de pouvoir stocker des éléments dans notre cache, nous allons devoir encapsuler notre objet Obj dans une classe générique (private au sein de la classe de Cache) qui contiendra la dernière date d'accès à Obj ainsi que sa durée de vie dans le cache. En voici le descriptif :

   1: private class CacheItem
   2: {
   3:     public V Item;
   4:     public DateTime LastRefresh;
   5:     public readonly bool SlidingExpiration;
   6:     public readonly TimeSpan Duration;
   7:  
   8:     public CacheItem(V value, bool slidingExpiration, TimeSpan duration)
   9:     {
  10:         Item = value;
  11:         LastRefresh = DateTime.Now;
  12:         SlidingExpiration = slidingExpiration;
  13:         Duration = duration;
  14:     }
  15: }

Si on se souvient du post précédent on peut voir rapidement que l'on reprend le type générique fourni dans la définition de notre cache (ie. Cache<K, V>).

On peut se demander pourquoi ne pas stocker directement la date d'expiration de l'objet plutôt que la date du dernier accès. Tout simplement parce que notre cache permet une SlidingExpiration (ie. prolonger la durée de vie de l'objet à chaque accès chaque fois que ce dernier est requêté). Cette SlidingExpiration imposerait de recalculer continuellement une nouvelle date d'expiration ce qui coûterait cher en terme de temps processeur.

Dans le post précédent, j'avais indiqué que notre cache allait implémenter l'interface IDictionnary. Or cette interface ne prévoit pas dans ses méthodes un argument définissant une durée de vie, ni la SlidingExpiration. Il faut donc pouvoir définir des valeurs par défaut lorsque ces méthodes seront appelées. Cela sera possible grâce aux propriétés suivante dans notre cache.

   1: public TimeSpan DefaultDuration
   2: {
   3:     get { return _defaultDuration; }
   4:     set { _defaultDuration = value; }
   5: }
   6:  
   7: public bool DefaultSlidingExpiration
   8: {
   9:     get { return _defaultSlidingExpiration; }
  10:     set { _defaultSlidingExpiration = value; }
  11: }

 

Mettre ici l'ensemble des méthodes que les différentes interfaces nous imposent d'implémenter nous prendrait un peu trop de place, et surtout je vais pas faire tout le boulot... :-) Je me contenterai seulement de mettre deux exemples (l'ajout et la récupération de valeur) qui illustre tout ce dont j'ai déjà parlé (le ReaderWriterLockSlim ainsi que notre classe générique) :

   1: public void Add(K key, V value)
   2: {
   3:     _lock.EnterWriteLock();
   4:     try
   5:     {
   6:         _items.Add(key, new CacheItem(value, _defaultSlidingExpiration, _defaultDuration));
   7:     }
   8:     finally
   9:     {
  10:         _lock.ExitWriteLock();
  11:     }
  12: }
  13:  
  14: ...
  15:  
  16: public bool TryGetValue(K key, out V value)
  17: {
  18:     _lock.EnterReadLock();
  19:     try
  20:     {
  21:         CacheItem ci;
  22:         if (_items.TryGetValue(key, out ci))
  23:         {
  24:             if (ci.SlidingExpiration)
  25:             {
  26:                 ci.LastRefresh = DateTime.Now;
  27:             }
  28:             value = ci.Item;
  29:             return true;
  30:         }
  31:     }
  32:     finally
  33:     {
  34:         _lock.ExitReadLock();
  35:     }
  36:     value = default(V);
  37:     return false;
  38: }

Et voilà, grâce à tout ça, et surtout si tu es motivé, tu devrais être capable d'avoir un cache qui se remplit sans problème mais qui est aussi et surtout entièrement Thread-Safe.

 

Dans un dernier post, nous verrons ensemble la touche finale de notre cache : comment faire expirer les éléments de notre cache.

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Les 10 derniers blogs postés

- T_PAAMAYIM_NEKUDOTAYIM par MadMatt le il y a 16 heures et 55 minutes

- Et je mets le son.... par Pierrick's Blog le il y a 21 heures et 1 minutes

- SharePoint : Comment interdire l’accès à un utilisateur pour tous les sites d’une Web Application par Blog Technique de Romelard Fabrice le 07-18-2008, 19:05

- VPC - Reset de la position de la console par Blog technique de Nicolas Boonaert le 07-18-2008, 16:29

- Un bug dans IE rendra cette page… non-imprimable ! par Le blog de FremyCompany le 07-18-2008, 15:33

- Quelques retours sur Google Protocol Buffers par Julien Chable le 07-18-2008, 11:10

- SharePoint et le multilinguisme : Comment gérer la traduction des propriétés dans les toolbars des WebParts par The Mit's Blog le 07-18-2008, 10:53

- [Open XML] Les liens de la semaine 14/07/2008 par Julien Chable le 07-18-2008, 10:29

- Une nouvelle version des TFS Power tools est disponible par Michel Perfetti [Miiitch] le 07-18-2008, 09:37

- EF et le testeur fou par Matthieu MEZIL le 07-18-2008, 07:34