]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/external_sort/mergefile.c
Se termina el external sort. La interfaz ya es completamente genérica y pasó un
[z.facultad/75.06/emufs.git] / emufs / external_sort / mergefile.c
1 /* vim: set noexpandtab tabstop=4 shiftwidth=4 wrap:
2  *----------------------------------------------------------------------------
3  *                                  emufs
4  *----------------------------------------------------------------------------
5  * This file is part of emufs.
6  *
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
10  * version.
11  *
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
15  * details.
16  *
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 04:54:53 ART 2004
22  * Autores: Leandro Lucarella <llucare@fi.uba.ar>
23  *----------------------------------------------------------------------------
24  *
25  * $Id$
26  *
27  */
28
29 /** \file
30  *
31  * Archivo temporal con un fragmento ordenado del archivo original.
32  * 
33  * Implementación de un archivo temporal con un fragmento ordenado del archivo
34  * original utilizado para hacer el ordenamiento por fusión (merge sort).
35  *
36  */
37
38 #include "mergefile.h"
39 #include <malloc.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <assert.h>
43
44 MERGEFILE* mergefile_new(size_t reg_size)
45 {
46         MERGEFILE* mf;
47         assert(reg_size);
48         mf = malloc(sizeof(MERGEFILE));
49         if (!mf) {
50                 return 0;
51         }
52         /* abre archivo */
53         if (!(mf->fp = tmpfile())) {
54                 free(mf->next);
55                 free(mf);
56                 return 0;
57         }
58         mf->next = 0;
59         mf->reg_size = reg_size;
60         return mf;
61 }
62
63 void mergefile_delete(MERGEFILE* mf)
64 {
65         assert(mf);
66         assert(mf->fp);
67         fclose(mf->fp);
68         if (mf->next) free(mf->next);
69         free(mf);
70 }
71
72 int mergefile_switch_to_input(MERGEFILE* mf)
73 {
74         assert(mf);
75         assert(mf->fp);
76         assert(!mf->next);
77         /* retrocede al principio del archivo y obtiene el primer dato */
78         if (fseek(mf->fp, 0L, SEEK_SET)) return 0;
79         /* aloco memoria para el próximo */
80         if (!(mf->next = malloc(mf->reg_size))) return 0;
81         /* leo primer valor */
82         if (!fread(mf->next, mf->reg_size, 1, mf->fp)) {
83                 free(mf->next);
84                 mf->next = 0;
85         }
86         return 1; /* OK */
87 }
88
89 int mergefile_push(MERGEFILE* mf, void* data)
90 {
91         assert(mf);
92         assert(mf->fp);
93         return fwrite(data, mf->reg_size, 1, mf->fp);
94 }
95
96 void* mergefile_pop(MERGEFILE* mf)
97 {
98         void* ret;
99         assert(mf);
100         assert(mf->fp);
101         /* Si no hay más, devuelvo 0 */
102         if (!mf->next) return 0;
103         ret = mf->next;
104         /* aloco memoria para el próximo */
105         if (!(mf->next = malloc(mf->reg_size))) {
106                 mf->next = ret;
107                 return 0;
108         }
109         /* obtiene dato, si no hay más, se activa el flag */
110         if (!fread(mf->next, mf->reg_size, 1, mf->fp)) {
111                 free(mf->next);
112                 mf->next = 0;
113         }
114         return ret;
115 }
116
117 void* mergefile_peek(MERGEFILE* mf)
118 {
119         assert(mf);
120         assert(mf->fp);
121         return mf->next;
122 }
123
124 int mergefile_has_more(MERGEFILE* mf)
125 {
126         assert(mf);
127         assert(mf->fp);
128         return mf->next != 0;
129 }
130