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

- ssdl view et TPT par Matthieu MEZIL le 07-05-2008, 02:04

- L'injection SQL n'est PAS un problème QUE pour les développeurs web ! par CoqBlog le 07-05-2008, 01:08

- Un outil pour réaliser des animations WPF basées sur des équations de Bézier par Perspective le 07-04-2008, 21:45

- Sandcastle et CodePlex : le verdict par CoqBlog le 07-04-2008, 20:53

- ssdl view et TPH par Matthieu MEZIL le 07-04-2008, 19:12

- Webcasts sur le Parallel Framework disponibles par Matthieu MEZIL le 07-04-2008, 17:26

- [Silverlight] - Comprendre et Débuter avec Silverlight par Danuz le 07-04-2008, 12:41

- SharePoint : Nouvel article sur l'exportation et Importation de sites SharePoint par Blog Technique de Romelard Fabrice le 07-04-2008, 01:00

- ImagineCup 2008 Final in Paris: Day 1 par Richard Clark le 07-03-2008, 22:48

- PowerShell : Comment utiliser un ENUM .NET dans un script PowerShell par Blog Technique de Romelard Fabrice le 07-03-2008, 18:09