5 mbkcache
*FILE_CACHE
= NULL
;
6 int FILE_CACHE_INDEX
= 0 ;
7 HeapAlloc FILE_CACHE_HEAP
;
8 ht
*FILE_CACHE_HT
= NULL
;
9 int MBK_MAX_CACHE
= 128 ;
11 /*****************************************************************************\
14 Crée un nouveau cache.
15 \*****************************************************************************/
17 mbkcache
* mbk_cache_create( char (*isactive
)( void *root
, void *elem
),
18 unsigned long int (*load
)( void *root
, void *elem
),
19 unsigned long int (*release
)( void *root
, void *elem
),
20 unsigned long int cachesize
25 cache
= mbk_cache_alloc();
27 cache
->CACHESIZE
= cachesize
;
28 cache
->INFOS
= addht( CACHE_ALLOC_BLOCLIST
);
29 cache
->FN_ISACTIVE
= isactive
;
30 cache
->FN_LOAD
= load
;
31 cache
->FN_RELEASE
= release
;
36 /*****************************************************************************\
39 Charge en mémoire un élément si il n'est pas déjà présent. Libère d'autres
40 éléments si c'est nécessaire.
41 \*****************************************************************************/
43 void mbk_cache_refresh( mbkcache
*cache
, void *root
, void *elem
)
45 mbkcachelist
*incache
;
47 if( !cache
|| mbk_cache_call_iscative( cache
, root
, elem
) == 0 )
50 avt_logenterfunction(LOGMBKCACHE
,2, "mbk_cache_refresh()" );
51 incache
= mbk_cache_getmbkcachelist( cache
, elem
);
54 avt_log(LOGMBKCACHE
,2,"element already loaded\n");
55 // L'élément est présent dans le cache, on le met en tête des éléments les
57 if( incache
!= cache
->FIRST
)
58 mbk_cache_makeitfirst( cache
, incache
);
62 // L'élément n'est pas dans le cache. On fait du ménage si necéssaire, puis
63 // on lit le nouvel élément.
65 // si le cache est limité en nb d'éléments, on réserve un éléments pour
66 // celui qui va être lu.
70 mbk_cache_update_memory( cache
, root
);
76 mbk_cache_add( cache
, root
, elem
);
79 avt_logexitfunction(LOGMBKCACHE
,2);
82 /*****************************************************************************\
85 Force la libération d'un élément du cache.
86 \*****************************************************************************/
88 void mbk_cache_release( mbkcache
*cache
, void *root
, void *elem
)
90 mbkcachelist
*incache
;
92 if( !cache
|| mbk_cache_call_iscative( cache
, root
, elem
) == 0 )
95 incache
= mbk_cache_getmbkcachelist( cache
, elem
);
96 if( incache
== NULL
) return;
98 if( incache
->LOCKED
== 0 )
99 mbk_cache_remove( cache
, incache
, root
);
102 /*****************************************************************************\
104 Fonction utilisateur.
105 Efface le cache. Appel mbk_cache_release() pour tous les éléments encore
106 présents dans le cache.
107 \*****************************************************************************/
109 extern void mbk_cache_delete( mbkcache
*cache
, void *root
)
111 while( cache
->FIRST
)
112 mbk_cache_remove( cache
, cache
->FIRST
, root
);
113 mbk_cache_free( cache
);
116 /*****************************************************************************\
118 Fonction utilisateur.
119 Verrouille un élément en mémoire
120 \*****************************************************************************/
122 extern void mbk_cache_lock( mbkcache
*cache
, void *elem
)
124 mbkcachelist
*incache
;
126 incache
= mbk_cache_getmbkcachelist( cache
, elem
);
127 if( incache
== NULL
) return;
132 /*****************************************************************************\
134 Fonction utilisateur.
135 Deverrouille un élément en mémoire
136 \*****************************************************************************/
138 extern void mbk_cache_unlock( mbkcache
*cache
, void *elem
)
140 mbkcachelist
*incache
;
142 incache
= mbk_cache_getmbkcachelist( cache
, elem
);
143 if( incache
== NULL
) return;
145 if( incache
->LOCKED
> 0 )
149 /*****************************************************************************\
151 Fonction utilisateur.
152 Informe si l'élément est vérouillé
153 \*****************************************************************************/
155 extern char mbk_cache_islock( mbkcache
*cache
, void *elem
)
157 mbkcachelist
*incache
;
159 incache
= mbk_cache_getmbkcachelist( cache
, elem
);
160 if( incache
== NULL
) return NO
;
162 if( incache
->LOCKED
> 0 )
167 /*****************************************************************************\
168 mbk_cache_update_size()
169 Fonction utilisateur.
170 Informe le cache que la taille d'un ou plusieurs de ses éléments a changée.
171 Libère des éléments si la taille maximum du cache a été dépassée.
172 \*****************************************************************************/
173 void mbk_cache_update_size( mbkcache
*cache
, void *root
, long int size
)
175 cache
->CURSIZE
= cache
->CURSIZE
+ size
;
176 mbk_cache_update_memory( cache
, root
);
179 /*****************************************************************************\
180 mbk_cache_list_content()
181 Fonction utilisateur.
182 renvoie la liste chainée des éléments présents dans le cache
183 \*****************************************************************************/
184 chain_list
* mbk_cache_list_content( mbkcache
*cache
)
191 for( scan
= cache
->LAST
; scan
; scan
= scan
->PREV
) {
192 list
= addchain( list
, scan
->DATA
);
198 /*****************************************************************************\
199 mbk_cache_set_limit_element()
201 Limite le nombre d'éléments pouvant être présent à chaque instant dans le
202 cache, en plus du critère de taille de cache.
203 Si 0, le nombre d'élément est illimité, le nombre d'éléments présents dans le
204 cache n'est limité que par la taille du cache.
205 Appelle automatiquement mbk_cache_release() pour tous les éléments en excès dans
207 \*****************************************************************************/
208 void mbk_cache_set_limit_element( mbkcache
*cache
,
213 cache
->MAXELEM
= nbelem
;
214 mbk_cache_update_memory( cache
, root
);
217 /*****************************************************************************\
218 mbk_cache_update_memory()
220 Si la taille maximum du cache est atteinte ou dépassée, libère les éléments de
222 \*****************************************************************************/
223 void mbk_cache_update_memory( mbkcache
*cache
, void *root
)
225 mbkcachelist
*lastlock
;
226 mbkcachelist
*testremove
;
229 while( cache
->CURSIZE
>= cache
->CACHESIZE
||
230 ( cache
->MAXELEM
> 0 && cache
->CURELEM
>= cache
->MAXELEM
) ) {
233 testremove
= lastlock
->PREV
;
235 testremove
= cache
->LAST
;
240 if( mbk_cache_islock( cache
, testremove
->DATA
)==NO
)
241 mbk_cache_remove( cache
, testremove
, root
);
243 lastlock
= testremove
;
245 if( cache
->FIRST
== lastlock
) {
246 /* Le cache est saturé d'éléments vérrouillés */
247 if( cache
->MAXELEM
> 0 && cache
->CURELEM
> cache
->MAXELEM
) {
248 avt_log(LOGMBKCACHE
,2,"maximum number of element in cache is excedeed : max=%u current=%u\n", cache
->MAXELEM
, cache
->CURELEM
);
255 /*****************************************************************************\
258 Ajoute un élément dans le cache.
259 \*****************************************************************************/
260 void mbk_cache_add( mbkcache
*cache
, void *root
, void *elem
)
262 mbkcachelist
*incache
;
264 avt_logenterfunction(LOGMBKCACHE
,2,"mbk_cache_add()" );
266 incache
= mbk_cache_alloccachelist( cache
);
267 cache
->CURSIZE
= cache
->CURSIZE
+ mbk_cache_call_load( cache
, root
, elem
);
269 incache
->DATA
= elem
;
270 incache
->PREV
= NULL
;
271 incache
->NEXT
= cache
->FIRST
;
272 incache
->LOCKED
= 0 ;
273 cache
->FIRST
= incache
;
275 cache
->LAST
= incache
;
277 incache
->NEXT
->PREV
= incache
;
279 mbk_cache_setmbkcachelist( cache
, elem
, incache
);
281 avt_logexitfunction(LOGMBKCACHE
,2);
284 /*****************************************************************************\
287 Libère un élément présent du cache.
288 \*****************************************************************************/
289 void mbk_cache_remove( mbkcache
*cache
, mbkcachelist
*incache
, void *root
)
291 avt_logenterfunction(LOGMBKCACHE
,2,"mbk_cache_remove()");
292 cache
->CURSIZE
= cache
->CURSIZE
- mbk_cache_call_release( cache
, root
, incache
->DATA
);
293 mbk_cache_delmbkcachelist( cache
, incache
->DATA
);
296 incache
->PREV
->NEXT
= incache
->NEXT
;
298 cache
->FIRST
= incache
->NEXT
;
301 incache
->NEXT
->PREV
= incache
->PREV
;
303 cache
->LAST
= incache
->PREV
;
305 mbk_cache_freecachelist( cache
, incache
);
307 avt_logexitfunction(LOGMBKCACHE
,2);
310 /*****************************************************************************\
311 mbk_cache_makeitfirst()
313 Fait de l'élément incache le premier élément de la liste.
314 \*****************************************************************************/
316 void mbk_cache_makeitfirst( mbkcache
*cache
, mbkcachelist
*incache
)
318 if( incache
->PREV
) incache
->PREV
->NEXT
= incache
->NEXT
;
321 incache
->NEXT
->PREV
= incache
->PREV
;
323 cache
->LAST
= incache
->PREV
;
325 cache
->FIRST
->PREV
= incache
;
326 incache
->NEXT
= cache
->FIRST
;
327 incache
->PREV
= NULL
;
329 cache
->FIRST
= incache
;
332 /*****************************************************************************\
333 Appels des fonctions utilisateur.
335 \*****************************************************************************/
337 char mbk_cache_call_iscative( mbkcache
*cache
, void *root
, void *elem
)
339 if( !cache
->FN_ISACTIVE
)
342 return (cache
->FN_ISACTIVE
)(root
, elem
);
345 unsigned long int mbk_cache_call_load( mbkcache
*cache
, void *root
, void *elem
)
347 return (cache
->FN_LOAD
)(root
, elem
);
350 unsigned long int mbk_cache_call_release( mbkcache
*cache
, void *root
, void *elem
)
352 return (cache
->FN_RELEASE
)(root
, elem
);
355 /*****************************************************************************\
356 Accède à un mbkcachelist à partir du data.
358 \*****************************************************************************/
360 mbkcachelist
* mbk_cache_getmbkcachelist( mbkcache
*cache
, void *data
)
362 mbkcachelist
*cachelist
;
364 cachelist
= (mbkcachelist
*)gethtitem( cache
->INFOS
, data
);
365 if( cachelist
== (mbkcachelist
*)EMPTYHT
|| cachelist
== (mbkcachelist
*)DELETEHT
)
370 void mbk_cache_setmbkcachelist( mbkcache
*cache
, void *data
, mbkcachelist
*cachelist
)
372 addhtitem( cache
->INFOS
, data
, (long int)cachelist
);
375 void mbk_cache_delmbkcachelist( mbkcache
*cache
, void *data
)
377 delhtitem( cache
->INFOS
, data
);
380 /*****************************************************************************\
381 Fonctions d'allocation.
383 \*****************************************************************************/
385 void mbk_cache_freecachelist( mbkcache
*cache
, mbkcachelist
*incache
)
387 DelHeapItem( &(cache
->HEAPCACHELIST
), incache
);
390 mbkcachelist
* mbk_cache_alloccachelist( mbkcache
*cache
)
394 elem
= (mbkcachelist
*) AddHeapItem( & (cache
->HEAPCACHELIST
) );
404 void mbk_cache_free( mbkcache
*cache
)
406 DeleteHeap( &( cache
->HEAPCACHELIST
) );
407 delht( cache
->INFOS
);
411 mbkcache
* mbk_cache_alloc( void )
415 cache
= (mbkcache
*)mbkalloc( sizeof( mbkcache
) );
419 cache
->CACHESIZE
= 0ul;
420 cache
->CURSIZE
= 0ul;
422 cache
->FN_ISACTIVE
= NULL
;
423 cache
->FN_LOAD
= NULL
;
424 cache
->FN_RELEASE
= NULL
;
427 CreateHeap( sizeof( mbkcachelist
),
428 CACHE_ALLOC_BLOCLIST
,
429 &(cache
->HEAPCACHELIST
)
435 /*****************************************************************************\
436 Fonctions permettant de limiter le nombre maximum de fichiers ouverts.
437 \*****************************************************************************/
439 /*****************************************************************************\
441 Fonctions utilisateur.
442 Renvoie un index associé au fichier passé en paramètre.
443 \*****************************************************************************/
444 int mbk_cache_set_file( FILE *fd
, char *filename
, char *extension
)
449 FILE_CACHE
= mbk_cache_create( NULL
,
450 (unsigned long int (*)(void*,void*))mbk_cache_file_open
,
451 (unsigned long int (*)(void*,void*))mbk_cache_file_close
,
454 CreateHeap( sizeof( cache_file
), 16, &FILE_CACHE_HEAP
);
455 FILE_CACHE_HT
= addht( 16 );
458 elem
= (cache_file
*) AddHeapItem( &FILE_CACHE_HEAP
);
459 elem
->IFILE
= ++FILE_CACHE_INDEX
;
461 elem
->BASENAME
= mbkstrdup( filename
);
462 elem
->EXTENSION
= mbkstrdup( extension
);
463 elem
->SIZE
= mbk_getfileacces( fd
);
464 addhtitem( FILE_CACHE_HT
, (void*)((long)elem
->IFILE
), (long)elem
);
466 mbk_cache_refresh( FILE_CACHE
, NULL
, elem
);
471 /*****************************************************************************\
473 Fonctions utilisateur.
474 Renvoie le fichier associé à l'index passé en paramètre
475 \*****************************************************************************/
476 FILE* mbk_cache_get_file( int id
)
483 elem
= (cache_file
*)gethtitem( FILE_CACHE_HT
, (void*)((long)id
));
484 if( (long)elem
== EMPTYHT
|| (long)elem
== DELETEHT
)
487 mbk_cache_refresh( FILE_CACHE
, NULL
, elem
);
492 /*****************************************************************************\
493 mbk_cache_clear_file()
494 Fonctions utilisateur.
495 Libère les informations associées à l'index passé en paramètre. Si le fichier
496 est ouvert, il est fermé.
497 \*****************************************************************************/
498 void mbk_cache_clear_file( int id
)
505 elem
= (cache_file
*)gethtitem( FILE_CACHE_HT
, (void*)((long)id
));
506 if( (long)elem
== EMPTYHT
|| (long)elem
== DELETEHT
)
509 mbk_cache_release( FILE_CACHE
, NULL
, elem
);
510 delhtitem( FILE_CACHE_HT
, (void*)elem
);
511 mbkfree( elem
->BASENAME
);
512 mbkfree( elem
->EXTENSION
);
513 DelHeapItem( &FILE_CACHE_HEAP
, elem
);
516 /*****************************************************************************\
517 mbk_cache_file_open()
519 Fonction de refresh : elle est appellée pour ouvrir un fichier.
520 \*****************************************************************************/
521 unsigned long int mbk_cache_file_open( void *root
, cache_file
*elem
)
524 elem
->PFILE
= mbkfopen_ext( elem
->BASENAME
,
531 avt_errmsg (MBK_ERRMSG
, "019", AVT_FATAL
,elem
->BASENAME
);
538 /*****************************************************************************\
539 mbk_cache_file_close()
541 Fonction de libération : elle est appellée pour fermer un fichier.
542 \*****************************************************************************/
543 unsigned long int mbk_cache_file_close( void *root
, cache_file
*elem
)
546 fclose( elem
->PFILE
);