From 5cb7b7129a77c6626097a4110ce23b07c624a92b Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Sun, 30 May 2004 07:40:25 +0000 Subject: [PATCH] Ejemplo de external sort andando aparentemente sin bugs. Falta generalizar un par de cosas y esta listo. --- emufs/external_sort/Makefile | 2 +- emufs/external_sort/bufford_test_sort.c | 43 ++++++++++++++++++------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/emufs/external_sort/Makefile b/emufs/external_sort/Makefile index 707dbc9..33ccead 100644 --- a/emufs/external_sort/Makefile +++ b/emufs/external_sort/Makefile @@ -12,7 +12,7 @@ TARGETS = s_ext bufford_test bufford_test_sort # Opciones para el compilador C. -CFLAGS = -Wall -ggdb -ansi -pedantic -DDEBUG +CFLAGS = -Wall -ggdb -DDEBUG # Opciones para el compilador C++. CXXFLAGS = $(CFLAGS) -fno-inline diff --git a/emufs/external_sort/bufford_test_sort.c b/emufs/external_sort/bufford_test_sort.c index b3c04f3..81b87f7 100644 --- a/emufs/external_sort/bufford_test_sort.c +++ b/emufs/external_sort/bufford_test_sort.c @@ -19,6 +19,7 @@ RECORD; typedef struct { FILE* fp; + char* filename; int next; int more; } @@ -26,13 +27,13 @@ MERGEFILE; char* mergefile_makefilename(int i) { - size_t size = sizeof(MERGEFILE_TEMPLATE) + 20; /* 20 más para el int */ + 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 += 20; + size += 8; new = realloc(filename, size); if (new) { filename = new; @@ -47,22 +48,24 @@ char* mergefile_makefilename(int i) MERGEFILE* mergefile_new(int i) { MERGEFILE* mf = malloc(sizeof(MERGEFILE)); - char* filename = mergefile_makefilename(i); - if (!mf || !filename) { + if (!mf) { + return 0; + } + /* asigno el nombre de archivo */ + if (!(mf->filename = mergefile_makefilename(i))) { free(mf); - free(filename); return 0; } /* abre archivo */ - mf->fp = fopen(filename, "rb"); - free(filename); - if (!mf->fp) { + 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); free(mf); return 0; } @@ -74,7 +77,10 @@ void mergefile_delete(MERGEFILE* mf) { assert(mf); assert(mf->fp); + assert(mf->filename); fclose(mf->fp); + remove(mf->filename); + free(mf->filename); free(mf); } @@ -95,7 +101,7 @@ int mergefile_pop_next(MERGEFILE* mf) ret = mf->next; /* obtiene dato, si no hay más, se activa el flag */ if (fscanf(mf->fp, "%i", &(mf->next)) <= 0) mf->more = 0; - return mf->next; + return ret; } int mergefile_has_more(MERGEFILE* mf) @@ -181,26 +187,39 @@ int main(int argc, char* argv[]) { 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); 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_pop_next(mfpool[n]); + min = mergefile_peek_next(mfpool[n]); + min_mf = mfpool[n]; + printf("min = %i\n", min); } } + printf("Iterando...\n"); while (1) { - int current; 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 */ /* 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])); + } else { + printf("Archivo %i: No hay más datos\n", n); + } if (mergefile_has_more(mfpool[n]) && (!assigned || mergefile_peek_next(mfpool[n]) < min)) { assigned = 1; - min = mergefile_pop_next(mfpool[n]); + min = mergefile_peek_next(mfpool[n]); + min_mf = mfpool[n]; + printf("min = %i\n", min); } } /* si no hay más datos en los archivos, salimos */ -- 2.43.0