]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - doc/informe_2da_entrega.lyx
506a3df6a412742d588475313dfa4ee8f661ff1e
[z.facultad/75.06/emufs.git] / doc / informe_2da_entrega.lyx
1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
2 \lyxformat 221
3 \textclass book
4 \language spanish
5 \inputencoding auto
6 \fontscheme palatino
7 \graphics default
8 \paperfontsize default
9 \spacing single 
10 \papersize a4paper
11 \paperpackage widemarginsa4
12 \use_geometry 0
13 \use_amsmath 0
14 \use_natbib 0
15 \use_numerical_citations 0
16 \paperorientation portrait
17 \secnumdepth 3
18 \tocdepth 3
19 \paragraph_separation indent
20 \defskip medskip
21 \quotes_language english
22 \quotes_times 2
23 \papercolumns 1
24 \papersides 1
25 \paperpagestyle default
26
27 \layout Title
28
29 Organización de Datos (75.06)
30 \newline 
31 Trabajo Práctico
32 \newline 
33 E
34 \begin_inset Formula $\mu$
35 \end_inset 
36
37 FS
38 \layout Author
39
40
41 \series bold 
42 Grupo 11
43 \series default 
44
45 \newline 
46 Nicolás Dimov (77624)
47 \newline 
48 Alan Kennedy (78907)
49 \newline 
50 Leandro Lucarella (77891)
51 \newline 
52 Ricardo Markiewicz (78226)
53 \layout Date
54
55 Segunda Entrega, 31 de Mayo de 2004
56 \layout Standard
57
58
59 \begin_inset LatexCommand \tableofcontents{}
60
61 \end_inset 
62
63
64 \layout Chapter
65
66 Introducción
67 \layout Standard
68
69 En esta entrega el trabajo estuvo concentrado en el manejo de índices para
70  los tipos de archivos implementados en la primer entrega.
71  Los índices se implementaron con:
72 \layout Enumerate
73
74 Árbol B
75 \layout Enumerate
76
77 Árbol B*
78 \layout Enumerate
79
80 Árbol B+
81 \layout Standard
82
83 Además de esto, se pide 3 funciones distintas para estos índices:
84 \layout Enumerate
85
86 Principal
87 \layout Enumerate
88
89 Selectivo
90 \layout Enumerate
91
92 Exhaustivo
93 \layout Standard
94
95 Con la autorización de los ayudantes de la cátedra decidimos que el árbol
96  B+ sólo pueda ser utilizado para índices principal ya que de otra manera
97  no tiene sentido el set secuencial.
98 \layout Standard
99
100 Finalmente, para obtener listados basados en campos de los cuales no se
101  tiene un índice, se implementó un ordenamiento externo.
102 \layout Standard
103
104 A continuación se presenta una descripción un poco más detallada sobre todas
105  herramientas utilizadas para resolver el trabajo práctico.
106 \layout Section
107
108 Documentación de la API
109 \layout Standard
110
111 Para obtener una documentación de la API más completa, se incluye en formato
112  HTML en el CD-ROM la documentación generado con Doxygen.
113  Esta documentación se encuentra en el directorio 
114 \family typewriter 
115 doc/api/html/index.html
116 \family default 
117 .
118 \layout Chapter
119
120 Estructura común
121 \layout Section
122
123 Tipos
124 \layout Standard
125
126 Se detallan a continuación los tipos de datos definidos y utilizados en
127  las distintas implementaciones que conforman nuestro sistema, siendo el
128  más importante de ellos en esta entrega, la estructura 
129 \family typewriter 
130 INDICE
131 \family default 
132  que actúa como interfaz común para el manejo de cualquier tipo de índice
133  (no importa que tipo de organización física ni de que forma esté implementado,
134  esta estructura proveerá una interfaz abstracta para su manejo).
135 \layout Subsection
136
137 Tipos Comunes
138 \layout Standard
139
140 Se agregaron varios tipos comunes nuevos en esta entrega, en su mayoría
141  relacionados a los índices.
142  Estos tipos son brevemente descriptos a continuación y pueden ser hallados
143  en el archivo 
144 \family typewriter 
145 indices.h
146 \family default 
147 :
148 \layout Itemize
149
150
151 \family typewriter 
152 INDICE_DATO
153 \family default 
154 : usado para representar el conjunto de un ID más su dato.
155 \layout Itemize
156
157
158 \family typewriter 
159 INDICE_TIPO
160 \family default 
161 : indica el tipo de índice (B, B* o B+).
162 \layout Itemize
163
164
165 \family typewriter 
166 INDICE_FUNCION
167 \family default 
168 : indica la función que cumple el índice (principal, selectivo o exhaustivo).
169 \layout Itemize
170
171
172 \family typewriter 
173 INDICE_TIPO_DATO
174 \family default 
175 : indica el tipo de dato que se usa como clave.
176 \layout Itemize
177
178
179 \family typewriter 
180 CLAVE
181 \family default 
182 : representa una clave de un índice.
183 \layout Subsection
184
185 INDICE
186 \layout Standard
187
188
189 \family typewriter 
190 INDICE
191 \family default 
192 \emph on 
193  
194 \emph default 
195 es la estructura principal que encapsula todas las funciones para el manejo
196  de un índice.
197  Posee punteros a funciones que permite utilizar la misma interface para
198  distintas implementaciones de árboles.
199  
200 \layout Standard
201
202 Su declaración puede ser observada en el archivo 
203 \family typewriter 
204 indices.h
205 \family default 
206 \series bold 
207  
208 \series default 
209 y cuenta con la siguiente información:
210 \layout Itemize
211
212 Tipo de índice.
213 \layout Itemize
214
215 Tipo de dato que maneja.
216 \layout Itemize
217
218 Función del índice.
219 \layout Itemize
220
221 Información sobre el desplazamiento para ubicar el dato dentro de la estructura
222  a indexar (para poder tener una implementación genérica que sirva para
223  cualquier estructura).
224 \layout Itemize
225
226 Información sobre archivos auxiliares para almacenar cadenas de texto y
227  otras estructuras que eventualmente requiera un índice.
228 \layout Itemize
229
230 Punteros a funciones para:
231 \begin_deeper 
232 \layout Itemize
233
234 Agregar entrada.
235 \layout Itemize
236
237 Borrar entrada.
238 \layout Itemize
239
240 Verificar la existencia de una entrada.
241 \layout Itemize
242
243 Buscar entradas.
244 \layout Itemize
245
246 Obtener clave menor o mayor del índice.
247 \layout Itemize
248
249 Obtener siguiente clave (para recorrido secuencial).
250 \end_deeper 
251 \layout Standard
252
253 Esta estructura define los valores de sus punteros según el tipo de implementaci
254 ón que se desee manejar y esto se realiza a través de la API 
255 \family typewriter 
256 emufs_indice
257 \family default 
258 , implementada en 
259 \family typewriter 
260 indices.h
261 \family default 
262 .
263  Esta API posee funciones para crear y destruir índices, agregarlos y quitarlos
264  de una estructura 
265 \family typewriter 
266 EMUFS
267 \family default 
268 , comparar claves y otras, necesarias para la correcta y completa utilización
269  de los índices a través de la interfaz de 
270 \family typewriter 
271 EMUFS
272 \family default 
273  descripta en la entrega anterior.
274 \layout Subsubsection
275
276 Integración con 
277 \family typewriter 
278 EMUFS
279 \family default 
280 .
281 \layout Standard
282
283 Para integrar la utilización de índices a 
284 \family typewriter 
285 EMUFS
286 \family default 
287  fueron necesarios los siguientes cambios:
288 \layout Paragraph
289
290 Nuevos tipos de archivo.
291 \layout Standard
292
293 Se incluyen dos tipos de archivo nuevos T4 y T5, que representan, respectivament
294 e, un archivo T1 (registros variables, bloques fijos) y un archivo T3 (registros
295  y bloques fijos), ambos organizados como un set secuencial indexado.
296  De esta manera se conserva la interfaz de 
297 \family typewriter 
298 EMUFS
299 \family default 
300  (los punteros a funciones) incluso cuando se debe insertar de forma ordenada,
301  ya que al saber que es T4 o T5 siempre se inserta de forma ordenada.
302 \layout Paragraph
303
304 Puntero a un arreglo de índices.
305 \layout Standard
306
307 Se agrega a la estructura 
308 \family typewriter 
309 EMUFS
310 \family default 
311  un puntero a un arreglo de 
312 \family typewriter 
313 INDICE
314 \family default 
315 , donde el primero es siempre el índice principal.
316 \layout Chapter
317
318 Especificaciones de índices
319 \layout Section
320
321 Indice B
322 \layout Section
323
324 Indice B*
325 \layout Subsection
326
327 Desiciones de diseño
328 \layout Standard
329
330 Una de las pocas desiciones que tuvimos que tomar fue la forma de manejar
331  el nodo raíz.
332  Hay dos formas comunes de hacerlo:
333 \layout Enumerate
334
335 Permitir que el nodo raíz pueda almacenar 2N+1 claves (siendo N el número
336  máximo de claves permitido por nodo).
337 \layout Enumerate
338
339 Hacer que se comporte como un árbol B.
340 \layout Standard
341
342 La primera forma garantiza un mejor aprovechamiento del espacio, ya que
343  se sigue haciendo una partición en 3 nodos hijo con 2/3 de los espacios
344  llenos.
345  El problema que encontramos para hacerlo de esa forma fue que usamos un
346  tamaño de nodo fijo de 512 para poder leer un sector completo del disco
347  y ganar algo de velocidad, por lo que para poder mantener este esquema
348  hubieramos necesitado de 3 bloques de 512 para poder guardar los 2N+1 claves,
349  desperdiciando 512-tamaño_de_clave espacio en el bloque final y haciendo
350  que cualquier ahorro de espacio en los hijos del nodo raíz difícilmente
351  lo compense.
352 \layout Standard
353
354 Ademas de esto, el utilizar la segunda forma trae como ventaja la reutilización
355  de código del árbol B, lo que facilita la implementación y el mantenimiento
356  del código.
357 \layout Standard
358
359 Estas son las dos razones principales por las cuales elegimos tratar el
360  nodo raíz como lo hace el árbol B.
361 \layout Section
362
363 Indice B+ Secuencial Indexado
364 \layout Standard
365
366 Se ha implementado un índice secuencial indexado utilizando un árbol B+,
367  el cual tiene la particularidad de tener en sus hojas todas las claves
368  que se han insertado.
369 \layout Standard
370
371 La estructura de un nodo del árbol es la siguiente:
372 \layout Itemize
373
374 Nivel
375 \layout Itemize
376
377 Cantidad de claves
378 \layout Itemize
379
380 Arreglo de claves
381 \layout Itemize
382
383 Arreglo de hijos
384 \layout Standard
385
386 Esta estructura se encuentra en el archivo 
387 \family typewriter 
388 indice_bplus.h
389 \layout Standard
390
391 Esta organización permite, con la ayuda del árbol, mantener el archivo de
392  datos ordenado por la clave principal.
393 \layout Standard
394
395 Para lograr esto, el árbol nos indicará donde (en qué bloque) debe insertarse
396  un registro.
397  (ver 3.3.1 Inserción)
398 \layout Standard
399
400 En el caso de una hoja, dado que cada nodo posee un hijo mas que la cantidad
401  de claves, el hijo que sobra será utilizado como referencia al nodo 
402 \begin_inset Quotes eld
403 \end_inset 
404
405 hermano
406 \begin_inset Quotes erd
407 \end_inset 
408
409 , lo cual constituye el 
410 \begin_inset Quotes eld
411 \end_inset 
412
413 set secuencial
414 \begin_inset Quotes erd
415 \end_inset 
416
417  del índice.
418  Para un nodo que no sea hoja el hijo será el número de nodo correspondiente
419  según la clave, es decir, para la clave 
420 \series bold 
421 \emph on 
422
423 \series default 
424 \emph default 
425 el hijo 
426 \series bold 
427 \emph on 
428 n
429 \series default 
430 \emph default 
431  contiene claves menores y el hijo 
432 \series bold 
433 \emph on 
434 n+1
435 \series default 
436 \emph default 
437  contiene las claves mayores.
438  En el caso particular del nivel 1 el hijo 
439 \series bold 
440 \emph on 
441 n+1
442 \series default 
443 \emph default 
444  contiene las claves mayores o iguales ya que el 
445 \begin_inset Quotes eld
446 \end_inset 
447
448 secuence set
449 \begin_inset Quotes erd
450 \end_inset 
451
452  debe contener todas las claves insertadas, esto produce que exista una
453  repetición de las claves entre el nivel 1 y el 0.
454 \layout Standard
455
456 En nuestro caso hemos implementado un Secuencial Indexado tipo ISAM (Indexed
457  Sequential Access Method) el cual posee en sus hojas las anclas de cada
458  bloque en el archivo de datos, es decir, solo se guardan en los nodos del
459  arbol la menor de las claves de un bloque del archivo de datos, acompañada
460  cada clave por el numero de bloque al cual pertenece.
461 \layout Subsection
462
463 Inserción
464 \layout Standard
465
466 Para realizar una inserción en el archivo de datos se debe realizar una
467  consulta en el árbol, la cual nos indicará el número de bloque donde debemos
468  insertar el nuevo registro.
469 \layout Standard
470
471 Las consultas se realizan a través de una estructura INDEX_DAT que posee:
472 \layout Itemize
473
474 Clave
475 \layout Itemize
476
477 Número de Bloque 
478 \layout Standard
479
480 Esta estructura se encuentra en el archivo 
481 \family typewriter 
482 indice_bplus.h
483 \layout Standard
484
485 El modo de uso es el siguiente:
486 \layout Standard
487
488 En primer lugar se carga la clave a insertar en el campo Clave, y en el
489  campo Número de Bloque se almacena un número de bloque válido, mas adelante
490  se explica el por qué.
491 \layout Standard
492
493 Luego se invoca a la función 
494 \family typewriter 
495 int emufs_b_plus_get_bloque(INDICE, INDEX_DAT) 
496 \family default 
497 la cual recibe como parámetro una estructura de índice y un INDEX_DAT para
498  realizar la consulta.
499 \layout Standard
500
501 Esta función recorre recursivamente el árbol y busca una clave mayor inmediata
502  a la enviada, siempre culminando la búsqueda en una hoja.
503  Al encontrar la clave mayor inmediata, el resultado de la búsqueda será
504  la clave anterior en el nodo, pues cada clave en el nodo es un ancla de
505  bloque de datos, de esta manera la clave anterior será menor a la clave
506  enviada, pues las claves en las hojas estan ordenadas.
507  
508 \layout Standard
509
510 En este paso pueden suceder dos cosas:
511 \layout Enumerate
512
513 Que exista una clave menor a la enviada.
514 \layout Enumerate
515
516 Que la clave enviada sea menor a todas las claves del árbol.
517 \layout Standard
518
519 En el primer caso, se ha encontrado la clave y se carga la estructura con
520  el hijo de esa clave, que será el número de bloque donde debe insertarse
521  el nuevo registro (por el cual se realizó la consulta), sobreescribiendo
522  el valor que almacenaba al ingresar, y la función retornará código 0 que
523  indica que se ha encontrado un bloque donde insertar.
524 \layout Standard
525
526 En el segundo caso, puede darse que la clave enviada sea menor a todas las
527  claves del árbol, por lo cual no es posible encontrar un ancla de bloque
528  para esa clave.
529  Aquí la función retornará código -1 lo cual indica que no se ha encontrado
530  un bloque donde insertar el registro nuevo, y es por esto que la estructura
531  debe inicializarse con un número de bloque válido antes de realizarse la
532  consulta.
533 \layout Chapter
534
535 Ordenamiento Externo
536 \layout Section
537
538 Descripción del algoritmo
539 \layout Standard
540
541 Luego de buscar varias alternativas sobre algoritmos de ordenamiento externo,
542  se optó por el siguiente (que resultó una mezcla de las alternativas analizadas
543 ):
544 \layout Enumerate
545
546 Tomar uno a uno los registros del archivo a ordenar e 
547 \emph on 
548 inyectarlos
549 \emph default 
550  en un buffer ordenado hasta llenar el buffer.
551 \layout Enumerate
552
553 Quitar el menor de los valores (
554 \emph on 
555 inyectando
556 \emph default 
557  uno nuevo desde el archivo a ordenar) e insertarlo en un archivo temporal.
558 \layout Enumerate
559
560 Quitar del buffer el mínimo valor mayor al último insertado en el archivo
561  temporal (
562 \emph on 
563 inyectando
564 \emph default 
565  nuevamente un registro obtenido del archivo a ordenar) y se lo inserta
566  en el archivo temporal.
567  De esta forma quedan ordenados los registros en el archivo temporal.
568 \layout Enumerate
569
570 Repetir el paso 3 hasta que se vacíe el buffer o hasta que no haya ningún
571  valor mayor al último insertado en el archivo temporal.
572  Cuando esto suceda se crea un nuevo archivo temporal volviendo al paso
573  2.
574 \layout Standard
575
576 En este punto ya tenemos el buffer vacío y todos los valores del archivo
577  a ordenar repartidos en 1 o más archivos temporales ordenados, sólo queda
578  unir los archivos para volver a un sólo archivo completo y ordenado.
579  El procedimiento es simple:
580 \layout Enumerate
581
582 Obtener el mínimo valor de los archivos temporales e insertarlo en el archivo
583  ordenado de salida.
584 \layout Enumerate
585
586 Repetir 1 hasta agotar los registros de todos los archivos temporales.
587 \layout Standard
588
589 Debe quedar claro que los archivos temporales se comportan como una cola.
590  Es decir que al obtener un registro de un archivo temporal se obtiene el
591  primer registro que se haya insertado (el mínimo por la forma en la que
592  fueron insertados).
593 \layout Subsection
594
595 Ejemplo
596 \layout Standard
597
598 A continuación se presenta un ejemplo para una más fácil comprensión del
599  algoritmo.
600 \layout Standard
601
602 Supongamos que queremos ordenar un archivo con registros de números enteros
603  (el archivo se lee de izquierda a derecha): 9 6 34 2 8 3 12 43 23 4 19
604  21 87 1 16 36 42 65
605 \layout Standard
606
607 Supongamos que disponemos de un buffer capaz de almacenar 3 registros.
608 \layout Paragraph
609
610 Se llena el buffer ordenado
611 \layout Standard
612
613 Se lee 9 del archivo original y se lo inserta en el buffer ordenado.
614  Buffer: 9
615 \layout Standard
616
617 Se lee 6 del archivo original y se lo inserta en el buffer ordenado.
618  Buffer: 6 9
619 \layout Standard
620
621 Se lee 34 del archivo original y se lo inserta en el buffer ordenado.
622  Buffer: 6 9 34
623 \layout Paragraph
624
625 Se crea el archivo temporal ordenado 1
626 \layout Standard
627
628 Se lee el mínimo valor del buffer (6), se lo inserta en el archivo temporal
629  y se carga un nuevo valor del archivo original al buffer (2).
630  Buffer: 2 9 34.
631  Archivo1: 6
632 \layout Standard
633
634 Se lee el mínimo valor del buffer mayor al insertado anteriormente (9),
635  se lo inserta en el archivo temporal y se carga un nuevo valor del archivo
636  original al buffer (8).
637  Buffer: 2 8 34.
638  Archivo1: 6 9
639 \layout Standard
640
641 Se lee el mínimo valor del buffer mayor al insertado anteriormente (34),
642  se lo inserta en el archivo temporal y se carga un nuevo valor del archivo
643  original al buffer (3).
644  Buffer: 2 3 8.
645  Archivo1: 6 9 34
646 \layout Standard
647
648 No hay más valores en el buffer mayores al último insertado (34), fin del
649  Archivo1.
650 \layout Paragraph
651
652 Se crea el archivo temporal ordenado 2
653 \layout Standard
654
655 Se lee el mínimo valor del buffer (2), se lo inserta en el archivo temporal
656  y se carga un nuevo valor del archivo original al buffer (12).
657  Buffer: 3 8 12.
658  Archivo2: 2
659 \layout Standard
660
661 Se lee el mínimo valor del buffer mayor al insertado anteriormente (3),
662  se lo inserta en el archivo temporal y se carga un nuevo valor del archivo
663  original al buffer (43).
664  Buffer: 8 12 43.
665  Archivo2: 2 3
666 \layout Standard
667
668 Se lee el mínimo valor del buffer mayor al insertado anteriormente (8),
669  se lo inserta en el archivo temporal y se carga un nuevo valor del archivo
670  original al buffer (23).
671  Buffer: 12 23 43.
672  Archivo2: 2 3 8
673 \layout Standard
674
675 Se lee el mínimo valor del buffer mayor al insertado anteriormente (12),
676  se lo inserta en el archivo temporal y se carga un nuevo valor del archivo
677  original al buffer (4).
678  Buffer: 4 23 43.
679  Archivo2: 2 3 8 12
680 \layout Standard
681
682 Se lee el mínimo valor del buffer mayor al insertado anteriormente (23),
683  se lo inserta en el archivo temporal y se carga un nuevo valor del archivo
684  original al buffer (19).
685  Buffer: 4 19 43.
686  Archivo2: 2 3 8 12 23
687 \layout Standard
688
689 Se lee el mínimo valor del buffer mayor al insertado anteriormente (43),
690  se lo inserta en el archivo temporal y se carga un nuevo valor del archivo
691  original al buffer (21).
692  Buffer: 4 19 21.
693  Archivo2: 2 3 8 12 23 43
694 \layout Standard
695
696 No hay más valores en el buffer mayores al último insertado (43), fin del
697  Archivo2.
698 \layout Paragraph
699
700 Se crea el archivo temporal ordenado 3
701 \layout Standard
702
703 Se repite el proceso anterior.
704  Buffer: 1 16 36.
705  Archivo3: 4 19 21 87
706 \layout Paragraph
707
708 Se crea el archivo temporal ordenado 4
709 \layout Standard
710
711 Se repite el proceso anterior.
712  Buffer: .
713  Archivo4: 1 16 36 42 65
714 \layout Paragraph
715
716 Se mezclan los archivos temporales ordenados obteniendo un archivo completo
717  ordenado
718 \layout Standard
719
720 Se obtiene el menor valor de los archivos temporales ordenados (sólo tenemos
721  que elegir entre el primer valor de cada uno).
722 \layout Standard
723
724 Archivo1: 6 9 34.
725  Archivo2: 2 3 8 12 23 43.
726  Archivo3: 4 19 21 87.
727  Archivo4: 1 16 36 42 65
728 \layout Standard
729
730 Sólo debo comparar y obtener el menor entre 6, 2, 4, y 1.
731  Obtengo el 1, lo saco del archivo temporal y lo agrego al de salida:
732 \layout Standard
733
734 Archivo1: 6 9 34.
735  Archivo2: 2 3 8 12 23 43.
736  Archivo3: 4 19 21 87.
737  Archivo4: 16 36 42 65 Salida: 1
738 \layout Standard
739
740 Repito hasta que no hayan más valores en los archivos temporales:
741 \layout Standard
742
743 Archivo1: 6 9 34.
744  Archivo2: 3 8 12 23 43.
745  Archivo3: 4 19 21 87.
746  Archivo4: 16 36 42 65.
747  Salida: 1 2
748 \layout Standard
749
750 Archivo1: 6 9 34.
751  Archivo2: 8 12 23 43.
752  Archivo3: 4 19 21 87.
753  Archivo4: 16 36 42 65.
754  Salida: 1 2 3
755 \layout Standard
756
757 Archivo1: 6 9 34.
758  Archivo2: 8 12 23 43.
759  Archivo3: 19 21 87.
760  Archivo4: 16 36 42 65.
761  Salida: 1 2 3 4
762 \layout Standard
763
764 Archivo1: 6 9 34.
765  Archivo2: 8 12 23 43.
766  Archivo3: 19 21 87.
767  Archivo4: 16 36 42 65.
768  Salida: 1 2 3 4
769 \layout Standard
770
771 Archivo1: 9 34.
772  Archivo2: 8 12 23 43.
773  Archivo3: 19 21 87.
774  Archivo4: 16 36 42 65.
775  Salida: 1 2 3 4 6
776 \layout Standard
777
778 Archivo1: 9 34.
779  Archivo2: 12 23 43.
780  Archivo3: 19 21 87.
781  Archivo4: 16 36 42 65.
782  Salida: 1 2 3 4 6 8
783 \layout Standard
784
785 Archivo1: 34.
786  Archivo2: 12 23 43.
787  Archivo3: 19 21 87.
788  Archivo4: 16 36 42 65.
789  Salida: 1 2 3 4 6 8 9
790 \layout Standard
791
792 Archivo1: 34.
793  Archivo2: 23 43.
794  Archivo3: 19 21 87.
795  Archivo4: 16 36 42 65.
796  Salida: 1 2 3 4 6 8 9 12
797 \layout Standard
798
799 Archivo1: 34.
800  Archivo2: 23 43.
801  Archivo3: 19 21 87.
802  Archivo4: 36 42 65.
803  Salida: 1 2 3 4 6 8 9 12 16
804 \layout Standard
805
806 Archivo1: 34.
807  Archivo2: 23 43.
808  Archivo3: 21 87.
809  Archivo4: 36 42 65.
810  Salida: 1 2 3 4 6 8 9 12 16 19
811 \layout Standard
812
813 Archivo1: 34.
814  Archivo2: 23 43.
815  Archivo3: 87.
816  Archivo4: 36 42 65.
817  Salida: 1 2 3 4 6 8 9 12 16 19 21
818 \layout Standard
819
820 Archivo1: 34.
821  Archivo2: 43.
822  Archivo3: 87.
823  Archivo4: 36 42 65.
824  Salida: 1 2 3 4 6 8 9 12 16 19 21 23
825 \layout Standard
826
827 Archivo1:.
828  Archivo2: 43.
829  Archivo3: 87.
830  Archivo4: 36 42 65.
831  Salida: 1 2 3 4 6 8 9 12 16 19 21 23 34
832 \layout Standard
833
834 Archivo1:.
835  Archivo2: 43.
836  Archivo3: 87.
837  Archivo4: 42 65.
838  Salida: 1 2 3 4 6 8 9 12 16 19 21 23 34 36
839 \layout Standard
840
841 Archivo1:.
842  Archivo2: 43.
843  Archivo3: 87.
844  Archivo4: 65.
845  Salida: 1 2 3 4 6 8 9 12 16 19 21 23 34 36 42
846 \layout Standard
847
848 Archivo1:.
849  Archivo2:.
850  Archivo3: 87.
851  Archivo4: 65.
852  Salida: 1 2 3 4 6 8 9 12 16 19 21 23 34 36 42 43
853 \layout Standard
854
855 Archivo1:.
856  Archivo2:.
857  Archivo3: 87.
858  Archivo4:.
859  Salida: 1 2 3 4 6 8 9 12 16 19 21 23 34 36 42 43 65
860 \layout Standard
861
862 Archivo1:.
863  Archivo2:.
864  Archivo3:.
865  Archivo4:.
866  Salida: 1 2 3 4 6 8 9 12 16 19 21 23 34 36 42 43 65 87
867 \layout Paragraph
868
869 Fin
870 \layout Standard
871
872 Finalmente, tengo en el archivo de salida el archivo original ordenado.
873 \layout Section
874
875 Alcance
876 \layout Standard
877
878 El algoritmo de ordenamiento es completamente genérico, ya que recibe un
879  puntero void como registro, su tamaño (para poder manipularlo sin conocer
880  su tipo) y una función de comparación, para poder comparar dos registros
881  (sin saber su tipo) a través de una relación de órden (descripta por dicha
882  función).
883 \layout Section
884
885 Desiciones de diseño.
886 \layout Standard
887
888 El algoritmo se eligió en base a una serie de razones y cuenta con una serie
889  de ventajas y desventajas.
890 \layout Itemize
891
892 El algoritmo es simple, tanto teóricamente como para implementar.
893 \layout Itemize
894
895 Tiene la desventaja de que puede llegar a usar muchos archivos temporales
896  y todos abiertos al mismo tiempo, pero considerando que el sistema operativo
897  en el que se utiliza suele manejar bien grandes cantidades de archivos
898  no es una desventaja importante.
899 \layout Itemize
900
901 Al usar un buffer intermedio, se puede controlar muy bien la cantidad de
902  memoria que utiliza y experimentar con distintos valores para analizar
903  los resultados.
904 \layout Itemize
905
906 El buffer ordenado se implementó con un árbol binario debido a que tiene
907  una buena relación entre velocidad de búsqueda y facilidad de implementación.
908  Al ser el principal determinante de la velocidad los accesos a disco no
909  se creyo necesario buscar una alternativa más rapida para mantener el buffer
910  ordenado en memoria, ya que no cambiaría de forma notable el tiempo total
911  del algoritmo.
912  Otras posibilidades hubieran sido cargar todo el buffer en memoria y ordenarlo
913  posteriormente (dependiendo del algoritmo de ordenamiento a utilizar puede
914  ser más o menos rápido que el árbol y más o menos complicado de implementar)
915  o hacer una búsqueda secuencial sobre un buffer desordenado (es más fácil
916  de implementar pero claramente más lento).
917  Una posible ventaja notable de leer el buffer primero y luego ordenarlo
918  en memoria es que se necesita un sólo acceso al disco para llenar el buffer,
919  mientras que al obtener uno a uno los valores puede generar muchos accesos
920  a disco.
921  Esto no debería ser muy notable ya que las funciones de acceso a archivos
922  de la biblioteca estándar de C poseen un buffer interno, por lo que los
923  accesos a disco probablemente sea muy poco aún cuando se obtienen uno a
924  uno.
925 \the_end