]> git.llucax.com Git - z.facultad/75.06/emufs.git/commitdiff
Se amplia MERGEFILE para poder usarlo de salida tambien (al crear los chunks).
authorLeandro Lucarella <llucax@gmail.com>
Sun, 30 May 2004 09:01:41 +0000 (09:01 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Sun, 30 May 2004 09:01:41 +0000 (09:01 +0000)
Antes se podia usar solo para entrada (al hacer el merge). Gracias a esto ahora
se implementa usando tmpfile() para los archivos temporales.

emufs/external_sort/mergefile.c
emufs/external_sort/mergefile.h
emufs/external_sort/sort_test.c

index 2d59fb12b476bde7143a976c4484c003b5619b64..f5bf0b0a53da80673939409c167c71497950ab30 100644 (file)
 #include <string.h>
 #include <assert.h>
 
-char* mergefile_makefilename(int i)
-{
-       size_t size = sizeof(MERGEFILE_TEMPLATE) + 8; /* 8 más para el int */
-       char* filename = malloc(size);
-       if (!filename) return 0;
-       /* Hasta que me de la memoria para crear el nombre del archivo */
-       while (snprintf(filename, size, MERGEFILE_TEMPLATE, i) >= size) {
-               char* new;
-               size += 8;
-               new = realloc(filename, size);
-               if (new) {
-                       filename = new;
-               } else {
-                       free(filename);
-                       return 0;
-               }
-       }
-       return filename;
-}
-
-MERGEFILE* mergefile_new(int i)
+MERGEFILE* mergefile_new()
 {
        MERGEFILE* mf = malloc(sizeof(MERGEFILE));
        if (!mf) {
                return 0;
        }
-       /* asigno el nombre de archivo */
-       if (!(mf->filename = mergefile_makefilename(i))) {
-               free(mf);
-               return 0;
-       }
        /* abre archivo */
-       if (!(mf->fp = fopen(mf->filename, "rb"))) {
-               free(mf->filename);
-               free(mf);
-               return 0;
-       }
-       /* obtiene dato */
-       if (fscanf(mf->fp, "%i", &(mf->next)) <= 0) {
-               fclose(mf->fp);
-               free(mf->filename);
+       if (!(mf->fp = tmpfile())) {
                free(mf);
                return 0;
        }
-       mf->more = 1;
+       mf->more = 0;
        return mf;
 }
 
@@ -93,22 +60,27 @@ void mergefile_delete(MERGEFILE* mf)
 {
        assert(mf);
        assert(mf->fp);
-       assert(mf->filename);
        fclose(mf->fp);
-       remove(mf->filename);
-       free(mf->filename);
        free(mf);
 }
 
-int mergefile_peek_next(MERGEFILE* mf)
+int mergefile_switch_to_input(MERGEFILE* mf)
+{
+       /* obtiene dato, debe tener al menos uno para ser un mergefile */
+       if (fseek(mf->fp, 0L, SEEK_SET)) return 0;
+       if (fscanf(mf->fp, "%i", &(mf->next)) <= 0) return 0;
+       mf->more = 1;
+       return 1; /* OK */
+}
+
+int mergefile_push(MERGEFILE* mf, int data)
 {
        assert(mf);
        assert(mf->fp);
-       assert(mf->more);
-       return mf->next;
+       return fprintf(mf->fp, "%i\n", data);
 }
 
-int mergefile_pop_next(MERGEFILE* mf)
+int mergefile_pop(MERGEFILE* mf)
 {
        int ret;
        assert(mf);
@@ -120,6 +92,14 @@ int mergefile_pop_next(MERGEFILE* mf)
        return ret;
 }
 
+int mergefile_peek(MERGEFILE* mf)
+{
+       assert(mf);
+       assert(mf->fp);
+       assert(mf->more);
+       return mf->next;
+}
+
 int mergefile_has_more(MERGEFILE* mf)
 {
        assert(mf);
index 1183d14f1b700fab1c3ceadff5617feda6c81c50..44c5fdd7b381629f7212b3ce79f11b35974cb2be 100644 (file)
 
 #include <stdio.h>
 
-#define MERGEFILE_TEMPLATE "sorted_chunk.%i"
-
 typedef struct
 {
        FILE* fp;
-       char* filename;
        int   next;
        int   more;
 }
 MERGEFILE;
 
-char* mergefile_makefilename(int i);
-
-MERGEFILE* mergefile_new(int i);
+MERGEFILE* mergefile_new();
 
 void mergefile_delete(MERGEFILE* mf);
 
-int mergefile_peek_next(MERGEFILE* mf);
+int mergefile_switch_to_input(MERGEFILE* mf);
+
+int mergefile_push(MERGEFILE* mf, int data);
+
+int mergefile_pop(MERGEFILE* mf);
 
-int mergefile_pop_next(MERGEFILE* mf);
+int mergefile_peek(MERGEFILE* mf);
 
 int mergefile_has_more(MERGEFILE* mf);
 
index 65c653d467d10756d8cf24e9f475735e9941b2c0..234e571d09a8d6ff5e5b21c1181458ab32de6112 100644 (file)
@@ -35,6 +35,7 @@ void buffer_dump(BUFFORD* b)
 
 int main(int argc, char* argv[])
 {
+       MERGEFILE** mfpool = 0;
        FILE* fp;
        int i;
        BUFFORD* b = bufford_new(8, sizeof(int), &cmp);
@@ -57,11 +58,21 @@ int main(int argc, char* argv[])
        while (!bufford_empty(b)) {
                int* c;
                int x;
-               FILE* fpo;
-               char filename[32];
-               snprintf(filename, sizeof(filename), "sorted_chunk.%i", i);
-               if (!(fpo = fopen(filename, "w"))) {
+               MERGEFILE** mfpool_new = realloc(mfpool, sizeof(MERGEFILE) * (i+1));
+               if (!mfpool_new) {
+                       int j;
+                       for (j = 0; j < i; j++) mergefile_delete(mfpool[j]);
+                       free(mfpool);
+                       bufford_delete(b);
+                       return 3;
+               } else {
+                       mfpool = mfpool_new;
+               }
+               if (!(mfpool[i] = mergefile_new())) {
+                       int j;
                        fclose(fp);
+                       for (j = 0; j < i; j++) mergefile_delete(mfpool[j]);
+                       free(mfpool);
                        bufford_delete(b);
                        return 3;
                }
@@ -71,7 +82,9 @@ int main(int argc, char* argv[])
                        if (!feof(fp)) fscanf(fp, "%i", &x);
                        if (!feof(fp) && !bufford_push(b, &x)) {
                                /* ERROR: no se pudo insertar */
-                               fclose(fpo);
+                               int j;
+                               for (j = 0; j < i+1; j++) mergefile_delete(mfpool[j]);
+                               free(mfpool);
                                fclose(fp);
                                bufford_delete(b);
                                return 4;
@@ -79,29 +92,29 @@ int main(int argc, char* argv[])
                        x = *c;
                        free(c);
                        printf("%- 8i\t", x);
-                       fprintf(fpo, "%i\n", x);
+                       if (!mergefile_push(mfpool[i], x)) printf("No se pudo escribir en el mergefile %i\n", i);
                        buffer_dump(b);
                }
                printf("Lote %i finalizado!\n\n", i);
                i++;
-               fclose(fpo);
        }
        fclose(fp);
        /* Mezclo lotes */
        {
        int n, min;
-       MERGEFILE** mfpool = malloc(sizeof(MERGEFILE) * i);
        MERGEFILE* min_mf;
        FILE* fp = fopen("salida.txt", "w");
        assert(fp);
-       assert(mfpool);
        printf("Abriendo archivos y buscando mínimo...\n");
        for (n = 0; n < i; n++) {
-               mfpool[n] = mergefile_new(n);
+               if (!mergefile_switch_to_input(mfpool[n])) {
+                       printf("No se pudo pasar a modo entrada el mfpool %i.\n", n);
+                       return 15;
+               }
                assert(mfpool[n]);
-               printf("Archivo %i: leído = %i\n", n, mergefile_peek_next(mfpool[n]));
-               if (!n || mergefile_peek_next(mfpool[n]) < min) {
-                       min = mergefile_peek_next(mfpool[n]);
+               printf("Archivo %i: leído = %i\n", n, mergefile_peek(mfpool[n]));
+               if (!n || mergefile_peek(mfpool[n]) < min) {
+                       min = mergefile_peek(mfpool[n]);
                        min_mf = mfpool[n];
                        printf("min = %i\n", min);
                }
@@ -111,17 +124,17 @@ int main(int argc, char* argv[])
                int assigned = 0;
                /* guardo el mínimo en el archivo de salida */
                fprintf(fp, "%i\n", min);
-               mergefile_pop_next(min_mf); /* lo saco del archivo */
+               mergefile_pop(min_mf); /* lo saco del archivo */
                /* obtengo el próximo mínimo */
                for (n = 0; n < i; n++) {
                        if (mergefile_has_more(mfpool[n])) {
-                               printf("Archivo %i: leído = %i\n", n, mergefile_peek_next(mfpool[n]));
+                               printf("Archivo %i: leído = %i\n", n, mergefile_peek(mfpool[n]));
                        } else {
                                printf("Archivo %i: No hay más datos\n", n);
                        }
-                       if (mergefile_has_more(mfpool[n]) && (!assigned || mergefile_peek_next(mfpool[n]) < min)) {
+                       if (mergefile_has_more(mfpool[n]) && (!assigned || mergefile_peek(mfpool[n]) < min)) {
                                assigned = 1;
-                               min = mergefile_peek_next(mfpool[n]);
+                               min = mergefile_peek(mfpool[n]);
                                min_mf = mfpool[n];
                                printf("min = %i\n", min);
                        }