/*! \brief Obtention depuis le fichier du bloc contenant l'enregistrement * d'indice-fichier donné. * * \ingroup cache_internal * * Cette fonction retourne un bloc valide contenant l'enregistrement cherché. * On cherche d'abord l'enregistrement dans le cache grâce à Find_Block. Si on * ne l'y trouve pas, on obtient un bloc libre grâce à la fonction * Strategy_Replace_Block (qui, comme son nom l'indique, depend de la * strategie). On sauve ce bloc si il est marqué modifié puis on initialise son * entête et on lit son contenu depuis le fichier (Read_Block). * * \param pcache un pointeur sur le cache à synchroniser * \param irfile indice du bloc cherché dans le fichier * \return un pointeur sur l'entête du bloc (ou le pointeur nul si le bloc n'est pas trouvé) */ struct Cache_Block_Header *Get_Block(struct Cache *pcache, int irfile) { struct Cache_Block_Header *pbh; if ((pbh = Find_Block(pcache, irfile)) == NULL) { /* L'enregistrement n'est pas dans le cache */ /* On demande un block à Strategy_Replace_Block */ pbh = Strategy_Replace_Block(pcache); if (pbh == NULL) return NULL; /* Si le bloc libéré est valide et modifié, on le sauve sur le fichier */ if ((pbh->flags & VALID) && (pbh->flags & MODIF) && (Write_Block(pcache, pbh) != CACHE_OK)) return NULL; /* On remplit le bloc libre et son entête avec l'information de * l'enregistrement d'indice-fichier irfile */ pbh->flags = 0; pbh->ibfile = irfile / pcache->nrecords; /* indice du bloc dans le fichier */ if (Read_Block(pcache, pbh) != CACHE_OK) return NULL; } /* Soit l'enregistrement était déjà dans le cache, soit on vient de l'y mettre */ return pbh; }
//a terminer Cache_Error Cache_Write(struct Cache *pcache, int irfile, const void *precord){ ibfile =irfile/nrecords; int var =IndexSearch( ibfile, pcache); if( var >-1){ memcpy(pcache->headers[var].data,precord,recordsz); }else{ struct Cache_Block_Header* block =Strategy_Replace_Block(pcache); Cache_Sync(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; }