Caching Library (English)
For the original Italian page, please click on the link: http://guru4.net/articoli/caching/default.aspx
Caching Library is a framework open-source of management of cache the more levels, designed for disaccoppiare the front-end applicativo from the concrete implementazione of the system of cache, to be scalabile and riusabile. Two levels of persistence of the cache are previewed, use you in elective way: the level more low is the rows system (slower but more capiente) while that highest one is the system of cache native of NET (System.Web.Caching.Cache). The bookcase implements also an control system of the state of the cache, defined "scavenging" that it concurs the automatic removal of the past due elements and contains the dimensions allotted from the less necessary cache of system rimuovendo, if necessary, elements by means of the automatic definition of the priority of the objects in cache. The priority of an element is calculated balancing the two more diffuse algorithms: MFU (Most Frequently Used) and LFU (Least Frequently Used). To the article they are binds together the sources to you of the plan, the rows binary, the documentation (releasable in format chm or consultabile on-linens) and a demonstrative application of I use.
The article Caching Architecture Guides for NET Framework Applications published from MSDN illustrates in exaustive way requirement that must have a good system of cache and defines the optimal architecture for its implementazione. The main points that emerge from the reading of aforesaid articles (and in particular from the section "Understanding Advanced Caching Issues") are:
Disaccoppiare the front-end applicativo from the inner implementazione of the persistence of the cache and from the functions of access
To supply high performances and one scalabile solution
To implement specific advance functionalities, like dependencies, time of life and instruments of management (as an example the scavenging), concurring with the utilizzatori to realize the own implementazioni of control
The implementazione of Caching Library takes cue from the architecture suggested from the lines guides of Microsoft, even if, for semplicitÓ, in particular those regarding have been decided not to implement all explicitly the interfaces (the distributed systems). Al same time has been introduced also other concepts that in some way extend the potentialities of the system of caching (are looked at as an example: elective logic of I use of the Storage and the algorithm of scavenging automatic rifle).
The main elements of the system, and their interactions, are shown in the following figure:
The demands for access to the cache come managed from the CacheManager class that, beyond recovering or saving the data in the storage of persistence of the cache, interface with the CacheService class, person in charge of the control of the system through the management of the metadati ones of the present elements in chache.
Of continuation the relative diagram to the class Cache Manager, that is the interface from which the application it will approach the cache:
The class is static, therefore it cannot be istanziata.
The methods publics to use are:
Add in order to insert or to modernize an object in cache. The objects, for being archiviati in a Cache Storage, must be serializzabili, that is must introduce the attribute [ Serializable ].
Get in order to obtain an object from the cache
Remove in order to eliminate an object from the cache
For every operation the CacheManager, come.primo.cosa, call the CacheStorage for the access to the data, therefore the CacheService for the modernization of the metadati ones relati you to the demanded object.
The method "Scavenge", seppur visible public, is used inner and it would not have to be to be recalled directly from the layer applicativo.
The class Cache Service comes used inner in order to control the state of the memory through the access to the metadati ones of every present element in cache.
The CacheService is implemented like singleton, therefore only a request of the class is present in every applicativo dominion. The GetInstance method is used in order to obtain the concrete request to use.
The class exposes the methods for the access metadati (to the Add, Get and Remove) and implements a mechanism of periodic control of the state of the cache, activated from an inner request of type System.Threading.Timer. To every expiration of the timer it comes executed the Scavenge method that removes from cache the past due elements and controls that it has not been exceeded the maximum threshold of I use of the storage. In qusto case they come removed from cache also the other objects, until that I use it of the storage is returned under the minimal threshold; the elements come eliminate to you in function of their calculate priority (to this purpose look at the definition of the CacheItemMetadata class).
Class diagram following the extension the relative entities to the storage of the data and the metadati ones:
The access to the storage comes made using the interface ICacheStorage, implemented from every storage concrete.
At the moment they come defined two storage: FileSystemCacheStorage (storage of the
data on rows system) and SystemCacheStorage (storage of the data in the cache native of ASP.NET, System.Web.HttpRuntime.Cache), it uses you in elective way (for a greater
understanding of the elective system of I use of the storage is sent
back to the relati to you cases of use).
The storage of system it directly uses the cache of system, invocando the method Insert, always adding the elements with equal priority to "CacheItemPriority.NotRemovable"since the control of the state of the storage is entrusted to the scavenging inner. You notice yourself that SystemCacheStorage exposes also a method RemovedCallback, currently implemented (he is not available for implementazioni or extensions custom), used as delegated (System.Web.Caching.CacheItemRemovedCallback) for the notification to the application of the removal of an element from the cache.
Being the storage it implements to you like singleton, their access comes made by means of it I use of one factory (CacheStorageFactory); the GetCacheStorage method gives back the demanded request of the storage concrete on the base of the enumeratore received CacheStorageProvider.
The storage of metadati (the MetadataCacheStorage) it turns out different leggermente, in how much implemented in specific way in order to optimize the access to the metadati ones informed to you.
The metadati ones contain information on the present elements in cache and on theirs I use (demanded received, time of life, expiration, dimension, etc.):
For every tipologia of object to save in cache it is necessary to supply delegates of CacheItemMetadataCreation type for the specific generation of metadato (time of life concurred, expiration absolute, etc.)
Like pointed out speaking about the method CacheService.Scavenge, the metadati ones, beyond to the HasExpired property that it indicates that the object is not more active and must therefore be eliminated, they expose to an other important calculate property: Priority. The priority comes determined in real time contemplating various aspects, therefore at the same time to consider the two more diffuse algorithms for the control of the cache: MFU (Most Frequently Used) and LFU (Least Frequently Used). In particular it comes used the following formula:
PrioritÓ = |((1 / (Now - DataUltimoUtilizzo)) * (TotaleRichieste / (Now - DataCreazione)))| 1
The elements with HasExpired = true have priority = 0, while for the others currency the time passed from the last one I use myself and I use it made mean of the object (the result is a number > = 1).
They come used others two classes (not represented in the diagram) for the access to the collection of the metadati ones: CacheItemMetadataDictionary (of type "dictionary", that is consultabile for key) and CacheItemMetadataList (of type list and ordinabile)
Exceptions and usefullness
To completion of the architecture of the system of cache we define:
one class (static) for the generation of keys univoche: KeyGenerator. The keys come generated on the base of the type of object (System.Type) and on the parameters that render univoco the object as an example (the value of property ID)
one CachingException class that drifts give System.Exception in order to classify in way univoco the exception raised from the layer of cache in an architecture the fine-level
Cases of use
In order better to comprise the operation of the system of cache we analyze the cases of use for operations CRUD (Created, Read, Update and Delete)
Insertion or modification
In order to insert or to modify a present element in cache it comes invocato a CacheManager.Add method that inserts the object in the FileSystemCacheStorage and removes eventual copies of the entity from SystemCacheStorage and the metadati relati ones to you, therefore to avoid the access to elements does not dawn to you
The reading of cache (the CacheManager.Get) demands initially the object to the SystemStorage; in case it is not possible to obtain the object from the cache of system, will be attempted in the FileSystemCacheStorage; if the operation has succeeded the object it comes added also to the SystemCacheStorage for the accesses succeeded to you. At the same time it comes notified to the CacheService the demand received for the modernization for the metadati correspondents.
The cancellation of the copy cache of an object previews the cancellation of the entity from both storage (the SystemCacheStorage and FileSystemCacheStorage) and the destruction of the metadati relati ones to you.
The framework proposed for the management of the cache it can be shaped directly from the following rows web.config with parameters:
Caching.FileSystemCacheStorge.Path: physical distance for the recording of the cache on rows system
Caching.CacheService.ScavangeInterval: interval of execution (in milliseconds) of the pulizia of the cache
Caching.CacheService.MaxMemoryUsage: the allocabile maximum memory (in bytes) for the cache; to the attainment of this threshold it comes started pulizia (the Scavange)
Caching.CacheService.MinMemoryAvailableAfterScavenge: minimal memory available (in bytes) for the cache after the pulizia
Caching.KeyGenerator.BaseNamespace: space of the names predefined for the generation of the keys
Of continuation an example:
<add key="Caching.FileSystemCacheStorge.Path" value="C:\cache\" />
<add key="Caching.CacheService.ScavangeInterval" value="60000" />
<add key="Caching.CacheService.MaxMemoryUsage" value="104857600" />
<add key="Caching.CacheService.MinMemoryAvailableAfterScavenge" value="52428800" />
<add key="Caching.KeyGenerator.BaseNamespace" value="G4N" />
As we have seen the control of the state of the cache comes made automatically from the CacheService, than it is taken care to analyze and to clean up the SystemCacheStorage on the base of the metadati ones. As far as the FileSystemCacheStorage, being predisposed in order to manage various gigabyte (GB!) of data, it is not possible to think to control and to clean up in real time the space occupied disc. Of continuation a possible implementazione of management of the state of the storage is proposed on rows system, implementabile as application consul periodically to execute (Operations Planned of Windows) or like Windows Service in execution in background. It comes proposed an algorithm of pulizia much simple one: the removal of the rows to which it is not approached gives beyond 7 days; clearly the adoption of a mechanism based on this logic previews the corrected calibration in function of the real one uses of cache (the limit of an inactivity week could be too much or too much little based on the type of application).
public class ScavengeFileSystemCacheStorage
private static string CACHE_PATH = @"C:\cache\";
private static DateTime LAST_ACCESS_TIME_ACCEPTED = DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0));
static void Main(string args)
DirectoryInfo root = new DirectoryInfo(CACHE_PATH);
private static void ProcessDirectory(DirectoryInfo folder)
foreach (FileInfo fi in folder.GetFiles())
foreach (DirectoryInfo di in folder.GetDirectories())
// remove empty folder
if (folder.GetFiles().Length == 0 && folder.GetDirectories().Length == 0)
private static void ProcessFile(FileInfo fi)
if (fi.LastAccessTime < LAST_ACCESS_TIME_ACCEPTED)
The system of caching is planned in order to be used in applications with architecture fine-level (3-tier or n-tier); for a greater understanding of as the layer of caching it can be integrated in an application n-tier it sees the attached demonstrative plan.
Of continuation a possible definition of architecture (the levels applied are introduce to you with ordering bottom - up):
Layer date - the level of persistence of the data. Typically it comes used a database relational. In the demonstrative example the SQL Serveur is looked at database 2000 "Northwind", in particular the table "Customers"
Date Access Layer - classes that implement methods CRUD (creation, reading, modernization and elimination) of the persistent data. In the demonstrative example "CachingDemoLib/Customer/CustomerDataAccess.cs" is looked at
Caching Layer - classes for the access to the storage of the data in cache, therefore consequently to reduce the accesses to the Date Access Layer, increasing the performances. In the demonstrative example one looks at "CachingDemoLib/Customer/CustomerCache.cs" and "CachingDemoLib/Customer/CustomerListCache.cs"
Business Logic Layer - classes that implement applicativa logic, the rules of business and those of validazione of the application. In the demonstrative example "CachingDemoLib/Customer/CustomerManager.cs" is looked at
Business Objects - classes that define the entities (and the collections of entity) of the applicativo dominion. "view" (front-end) of the application it converses exclusively with the Business Logic and in terms of entity (or types primiti to you). In the demonstrative example one looks at "CachingDemoLib/Customer/Customer.cs" and "CachingDemoLib/Customer/CustomerList.cs"
Front-end - controls, form, dynamic pages of presentation of the entities which it approaches the customer. In the demonstrative example pages ASPX of the plan Web "CachingDemoWeb" are looked at
Some operations turn out repetitive and, therefore, it is possible to create framework or bookcases in order to become simpler some and to conform of the execution (as an example takes in consideration the management of the logons to the database, the execution of instructions SQL of writing and reading, etc). In the same way the proposed bookcase of cache is devised in order to manage the access to the cache: it does not contain logical of a specific application but the more generic methods and than common use.