/*! * \ingroup cache_interface * * Cette fonction permet de lire un enregistrement à travers le cache. * * La fonction \c Get_Block retourne le bloc du cache contenant l'enregistrement à * l'index-fichier \a irfile. Il n'y a plus qu'à faire la copie physique dans la zone * de l'utilisateur. On doit également notifier la stratégie de ce qu'on vient * de faire. * * La fonction \c Do_Sync_If_Needed effectue une synchronisation à * intervalle régulier. * * \param pcache un pointeur sur le cache à synchroniser * \param irfile index de l'enregistrement dans le fichier * \param precord adresse où ranger l'enregistrement dans l'espace utilisateur * \return le code d'erreur */ Cache_Error Cache_Read(struct Cache *pcache, int irfile, void *precord) { struct Cache_Block_Header *pbh; pcache->instrument.n_reads++; if ((pbh = Get_Block(pcache, irfile)) == NULL) return CACHE_KO; (void)memcpy(precord, ADDR(pcache, irfile, pbh), pcache->recordsz); Strategy_Read(pcache, pbh); return Do_Sync_If_Needed(pcache); }
//! Lecture (à travers le cache). Cache_Error Cache_Read(struct Cache *pcache, int irfile, void *precord) { if(CheckSync(pcache)) Cache_Sync(pcache); int ibfile = (int)(irfile/pcache->nrecords); struct Cache_Block_Header *cbh = NULL; for(struct Cache_Block_Header *h = pcache->headers; h < (pcache->headers + pcache->nblocks); h++) { if(h->ibfile == ibfile && (h->flags & VALID)) { cbh = h; pcache->instrument.n_hits++; break; } } if(!cbh) { cbh = Strategy_Replace_Block(pcache); if(!cbh) cbh = pcache->headers; if(cbh->flags&MODIF) { fseek(pcache->fp, DADDR(pcache, cbh->ibfile), SEEK_SET); fwrite(cbh->data, pcache->blocksz, 1, pcache->fp); } cbh->ibfile = ibfile; cbh->flags = VALID; fseek(pcache->fp, DADDR(pcache, ibfile), SEEK_SET); fread(cbh->data, pcache->blocksz, 1, pcache->fp); } memcpy(precord, ADDR(pcache, irfile, cbh), pcache->recordsz); pcache->instrument.n_reads++; Strategy_Read(pcache, cbh); return CACHE_OK; }