#include <string.h>
#include <assert.h>
+static int extsort_fill_buffer(BUFFORD* bo, size_t reg_size, FILE* fp);
+
+static int extsort_make_pool(BUFFORD* bo, MERGEPOOL* pool, size_t reg_size,
+ FILE* fp);
+
+static int extsort_merge_pool(MERGEPOOL* pool, size_t reg_size,
+ const char* filename);
+
int extsort(const char* filename, size_t buf_size, size_t reg_size,
CMP_FUNC cmp)
{
BUFFORD* bo;
MERGEPOOL* pool;
FILE* fp;
- void* min = 0;
- void* reg;
assert(filename);
assert(reg_size);
assert(buf_size);
assert(cmp);
- /* aloco registro de uso genérico */
- if (!(reg = malloc(reg_size))) {
- return 0; /* ERROR */
- }
/* creo buffer ordenado */
if (!(bo = bufford_new_bytes_size(buf_size, reg_size, cmp))) {
- free(reg);
return 0; /* ERROR */
}
/* creo pool de archivos temporales ordenados */
if (!(pool = mergepool_new(reg_size, cmp))) {
bufford_delete(bo);
- free(reg);
return 0; /* ERROR */
}
/* abro archivo a ordenar */
if (!(fp = fopen(filename, "r"))) {
mergepool_delete(pool);
bufford_delete(bo);
- free(reg);
return 0; /* ERROR */
}
/* lleno el buffer */
+ if (!extsort_fill_buffer(bo, reg_size, fp)) {
+ fclose(fp);
+ mergepool_delete(pool);
+ bufford_delete(bo);
+ return 0; /* ERROR */
+ }
+ /* creo archivos temporales ordenados usando el buffer */
+ if (!extsort_make_pool(bo, pool, reg_size, fp)) {
+ fclose(fp);
+ mergepool_delete(pool);
+ bufford_delete(bo);
+ return 0; /* ERROR */
+ }
+ fclose(fp);
+ /* Mezclo lotes */
+ if (!extsort_merge_pool(pool, reg_size,
+ new_filename ? new_filename : filename)) {
+ mergepool_delete(pool);
+ bufford_delete(bo);
+ return 0; /* ERROR */
+ }
+ mergepool_delete(pool);
+ bufford_delete(bo);
+ return 1; /* OK */
+}
+
+int extsort_fill_buffer(BUFFORD* bo, size_t reg_size, FILE* fp)
+{
+ void* reg;
+ /* aloco registro de uso genérico */
+ if (!(reg = malloc(reg_size))) {
+ return 0; /* ERROR */
+ }
while (!bufford_full(bo)) {
if (!fread(reg, reg_size, 1, fp)) {
break; /* EOF */
}
bufford_push(bo, reg);
}
- /* creo archivos temporales ordenados usando el buffer */
+ free(reg);
+ return 1; /* OK */
+}
+
+int extsort_make_pool(BUFFORD* bo, MERGEPOOL* pool, size_t reg_size, FILE* fp)
+{
+ void* reg;
+ /* aloco registro de uso genérico */
+ if (!(reg = malloc(reg_size))) {
+ return 0; /* ERROR */
+ }
while (!bufford_empty(bo)) {
void* tmp;
/* agrego un nuevo archivo temporal al pool */
if (!mergepool_add_file(pool)) {
- fclose(fp);
- mergepool_delete(pool);
- bufford_delete(bo);
free(reg);
return 0; /* ERROR */
}
/* si hay un valor en la entrada, lo inserto */
if (fread(reg, reg_size, 1, fp) && !bufford_push(bo, reg)) {
/* ERROR: no se pudo insertar */
- fclose(fp);
- mergepool_delete(pool);
- bufford_delete(bo);
free(reg);
return 0; /* ERROR */
}
free(tmp);
/* Agrego el dato al último archivo temporal */
if (!mergepool_append_data(pool, reg)) {
- fclose(fp);
- mergepool_delete(pool);
- bufford_delete(bo);
free(reg);
return 0; /* ERROR */
}
}
}
- fclose(fp);
free(reg);
- /* Mezclo lotes */
- if (!(fp = fopen(new_filename ? new_filename : filename, "w"))) {
- mergepool_delete(pool);
- bufford_delete(bo);
+ return 1;
+}
+
+int extsort_merge_pool(MERGEPOOL* pool, size_t reg_size, const char* filename)
+{
+ FILE* fp;
+ void* min = 0;
+ if (!(fp = fopen(filename, "w"))) {
+ return 0; /* ERROR */
}
/* obtengo próximo mínimo y lo guardo en el archivo de salida */
while ((min = mergepool_pop_min(pool))) {
}
/* libero todos los recursos */
fclose(fp);
- mergepool_delete(pool);
- bufford_delete(bo);
return 1; /* OK */
}