1 /* vim: set noexpandtab tabstop=4 shiftwidth=4:
2 *----------------------------------------------------------------------------
4 *----------------------------------------------------------------------------
5 * This file is part of emufs.
7 * emufs is free software; you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option) any later
12 * emufs is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along
18 * with emufs; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
20 *----------------------------------------------------------------------------
21 * Creado: dom may 30 07:48:10 ART 2004
22 * Autores: Leandro Lucarella <llucare@fi.uba.ar>
23 *----------------------------------------------------------------------------
25 * $Id: bufford.h 609 2004-05-30 10:14:21Z llucare $
31 * Algoritmo de ordenamiento externo.
33 * Implementación del algoritmo de ordenamiento externo.
39 #include "mergepool.h"
43 int extsort(const char* filename, size_t buf_size, size_t reg_size, CMP_FUNC cmp)
53 /* creo buffer ordenado */
54 if (!(b = bufford_new_bytes_size(buf_size, reg_size, cmp))) {
57 /* creo pool de archivos temporales ordenados */
58 if (!(pool = mergepool_new())) {
62 /* abro archivo a ordenar */
63 if (!(fp = fopen(filename, "r"))) {
64 mergepool_delete(pool);
71 if (fscanf(fp, "%i", ®) < 1) break; /* EOF */
72 if (!bufford_push(b, ®)) break; /* buffer lleno */
74 /* creo archivos temporales ordenados usando el buffer */
75 while (!bufford_empty(b)) {
78 /* agrego un nuevo archivo temporal al pool */
79 if (!mergepool_add_file(pool)) {
81 mergepool_delete(pool);
85 /* lleno el archivo temporal ordenadamente usando el buffer */
86 for (c = bufford_pop_min(b); c; c = bufford_pop_next(b, &x)) {
87 /* si hay un valor en la entrada, lo inserto */
88 if ((fscanf(fp, "%i", &x) > 0) && !bufford_push(b, &x)) {
89 /* ERROR: no se pudo insertar */
91 mergepool_delete(pool);
97 /* Agrego el dato al último archivo temporal */
98 if (!mergepool_append_data(pool, x)) {
100 mergepool_delete(pool);
102 return 0; /* ERROR */
108 if (!(fp = fopen(filename, "w"))) {
109 mergepool_delete(pool);
112 /* obtengo próximo mínimo y lo guardo en el archivo de salida */
113 while (mergepool_pop_min(pool, &min)) fprintf(fp, "%i\n", min);
114 /* libero todos los recursos */
116 mergepool_delete(pool);