#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;
}
{
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);
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);
#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);
int main(int argc, char* argv[])
{
+ MERGEFILE** mfpool = 0;
FILE* fp;
int i;
BUFFORD* b = bufford_new(8, sizeof(int), &cmp);
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;
}
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;
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);
}
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);
}