hice solo un par de pruebas.
En esta misma funcion tuve un quilombo con un fclose, que se me hace que es porque el archivo ya estaba cerrado, asi que lo saque y le dejo la tarea al sistema operativo :-P
me voy a poner a testear lo mas que pueda para despues empezar a documentar.
switch (tipo) {
case T1:
- /* Inicializa archivo (punteros a funciones, chequeos, etc). */
- if (emufs_tipo1_inicializar(efs)) {
- /* TODO ERROR */
- free(efs->nombre);
- free(efs);
- return NULL;
- }
+ /* Asigna punteros a funciones. */
+ /* TODO verificar que el tamaño de bloque sea como mínimo del
+ * tamaño de la cabecera de un registro + N */
+ emufs_tipo1_inicializar(efs);
- /* Guarda cabeceras propias.
- * FIXME esto me gustaria que vaya a inicializar() */
+ /* Guarda cabeceras propias. */
fwrite(&tam_bloque, sizeof(EMUFS_BLOCK_SIZE), 1, fp);
break;
efs->borrar_registro = emufs_tipo3_borrar_registro;
efs->leer_estadisticas = emufs_tipo3_leer_estadisticas;
efs->modificar_registro = emufs_tipo3_modificar_registro;
+ efs->compactar = emufs_tipo3_compactar;
/* Guarda cabeceras propias. */
fwrite(&tam_bloque, sizeof(EMUFS_BLOCK_SIZE), 1, fp);
fwrite(&tam_reg, sizeof(EMUFS_REG_SIZE), 1, fp);
efs->borrar_registro = emufs_tipo3_borrar_registro;
efs->leer_estadisticas = emufs_tipo3_leer_estadisticas;
efs->modificar_registro = emufs_tipo3_modificar_registro;
+ efs->compactar = emufs_tipo3_compactar;
break;
}
EMUFS_FSC gap_aux,gap_before,gap_after,gap_new;
char name_f_fsc[255];
EMUFS_REG_ID pos_gap_before = 0, pos_gap_after = 0;
- unsigned long source,destination,limit,file_size,reg_count = 0,cant_moved = 0;
- char found = 0;
+ unsigned long source,destination,file_size,reg_count = 0,cant_moved = 0;
strcpy(name_f_fsc,emu->nombre);
strcat(name_f_fsc, EMUFS_FSC_EXT);
/* Si no encontre gaps ni por delante ni por detras */
if ((gap_before.marker == -1) && (gap_after.marker == -1)) {
- /* Lo guardo ordenado donde deba ir */
+ /* Lo guardo en el archivo al final */
gap_new.marker = marker;
gap_new.freespace = freespace;
- /* Busco el gap que sucede a este */
- fseek(f_fsc,0,SEEK_SET);
- while (!feof(f_fsc)) {
- fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
- if (gap_aux.marker > gap_new.marker) {
- found = 1;
- break;
- }
- }
- if (found == 1) {
- /* Movemos todos los gaps desde el sucesor hasta el final, una pos adelante */
- limit = ftell(f_fsc) - sizeof(EMUFS_FSC);
- fseek(f_fsc,0,SEEK_END);
- reg_count = (ftell(f_fsc) - limit) / sizeof(EMUFS_FSC);
- source = ftell(f_fsc) - sizeof(EMUFS_FSC);
-
- while (cant_moved < reg_count)
- {
- fseek(f_fsc,source,SEEK_SET);
- fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
- fwrite(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
- source -= sizeof(EMUFS_FSC);
- ++cant_moved;
- }
- /* Agrego el nuevo registro */
- fseek(f_fsc,limit,SEEK_SET);
- fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
- }
- else {
- fseek(f_fsc,0,SEEK_END);
- fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
- }
-
+ fseek(f_fsc,0,SEEK_END);
+ fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
fclose(f_fsc);
}
strcpy(name_f_fsc,emu->nombre);
strcat(name_f_fsc, EMUFS_FSC_EXT);
+ *min = ULONG_MAX;
+ *max = 0;
if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
-
- /* Si el file esta vacio, devuelvo valores nulos */
- fseek(f_fsc,0,SEEK_END);
- if (ftell(f_fsc) == 0) {
- *min = 0;
- *max = 0;
- return 0;
- }
- else
- {
- /* Busco Min y Max */
- *min = ULONG_MAX;
- *max = 0;
- fseek(f_fsc,0,SEEK_SET);
- while ( !feof(f_fsc) ){
- if ( fread(®, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;
- if ( reg.freespace < *min )
- *min = reg.freespace;
- if ( reg.freespace > *max )
- *max = reg.freespace;
- }
- fclose(f_fsc);
- return 0;
+
+ while ( !feof(f_fsc) ){
+ fread(®, sizeof(EMUFS_FSC), 1, f_fsc);
+ if ( reg.freespace < *min )
+ *min = reg.freespace;
+ if ( reg.freespace > *max )
+ *max = reg.freespace;
}
+
+ fclose(f_fsc);
+ return 0;
}
EMUFS_FREE emufs_fsc_get_media_fs(EMUFS *emu)
if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
while ( !feof(f_fsc) ){
- if ( fread(®, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;
+ fread(®, sizeof(EMUFS_FSC), 1, f_fsc);
total_fs += reg.freespace;
++gap_count;
}
fclose(f_fsc);
+ return total_fs/gap_count;
+}
+
+int emufs_fsc_get_cant_bloques_vacios(EMUFS *emu)
+{
+ FILE *f_fsc;
+ EMUFS_FSC reg;
+ char name_f_fsc[255];
+ int cant=0;
- if (gap_count > 0) return total_fs/gap_count;
- else return 0;
+ strcpy(name_f_fsc,emu->nombre);
+ strcat(name_f_fsc, EMUFS_FSC_EXT);
+
+ if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
+ while ( !feof(f_fsc) ){
+ fread(®, sizeof(EMUFS_FSC), 1, f_fsc);
+ if ( reg.freespace == emu->tam_bloque )
+ cant++;
+ }
+
+ fclose(f_fsc);
+ return cant;
}
EMUFS_FREE emufs_fsc_get_total_fs(EMUFS *);
EMUFS_FREE emufs_fsc_get_media_fs(EMUFS *);
int emufs_fsc_get_max_min_fs(EMUFS *, EMUFS_FREE *, EMUFS_FREE *);
-
+int emufs_fsc_get_cant_bloques_vacios(EMUFS *emu);
#endif /* _EMUFS_FSC_H */
block = emufs_idx_buscar_registro(emu,ID); /*me devuelve el nro de bloque al que pertenece el registro*/
if ( block == EMUFS_NOT_FOUND ){
PERR("No se encontro el bloque");
+ *err = -1;
return NULL;
}
FILE *file;
char name_f[255];
char* bloque;
- int cant_bloques, resto, i=0;
+ int cant_bloques, resto, i=0, lugar;
strcpy(name_f,emu->nombre);
strcat(name_f,".dat");
cant_bloques = (emu->tam_reg / (emu->tam_bloque-sizeof(EMUFS_REG_ID))) + 1;
resto = emu->tam_bloque - sizeof(EMUFS_REG_ID);
+ lugar = emu->tam_reg - sizeof(EMUFS_REG_ID);
+ if ( emu->tam_bloque < emu->tam_reg - sizeof(EMUFS_REG_ID) )
+ lugar = emu->tam_bloque;
/* me devuelve el ID del bloque donde quepa un registro y el espacio libre en "fs"*/
- num_bloque = emufs_fsc_buscar_lugar(emu, emu->tam_reg+sizeof(EMUFS_REG_ID), &fs);
+ num_bloque = emufs_fsc_buscar_lugar(emu, lugar, &fs);
/*si no hay bloques con suficiente espacio creo un bloque nuevo */
if (num_bloque == -1) {
if ( (file = fopen(name_f,"a+"))==NULL ) return -1; /*ERROR*/
}
return bloque;
}
+
+void emufs_tipo3_compactar(EMUFS *emu)
+{
+ FILE *f;
+ EMUFS_REG_ID *tmp, max_id;
+ EMUFS_REG_SIZE size;
+ EMUFS_Estadisticas s;
+ char name[255];
+ char *reg;
+ int err=0, ID_aux, cant_bloques, i, bloques_vacios=0;
+
+ /* si el bloque es mas chico que el registro no hace falta compactar */
+ /*if( emu->tam_reg-sizeof(EMUFS_REG_ID) > emu->tam_bloque ) return; */
+
+ strcpy(name,emu->nombre);
+ strcat(name,".dat");
+
+ if ( (f=fopen(name,"r") == NULL) ){
+ PERR("No se pudo abrir el archivo");
+ return;
+ }
+ s = emufs_tipo3_leer_estadisticas(emu);
+ cant_bloques = s.cant_bloques;
+
+ /* si solo hay un bloque no hace falta compactar */
+ if ( cant_bloques == 0 ){
+ fclose(f);
+ return;
+ }
+ tmp = emufs_idx_get(emu, &max_id);
+ if (tmp) free(tmp);
+ for( i=0; i<=max_id; i++){
+ /* si el id no existe paso al siguiente*/
+ if ( emufs_idx_existe_id(emu, i) != 0 ) continue;
+ reg = emufs_tipo3_leer_registro(emu, i, &size, &err);
+ if (err){
+ PERR("No se pudo leer el registro");
+ fclose(f);
+ return;
+ }
+ emufs_tipo3_borrar_registro(emu, i);
+ ID_aux = emufs_tipo3_grabar_registro(emu, reg, emu->tam_reg, &err);
+ i++;
+ }
+ /*tengo que truncar el archivo*/
+ bloques_vacios = emufs_fsc_get_cant_bloques_vacios(emu)-1;
+ truncate(name, sizeof(EMUFS_Tipo)+sizeof(EMUFS_REG_SIZE)+sizeof(EMUFS_BLOCK_SIZE)+emu->tam_bloque*(cant_bloques-bloques_vacios));
+ /*fclose(f); problemas con el fclose FIXME!!!*/
+ free(reg);
+}
void* emufs_tipo3_leer_registro_raw(struct _emu_fs_t*, EMUFS_REG_ID, EMUFS_REG_SIZE*, int *);
+void emufs_tipo3_compactar(EMUFS *emu);
#endif /* _EMUFS_TIPO3_H_ */
}
ver_archivo_FS(fp);
printf("BORRANDO REGISTROS....\n");
- for (j=0; j<8; j++){
+ for (j=0; j<8; j+=2){
fp->borrar_registro(fp, v[j]);
printf("borrado : %d\n", v[j]);
}
- printf("GRABANDO REGISTROS....\n");
+/* printf("GRABANDO REGISTROS....\n");
v[0] = fp->grabar_registro(fp, a, 100, &err);
v[1] = fp->grabar_registro(fp, c, 100, &err);
v[2] = fp->grabar_registro(fp, d, 100, &err);
v[5] = fp->grabar_registro(fp, g, 100, &err);
v[6] = fp->grabar_registro(fp, h, 100, &err);
v[7] = fp->grabar_registro(fp, i, 100, &err);
- for (j=0; j<8; j++){
+*/
+ for (j=1; j<8; j+=2){
b_ptr = fp->leer_registro(fp, v[j], ®_size, &err);
printf("Recuperado : %s\n", b_ptr);
}
-
- free(b_ptr);
+ printf("COMPACTANDO........\n");
+ fp->compactar(fp);
+
+ /*s=fp->leer_estadisticas(fp);
+ printf("tam archivo: %d\ntam arch bytes: %d\ninfo control: %d\nmedia fs: %d\ntotal fs:%d\nmax fs: %d\nmin fs: %d\ncant bloques: %d\n",
+ s.tam_archivo, s.tam_archivo_bytes, s.info_control, s.media_fs, s.total_fs, s.max_fs, s.min_fs, s.cant_bloques);
+ free(b_ptr);*/
ver_archivo_FS(fp);
emufs_destruir(fp);