/*! * \ingroup cache_interface * * Cette fonction permet d'écrire un enregistrement à travers le cache. * * La fonction Get_Block retourne le bloc du cache contenant l'enregistrement à * l'indice-fichier irfile. Il n'y a plus qu'à faire la copie physique depuis la * zone de l'utilisateur. Le bloc est marqué modifié (flag MODIF). * La fonction 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ù lire l'enregistrement dans l'espace utilisateur * \return le code d'erreur */ Cache_Error Cache_Write(struct Cache *pcache, int irfile, const void *precord) { struct Cache_Block_Header *pbh; pcache->instrument.n_writes++; if ((pbh = Get_Block(pcache, irfile)) == NULL) return CACHE_KO; (void)memcpy(ADDR(pcache, irfile, pbh), precord, pcache->recordsz); pbh->flags |= MODIF; Strategy_Write(pcache, pbh); return Do_Sync_If_Needed(pcache); }
//! Écriture (à travers le cache). Cache_Error Cache_Write(struct Cache *pcache, int irfile, const 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)) { pcache->instrument.n_hits++; cbh = h; 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|MODIF); fseek(pcache->fp, DADDR(pcache, ibfile), SEEK_SET); fread(cbh->data, pcache->blocksz, 1, pcache->fp); } memcpy(ADDR(pcache, irfile, cbh), precord, pcache->recordsz); pcache->instrument.n_writes++; Strategy_Write(pcache, cbh); return CACHE_OK; }