]> git.llucax.com Git - z.facultad/75.06/emufs.git/commitdiff
Recompactacion Tipo 2 al 80%. Ya recompacta y toda la bola, lo unico que le falta...
authorAlan Kennedy <kennedya@3dgames.com.ar>
Fri, 16 Apr 2004 06:50:06 +0000 (06:50 +0000)
committerAlan Kennedy <kennedya@3dgames.com.ar>
Fri, 16 Apr 2004 06:50:06 +0000 (06:50 +0000)
emufs/fsc.c
emufs/tipo2.c
emufs/tipo2.h
emufs/tipo2_main.c

index 044ef3352d57e7a6a044da9a4a27165bf24b68a1..ffcad7943ba94acd2e942263ef05874a903a5359 100644 (file)
@@ -84,7 +84,8 @@ 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;
        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,file_size,reg_count = 0,cant_moved = 0;
+       unsigned long source,destination,limit,file_size,reg_count = 0,cant_moved = 0;
+       char found = 0;
                
        strcpy(name_f_fsc,emu->nombre);
        strcat(name_f_fsc, EMUFS_FSC_EXT);
                
        strcpy(name_f_fsc,emu->nombre);
        strcat(name_f_fsc, EMUFS_FSC_EXT);
@@ -116,11 +117,42 @@ 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)) {
        
        /* Si no encontre gaps ni por delante ni por detras */
        if ((gap_before.marker == -1) && (gap_after.marker == -1)) {
-               /* Lo guardo en el archivo al final */
+               /* Lo guardo ordenado donde deba ir */
                gap_new.marker = marker;
                gap_new.freespace = freespace;
                gap_new.marker = marker;
                gap_new.freespace = freespace;
-               fseek(f_fsc,0,SEEK_END);
-               fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
+               /* 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);
+               }
+               
                fclose(f_fsc);          
        }
        
                fclose(f_fsc);          
        }
        
@@ -374,20 +406,31 @@ 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);
 
        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;
        if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
-       
-       while ( !feof(f_fsc) ){
-               fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc);
-               if (  reg.freespace < *min )
-                       *min = reg.freespace;
-               if ( reg.freespace > *max )
-                       *max = reg.freespace;
+               
+       /* 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(&reg, 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;               
        }
        }
-
-       fclose(f_fsc);
-       return 0;
 }
 
 EMUFS_FREE emufs_fsc_get_media_fs(EMUFS *emu)
 }
 
 EMUFS_FREE emufs_fsc_get_media_fs(EMUFS *emu)
@@ -404,11 +447,13 @@ 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 ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
        
        while ( !feof(f_fsc) ){
-               fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc);
+               if ( fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;           
                total_fs += reg.freespace;
                ++gap_count;
        }
 
        fclose(f_fsc);
                total_fs += reg.freespace;
                ++gap_count;
        }
 
        fclose(f_fsc);
-       return total_fs/gap_count;
+       
+       if (gap_count > 0) return total_fs/gap_count;
+       else return 0;
 }
 }
index e1bdf868cfd85493293ce8832e4ae4e728034aca..d424bf08714488107f9bc66a761cee921c49ab9e 100644 (file)
@@ -216,7 +216,7 @@ int emufs_tipo2_dummyfill(EMUFS *efs, EMUFS_OFFSET reg_pos, EMUFS_REG_SIZE amoun
        strcpy(name_f,efs->nombre);
        strcat(name_f,".dat");
 
        strcpy(name_f,efs->nombre);
        strcat(name_f,".dat");
 
-    if ((f_data = fopen(name_f,"r+")) == NULL) return -1; /* ERROR */
+    if ((f_data = fopen(name_f,"rb+")) == NULL) return -1; /* ERROR */
        
        /* Preparo el garbage y se lo tiro encima */
        fill_size = amount+sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE);
        
        /* Preparo el garbage y se lo tiro encima */
        fill_size = amount+sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE);
@@ -302,3 +302,123 @@ EMUFS_Estadisticas emufs_tipo2_leer_estadisticas(EMUFS *efs)
        
        return(stats);  
 }
        
        return(stats);  
 }
+
+/* Recompila y devuelve ciertas estadisticas del archivo indicado */
+int emufs_tipo2_recompactar(EMUFS *efs)
+{
+       char name_fdat[255],name_ffsc[255];
+       FILE *datfile;
+       FILE *fscfile;
+       EMUFS_FSC reg1,reg2;
+       unsigned long cant_gaps = 0,mustmove_bytes = 0,source = 0,
+                                 destination = 0,datsize = 0,totalfsc = 0;
+       
+       strcpy(name_fdat,efs->nombre);
+       strcpy(name_ffsc,efs->nombre);
+       strcat(name_fdat,".dat");
+       strcat(name_ffsc,EMUFS_FSC_EXT);
+       
+       /* Obtengo el tamanio del .dat */
+       if ( (datfile = fopen(name_fdat,"rb+")) == NULL){
+                       PERR("No se pudo abrir el archivo");
+                       return -1;      
+       }
+       fseek(datfile,0,SEEK_END);
+       datsize = ftell(datfile);
+       
+       /* Obtengo la cantidad de gaps */
+       if ( (fscfile = fopen(name_ffsc,"rb")) == NULL){
+                       PERR("No se pudo abrir el archivo");
+                       return -1;      
+       }
+       fseek(fscfile,0,SEEK_END);
+       cant_gaps = ftell(fscfile)/sizeof(EMUFS_FSC);
+       
+       if (cant_gaps == 0) return 0;
+       if (cant_gaps == 1) {
+               /* Un solo gap, muevo toda la data luego del gap y trunco */
+               fseek(fscfile,0,SEEK_SET);
+               fread(&reg1,sizeof(EMUFS_FSC),1,fscfile);       
+               source = reg1.marker + reg1.freespace;
+               destination = reg1.marker;
+               mustmove_bytes = datsize - source;
+               /*printf("Para recompactar, must move: %lu bytes\n",mustmove_bytes);
+               printf("Will move from: %lu  to  %lu\n",source,destination);*/
+               emufs_tipo2_movedata(datfile,&source,&destination,mustmove_bytes);
+       }
+       if (cant_gaps > 1)
+       {
+               /* Comienzo leyendo un gap */
+               fseek(fscfile,0,SEEK_SET);
+               fread(&reg1,sizeof(EMUFS_FSC),1,fscfile);
+               destination = reg1.marker;
+               --cant_gaps;
+               
+               while (cant_gaps > 0)
+               {
+                       /* El source siempre sera el fin del anteultimo gap leido */
+                       source = reg1.marker + reg1.freespace;
+                       /* Leemos otro gap para calcular cuanto debemos mover */
+                       fread(&reg2,sizeof(EMUFS_FSC),1,fscfile);
+                       mustmove_bytes = reg2.marker - source;
+                       /*printf("Para recompactar, must move: %lu bytes\n",mustmove_bytes);
+                       printf("Will move from: %lu  to  %lu\n",source,destination);*/
+                       emufs_tipo2_movedata(datfile,&source,&destination,mustmove_bytes);
+                       /* Guardo el nuevo destino que es donde termino de mover */
+                       destination = ftell(datfile);
+                       /* El ultimo gap leido, pasa a ser el de referencia ahora */
+                       reg1.marker = reg2.marker;
+                       reg1.freespace = reg2.freespace;
+                       --cant_gaps;
+               }
+               
+               /* Realizo el movimiento del ultimo chunk de datos */
+               source = reg1.marker + reg1.freespace;
+               mustmove_bytes = datsize - source;
+               emufs_tipo2_movedata(datfile,&source,&destination,mustmove_bytes);
+       }
+               
+       fclose(datfile);
+       fclose(fscfile);
+       
+       /* Trunco el dat para que no quede el espacio vacio al final */
+       totalfsc = emufs_fsc_get_total_fs(efs);
+       truncate(name_fdat,datsize - totalfsc);
+       truncate(name_ffsc,0);
+       return 0;
+}
+
+void emufs_tipo2_movedata(FILE *datfile,EMUFS_OFFSET *source, EMUFS_OFFSET *destination, EMUFS_BLOCK_SIZE mustmove_bytes)
+{
+    int chunksize = 9;
+       char *chunk = malloc(chunksize*sizeof(char));
+       unsigned long cant_chunks = 0,left_chunk = 0;
+       
+       /* Obtengo cuantos bloques de a CHUNKSIZE bytes debo mover. Si la cantidad es no entera */
+       cant_chunks = floor(mustmove_bytes/chunksize);
+       left_chunk = fmod(mustmove_bytes,chunksize);
+       
+       /*printf ("Cantidad de chunk de %i bytes movidos: %lu\n",chunksize,cant_chunks);
+       printf ("Left chunk movido fue de: %lu bytes\n",left_chunk);*/
+       
+       while(cant_chunks > 0)
+       {
+               fseek(datfile,*source,SEEK_SET);
+               fread(chunk,chunksize,1,datfile);
+               fseek(datfile,*destination,SEEK_SET);
+               fwrite(chunk,chunksize,1,datfile);
+               *source += chunksize;
+               *destination += chunksize;              
+               --cant_chunks;
+       }
+       
+       if (left_chunk > 0)
+       {
+               fseek(datfile,*source,SEEK_SET);
+               fread(chunk,left_chunk,1,datfile);
+               fseek(datfile,*destination,SEEK_SET);
+               fwrite(chunk,left_chunk,1,datfile);
+       }
+       
+       free(chunk);
+}
index fb5d9f23ce46e52c1b698fb0d82cf622ed5a6b53..f3aad1e959faed3bec5577aef00e54b1a8c155bd 100644 (file)
@@ -58,6 +58,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <math.h>
 #include "emufs.h"
 
 /** Inicializa la estructura <em>EMUFS* efs</em> que recibe, asignando las funciones que permiten
 #include "emufs.h"
 
 /** Inicializa la estructura <em>EMUFS* efs</em> que recibe, asignando las funciones que permiten
@@ -126,4 +127,12 @@ EMUFS_REG_ID emufs_tipo2_modificar_registro(EMUFS *efs, EMUFS_REG_ID id, void *d
  */
 EMUFS_Estadisticas emufs_tipo2_leer_estadisticas(EMUFS *efs);
 
  */
 EMUFS_Estadisticas emufs_tipo2_leer_estadisticas(EMUFS *efs);
 
+/** Método para recompactar un archivo tipo 2
+ *
+ * \param efs Estructura que realiza el handling de archivos de cualquier tipo.
+ * \return \b int Indicador de exito de la opracion.
+ */
+int emufs_tipo2_recompactar(EMUFS *efs);
+void emufs_tipo2_movedata(FILE * datfile,EMUFS_OFFSET *source, EMUFS_OFFSET *destination, EMUFS_BLOCK_SIZE mustmove_bytes);
+
 #endif /* _EMUFS_TIPO2_H_ */
 #endif /* _EMUFS_TIPO2_H_ */
index b830069da75504659e11f5fc9e3e116814920eb4..ae03f7c547363c29ff4fb1303025bc4c91ec840a 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
 
 #include <stdio.h>
 #include <string.h>
+#include <math.h>
 #include "emufs.h"
 #include "fsc.h"
 #include "emufs.h"
 #include "fsc.h"
+#include "tipo2.h"
 
 int main(int argc, char *argv[])
 {
 
 int main(int argc, char *argv[])
 {
@@ -74,9 +76,10 @@ int main(int argc, char *argv[])
        n5 = efs->grabar_registro(efs, f, 9, &err);
        n6 = efs->grabar_registro(efs, g, 41, &err);
        n7 = efs->grabar_registro(efs, h, 63, &err);
        n5 = efs->grabar_registro(efs, f, 9, &err);
        n6 = efs->grabar_registro(efs, g, 41, &err);
        n7 = efs->grabar_registro(efs, h, 63, &err);
+       n8 = efs->grabar_registro(efs, d, 8, &err);
 
        /* Borramos un registro del medio */
 
        /* Borramos un registro del medio */
-       printf("tipo2_main.c >> Borrando registro: %lu\n",n5);
+       /*printf("tipo2_main.c >> Borrando registro: %lu\n",n5);
        efs->borrar_registro(efs, n5);          
        printf("tipo2_main.c >> Borrando registro: %lu\n",n1);
        efs->borrar_registro(efs, n1);
        efs->borrar_registro(efs, n5);          
        printf("tipo2_main.c >> Borrando registro: %lu\n",n1);
        efs->borrar_registro(efs, n1);
@@ -87,13 +90,15 @@ int main(int argc, char *argv[])
        printf("tipo2_main.c >> Borrando registro: %lu\n",n7);
        efs->borrar_registro(efs, n7);  
        printf("tipo2_main.c >> Borrando registro: %lu\n",n4);
        printf("tipo2_main.c >> Borrando registro: %lu\n",n7);
        efs->borrar_registro(efs, n7);  
        printf("tipo2_main.c >> Borrando registro: %lu\n",n4);
+       efs->borrar_registro(efs, n4);*/
+       
+       /* Prueba de recompactacion */
+       efs->borrar_registro(efs, n2);
+       efs->borrar_registro(efs, n7);
        efs->borrar_registro(efs, n4);
        efs->borrar_registro(efs, n4);
-         
-       n8 = efs->grabar_registro(efs, d, 8, &err);
-       printf("tipo2_main.c >> Id recuperado: %lu\n",n8);
-                       
+                               
        /* Levanto un registro */
        /* Levanto un registro */
-       registro = efs->leer_registro(efs,n2,&reg_size,&err);
+       registro = efs->leer_registro(efs,n1,&reg_size,&err);
        if (err == 0) {
                printf("tipo2_main.c >>Registro: %lu Size: %lu Content: %s\n\n",n2,reg_size,registro);
        }
        if (err == 0) {
                printf("tipo2_main.c >>Registro: %lu Size: %lu Content: %s\n\n",n2,reg_size,registro);
        }
@@ -108,6 +113,20 @@ int main(int argc, char *argv[])
        printf("Media de espacio libre en bloque o gap: %lu\n",stats.media_fs); 
        printf("Cantidad en bytes de informacion de control: %lu\n",stats.info_control);
        
        printf("Media de espacio libre en bloque o gap: %lu\n",stats.media_fs); 
        printf("Cantidad en bytes de informacion de control: %lu\n",stats.info_control);
        
+       /* Recompacto */
+       printf("Recompactando...\n");
+       emufs_tipo2_recompactar(efs);
+       
+       /* Obtengo stats nevas */
+       stats = efs->leer_estadisticas(efs);
+       printf("Size del Archivo de datos: %lu\n",stats.tam_archivo_bytes);
+       printf("Cantidad de Registros en el Archivo de datos: %lu\n",stats.tam_archivo);        
+       printf("Total de espacio libre en el .dat: %lu\n",stats.total_fs);
+       printf("Minimo espacio libre en bloque o gap: %lu\n",stats.min_fs);
+       printf("Maximo espacio libre en bloque o gap: %lu\n",stats.max_fs);     
+       printf("Media de espacio libre en bloque o gap: %lu\n",stats.media_fs); 
+       printf("Cantidad en bytes de informacion de control: %lu\n",stats.info_control);        
+       
        emufs_destruir(efs);    
        
        return 0;
        emufs_destruir(efs);    
        
        return 0;