From b0233335e2cfb8623d7aad0d641d56e6842e93b5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicol=C3=A1s=20Dimov?= Date: Sat, 17 Apr 2004 04:10:36 +0000 Subject: [PATCH 1/1] Impelentacion de compactar terminada pero NO ESTA TESTEADA del todo.. 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. --- emufs/emufs.c | 16 ++++---- emufs/fsc.c | 100 +++++++++++++++++---------------------------- emufs/fsc.h | 2 +- emufs/tipo3.c | 58 +++++++++++++++++++++++++- emufs/tipo3.h | 1 + emufs/tipo3_main.c | 16 +++++--- 6 files changed, 114 insertions(+), 79 deletions(-) diff --git a/emufs/emufs.c b/emufs/emufs.c index 9f60c37..9a03441 100644 --- a/emufs/emufs.c +++ b/emufs/emufs.c @@ -142,16 +142,12 @@ EMUFS *emufs_crear(const char *filename, EMUFS_Tipo tipo, EMUFS_BLOCK_SIZE tam_b 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; @@ -170,6 +166,7 @@ EMUFS *emufs_crear(const char *filename, EMUFS_Tipo tipo, EMUFS_BLOCK_SIZE tam_b 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); @@ -244,6 +241,7 @@ EMUFS *emufs_abrir(const char *filename) 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; } diff --git a/emufs/fsc.c b/emufs/fsc.c index ffcad79..a76ca10 100644 --- a/emufs/fsc.c +++ b/emufs/fsc.c @@ -84,8 +84,7 @@ int emufs_fsc_agregar_gap(EMUFS *emu, EMUFS_OFFSET marker, EMUFS_FREE freespace) 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); @@ -117,42 +116,11 @@ int emufs_fsc_agregar_gap(EMUFS *emu, EMUFS_OFFSET marker, EMUFS_FREE freespace) /* 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); } @@ -406,31 +374,20 @@ int emufs_fsc_get_max_min_fs(EMUFS *emu, EMUFS_FREE *min, EMUFS_FREE *max) 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) @@ -447,13 +404,32 @@ 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; } diff --git a/emufs/fsc.h b/emufs/fsc.h index 27ee1cc..408bcb5 100644 --- a/emufs/fsc.h +++ b/emufs/fsc.h @@ -58,5 +58,5 @@ EMUFS_FREE emufs_fsc_get_fs(EMUFS *, EMUFS_BLOCK_ID); 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 */ diff --git a/emufs/tipo3.c b/emufs/tipo3.c index c287cb4..56954ff 100644 --- a/emufs/tipo3.c +++ b/emufs/tipo3.c @@ -54,6 +54,7 @@ void* emufs_tipo3_leer_registro(EMUFS *emu, EMUFS_REG_ID ID, 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; } @@ -144,15 +145,18 @@ EMUFS_REG_ID emufs_tipo3_grabar_registro(EMUFS *emu, void *ptr, EMUFS_REG_SIZE t 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*/ @@ -468,3 +472,53 @@ void* emufs_tipo3_leer_registro_raw(EMUFS *emu, EMUFS_REG_ID ID, EMUFS_REG_SIZE } 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); +} diff --git a/emufs/tipo3.h b/emufs/tipo3.h index 7c85555..43aad6a 100644 --- a/emufs/tipo3.h +++ b/emufs/tipo3.h @@ -70,4 +70,5 @@ EMUFS_Estadisticas emufs_tipo3_leer_estadisticas(EMUFS *); 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_ */ diff --git a/emufs/tipo3_main.c b/emufs/tipo3_main.c index 367bb7e..17a7b86 100644 --- a/emufs/tipo3_main.c +++ b/emufs/tipo3_main.c @@ -97,11 +97,11 @@ int main(int argc, char *argv[]) } 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); @@ -110,12 +110,18 @@ int main(int argc, char *argv[]) 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); -- 2.43.0