1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
11 \paperpackage widemarginsa4
15 \use_numerical_citations 0
16 \paperorientation portrait
19 \paragraph_separation indent
21 \quotes_language english
25 \paperpagestyle default
29 Organización de Datos (75.06)
34 \begin_inset Formula $\mu$
50 Leandro Lucarella (77891)
52 Ricardo Markiewicz (78226)
55 Primera Entrega, 19 de Abril de 2004
59 \begin_inset LatexCommand \tableofcontents{}
69 Esta es la documentación correspondiente a las API`s para el manejo de tres
70 organizaciones de archivo diferentes.
71 A continuación se describe cada una de ellas y su modo de funcionamiento
72 y sus características principales.
73 De la correcta elección de la organización, dependerá la eficiencia de
74 la aplicación que la utilice.
78 EMUFS se presenta como un
86 , capaz de administrar datos almacenados en cualquiera de las tres organizacione
87 s de archivo previamente mencionadas, las cuales a saberse son:
90 Registros de Longitud Variable, Bloques de tamaño parametrizable
93 Registros de Longitud Variable, Sin Bloques
96 Registros de Longitud Fija, Bloques de tamaño parametrizables
99 A través de este trabajo, se podrán observar las diferencias entre distintos
100 tipos de organización de archivos, ventajas y desventajas de cada una de
101 ellas, y las situaciones particulares que deberá sortear un filesystem,
102 como la partición de registros en distintos bloques, manejo de espacio
103 libre, compactación de un archivo, etc.
106 A continuación, veremos que el manejo de los archivos en EMUFS se realiza
107 a través de una estructura de control común para cualquier tipo de archivo,
108 dándole flexibilidad y escalabilidad a nuestro sistema.
111 Hacia el final de esta presentación, se observaran las pruebas realizadas
112 con las distintas organizaciones de archivos, y las conclusiones obtenidos
122 Se detallan a continuación los tipos de datos definidos y utilizados en
123 las distintas implementaciones que conforman nuestro sistema, siendo el
124 más importante de ellos, la estructura
128 que actúa como interfaz común para el manejo de cualquier tipo de archivo
129 (no importa que tipo de organización física posea un archivo, esta estructura
130 proveerá una interfaz (funciones) para su manejo).
136 En la implementación de cada tipo de organización física, así como también
137 en las API de los archivos auxiliares comunes a ellas, se da la utilización
138 de tipo definidos para una clara interfaz entre las mismas, los cuales
139 son brevemente descriptos a continuación y pueden ser hallados en el archivo
151 : usado para representar un
162 : usado para representar el tamaño en bytes de un registro.
169 : usado para representar un número de bloque.
176 : usado para representar el tamaño en bytes de un bloque.
183 : usado para representar espacio libre en bytes.
190 : usado para representar un offset.
210 es la estructura principal que encapsula todas las funciones para el manejo
211 de un archivo de datos.
212 Posee punteros a funciones que dependiendo de la organización física por
213 la cual se opte dentro del sistema, serán asignados de acorde.
217 Su declaración puede ser observada en el archivo
221 y la misma cuenta con los siguiente campos:
228 que es un tipo enumerado que indica cual es la organización.
235 indica el tamaño del bloque para los tipos 1 y 3.
242 indica el tamaño del registro, para el tipo 3 que posee tamaño constante.
249 puntero a la función para leer un bloque.
254 void *leer_bloque_raw()
256 puntero a la función para leer un bloque, el anterior y el siguiente.
261 void **leer_registro()
263 puntero a la función para leer un registro.
268 void **leer_registro_raw()
270 puntero a la función para leer un registro con su encabezado.
275 EMUFS_REG_ID *grabar_registro()
277 puntero a la función para grabar un registro.
282 EMUFS_REG_ID *modificar_registro()
284 puntero a la función para modificar un registro.
289 int *borrar_registro()
291 puntero a la función para borrar un registro.
296 EMUFS_Estadisticas *leer_estadisticas()
298 puntero a la función para cargar una estructura con las estadísticas.
305 puntero a la función para compactar un archivo.
312 almacena el nombre del archivo sin extensión.
315 Esta estructura define los valores de sus punteros según el tipo de organización
316 que se desee manejar y esto se realiza a través del API emufs, implementado
321 , que se describirá posteriormente.
324 Por ejemplo si se desea crear un archivo de nombre
325 \begin_inset Quotes eld
329 \begin_inset Quotes erd
332 organizado de la forma 3, se invoca a la función:
337 emufs_crear(filename,tipo,tam_bloque,tam_reg),
343 es el nombre que tendrán los archivos de datos e índice,
347 es el tipo de organización - bloques parametrizados y registros constantes
352 es el tamaño del bloque, y
356 es el tamaño del registro.
359 Para las diferentes organizaciones puede ser que alguno de estos 2 últimos
360 valores no tengan sentido almacenarlas y tomaran un valor por defecto igual
364 Según el tipo de organización, se inicializan los punteros a las funciones.
371 emufs_tipo3_leer_bloque()
373 , y lo mismo sucede con los demás.
383 es un tipo de dato enum, el cual será utilizado en la cabecera de todo
388 ), para indicar los distintos tipos de organización física.
389 Su declaración puede verse en el archivo
394 A saberse los valores y significado correspondiente que puede tomar este
402 : Archivos con registros de longitud variable y bloques parametrizables.
409 : Archivos con registros de longitud variable sin bloques.
416 : Archivos con registros de longitud fija y bloques parametrizables.
426 es una estructura que almacenará los datos pertinentes a las estadísticas
427 de un archivo dado, y será utilizada para visualizar dichas observaciones
431 Su declaración puede ser observada en el archivo
435 y la misma cuenta con los siguiente campos:
446 : indica el tamaño del archivo de datos (.dat) en bytes.
457 : indica el tamaño de los archivos auxiliares sumados en bytes.
468 : indica la cantidad de bytes en información de control utilizados para
480 : promedio de espacio libre en el archivo de datos (por bloque o gap promedio
492 : total de espacio libre en el archivo de datos.
503 : máximo espacio libre en el archivo de datos (en un bloque o máximo gap
526 : cantidad de bloques en el archivo de datos (.
541 : cantidad de registros en el archivo de datos (
548 En base a la estructura descripta anteriormente y mediante la utilización
549 de la función de lectura de estadísticas
551 emufs_leer_estadisticas()
553 disponible en la estructura común
557 handler de cualquier tipo de archivo, podremos obtener una serie de estadística
558 s que pasamos a detallar (más allá de los datos básicos como cant registros,
559 cant bloques, tam archivo, etc):
562 Relación entre espacio libre y el tamaño del archivo de datos (
569 Relación entre el espacio ocupado por información de control y el tamaño
570 del archivo de datos (
577 Cantidad promedio de espacio libre (en bloque o gap promedio)
580 Desviaciones extremas de espacio libre (máximo/mínimo espacio libre en bloque
585 \begin_inset LatexCommand \label{sec:cabecera_gral}
589 Organización física general de un archivo E
590 \begin_inset Formula $\mu$
597 \begin_inset Formula $\mu$
600 FS está compuesto por 4 archivos a nivel de sistema operativo: archivo de
601 datos (con 3 formatos posibles, ver páginas
602 \begin_inset LatexCommand \pageref{cha:tipo1}
607 \begin_inset LatexCommand \pageref{cha:tipo2}
612 \begin_inset LatexCommand \pageref{cha:tipo3}
616 ), archivo de índice (ver página
617 \begin_inset LatexCommand \pageref{sec:idx}
621 ), archivo de control de espacio libre (ver página
622 \begin_inset LatexCommand \pageref{sec:fsc}
626 ) y archivo de índices recuperables (ver página
627 \begin_inset LatexCommand \pageref{sec:did}
634 El archivo de datos está compuesto por:
645 (4 bytes en plataformas Linux de 32 bits) que representa el tipo de archivo.
648 Datos dependientes del tipo de archivo.
655 es utilizada para poder detectar el formato de un archivo al abrirlo.
656 Los datos dependientes del tipo de archivo serán explicados en sus secciones
663 +-----------+--------------------------------------------//-+
666 | tipo | Datos dependientes del tipo de archivo ...
674 +-----------+--------------------------------------------//-+
680 Uso de la estructura EMUFS
683 Como fue mencionado anteriormente en la descripción de la estructura EMUFS,
684 la misma proporciona al usuario una interfaz a través de la cual puede
685 realizar el manejo de archivos en forma genérica, abstrayéndose del tipo
686 de organización física en particular que dicho archivo posea.
691 y las funciones que inicializan la estructura se encuentran en
696 Es decir que a través de esta estructura, podemos manejar cualquier tipo
697 de archivo, mediante una misma interfaz en común.
702 posee además de ciertos datos que describen la organización física de un
703 archivo dado como por ejemplo
721 , una serie de punteros a funciones para el manejo del archivo del cual
725 Entre dichos funciones se encuentran:
731 leer_bloque(), borrar_registro()
739 modificar_registro, leer_estadisticas()
746 Para entender mejor el uso de esta estructura para el manejo de los archivos,
747 mostraremos un ejemplo concreto.
748 Supongamos que tenemos el siguiente código:
751 EMUFS *efs = emufs_crear(¨articulos.dat¨,T3,200,50);
754 Esto hará que se cree el archivo de datos
758 , con la organización física tipo 3 con registros de longitud fija de 50
759 bytes y bloques de 200 bytes.
760 Al mismo tiempo, los se asignaran valores a los punteros a funciones que
761 posee dicha estructura, la cual de ahora en más estará en condiciones de
762 manejar un archivo del tipo 3.
763 Gráficamente lo que sucede es:
767 \begin_inset Float figure
774 Inicialización de estructura EMUFS para un caso Archivo Tipo 3
778 \begin_inset Graphics
779 filename graphics/Emufsinit.png
791 Así pues, cuando se utilice la estructura para por ejemplo leer un registro,
792 sucederá lo siguiente:
795 efs->leer_registro(params) -- calls --> emufs_tipo3_leer_registro(params)
798 Como se puede observar, la estructura
802 permitirá el manejo de cualquier tipo de archivo, a través del mismo código,
803 dándole gran flexibilidad a nuestro sistema, que podrá expandirse a más
804 tipos de archivos de ser necesario.
810 Acompañando al archivo de datos (
814 ) el cual es responsable de la contención de los registros, tendremos tres
815 archivos auxiliares (
827 ) cuya funcionalidad y propósito pasamos a describir a continuación, sin
828 antes remarcar que los tres archivos poseen una sola implementación para
829 las distintas formas de organización física que hemos implementado (tres
830 para ser mas exactos).
833 Entre las ventajas de poseer la misma implementación se encuentra el tener
834 un API común entre los tres tipos para el manejo de la localización de
835 sus registros, administración de espacio libre e Id's liberados, sin necesidad
836 de realizar n-implementaciones para un mismo objetivo final.
839 Además, la obtención de ciertos datos estadísticos como espacio libre, o
840 cantidad de registros, se realiza a través de la misma interfaz, y también
841 se ha facilitado en cierto grado la re-organización física de un archivo
842 (pasar de un tipo a otro), dado el uso de estos tres archivos auxiliares
843 en común para funciones tan predominantes como índexación, administración
844 de espacio libre y recuperación de Id's.
848 \begin_inset LatexCommand \label{sec:idx}
855 El archivo índice (.idx), permite la localización de los registros en el
856 .DAT de forma directa, mediante la obtención de su offset respecto del inicio
857 del .dat, o nro bloque (segun el tipo de organización física) en donde se
858 encuentra un registro dado, indicado por su
863 Los registros de este archivo se encuentran representados una estructura
864 que indica un número de registro y el bloque u offset en donde se encuentra
868 Es necesario que este archivo esté ordenado por
872 , ya que esto permitirá el acceso directo al mismo, para la rápida obtención
873 del nro de bloque u offset y posterior búsqueda de un registro en el archivo
880 Los registros de este archivo se encuentran representados a nivel código
881 por el siguiente tipo de dato interno (
888 typedef struct emufs_idx_t {
894 EMUFS_OFFSET location;
901 \begin_inset Float table
908 Ejemplo de registro en archivo índice (.idx), para un archivo de organización
914 <lyxtabular version="3" rows="2" columns="3">
916 <column alignment="center" valignment="top" leftline="true" width="0">
917 <column alignment="center" valignment="top" leftline="true" width="0">
918 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
919 <row topline="true" bottomline="true">
920 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
928 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
936 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
944 <row topline="true" bottomline="true">
945 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
953 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
961 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
966 Indica que el registro de id_reg = 5, se encuentra en el bloque 54
978 \begin_inset Float table
985 Ejemplo de registro en archivo índice (.idx), para un archivo de organización
991 <lyxtabular version="3" rows="2" columns="3">
993 <column alignment="center" valignment="top" leftline="true" width="0">
994 <column alignment="center" valignment="top" leftline="true" width="0">
995 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
996 <row topline="true" bottomline="true">
997 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1005 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1013 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1021 <row topline="true" bottomline="true">
1022 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1030 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1038 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1043 Indica que el registro de id_reg = 5, se encuentra en el bloque 54
1063 Como se puede observar, para distintas organizaciones el significado de
1064 los registros en este archivo es diferente y se utilizará de distinta manera
1071 Las declaraciones e implementación se pueden encontrar en
1085 \labelwidthstring 00.00.0000
1093 Los registros del archivo índice (
1097 ), poseen una correspondencia 1 a 1, con los Id's de los registros en el
1103 Con esto, queremos decir que el N-ésimo registro del archivo índice, será
1104 aquél que posea la información para localizar al registro cuyo
1108 es N, dentro del archivo de datos (
1118 Cabe aclarar que por si bien el índice se encuentra ordenado por
1122 , los registros en el archivo de datos, por lo general no lo estarán (ordenados
1128 emufs_idx_buscar_registro(), emufs_idx_get()
1130 \labelwidthstring 00.00.0000
1136 Ante la alta de un registro en el archivo de datos, se insetará un nuevo
1137 registro en el archivo índice, con el id_reg del registro en cuestión,
1138 y el offset u bloque donde se lo haya grabado en disco.
1144 \labelwidthstring 00.00.0000
1150 Ante el borrado de un registro del archivo de datos, se accederá el registro
1151 correspondiente en el índice, y se actualizara su LOCATION, estableciéndolo
1152 en el valor especial
1156 , el cual indica que ese registro ha sido eliminado y por ende no se lo
1157 podrá localizar en el futuro.
1158 Como se verá mas adelante, según el tipo de organización física, el registro
1159 puede ser borrado concretamente del .
1170 \labelwidthstring 00.00.0000
1176 Ante la modificación en la posición física de un registro dentro del archivo
1177 de datos (por ejemplo luego del proceso de re-compactación, se realizará
1178 la modificación respectiva del campo
1186 emufs_idx_actualizar()
1190 \begin_inset LatexCommand \label{sec:fsc}
1194 Archivo de control de espacio libre
1197 El archivo de espacio libre (
1201 ) (espacio por bloque o gaps en archivo, según el tipo de organización física),
1202 tiene como función la administración del espacio libre, generado por previas
1203 eliminaciones de registros en el archivo de datos.
1204 El mismo, nos indicará donde hay lugar para insertar un nuevo registro.
1207 Para el caso de una organización por bloque, nos dirá en que bloque o si
1208 se debe generar un nuevo bloque.
1209 En el caso de la organización sin bloques, nos indicará en que gap o si
1210 al final del archivo.
1213 Los registros de este archivo se encuentran representados una estructura
1214 que indica un número de bloque u offset y el espacio libre disponible en
1215 el mismo (o a partir del mismo en el caso del offset).
1222 : Por requerimiento del algoritmo de compactación el tipo de organización
1223 física con reg long var, sin bloques, los gaps se graban en forma ordenada
1225 (El orden se corresponde con lo que hay en el .dat).
1231 Los registros de este archivo se encuentran representados a nivel código
1232 por el siguiente tipo de dato interno (
1239 typedef struct emufs_fsc_t {
1242 EMUFS_BLOCK_ID marker;
1245 EMUFS_FREE freespace;
1255 \begin_inset Float table
1262 Ejemplo de registro en archivo de control de espacio libre para un archivo
1267 \begin_inset Tabular
1268 <lyxtabular version="3" rows="2" columns="3">
1270 <column alignment="center" valignment="top" leftline="true" width="0">
1271 <column alignment="center" valignment="top" leftline="true" width="0">
1272 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
1273 <row topline="true" bottomline="true">
1274 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1282 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1290 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1298 <row topline="true" bottomline="true">
1299 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1307 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1315 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1320 Indica que en el bloque 12, hay 120 bytes libres al final del mismo.
1332 \begin_inset Float table
1339 Ejemplo de registro en archivo de
1343 para un archivo sin bloques
1347 \begin_inset Tabular
1348 <lyxtabular version="3" rows="2" columns="3">
1350 <column alignment="center" valignment="top" leftline="true" width="0">
1351 <column alignment="center" valignment="top" leftline="true" width="0">
1352 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
1353 <row topline="true" bottomline="true">
1354 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1362 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1370 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1378 <row topline="true" bottomline="true">
1379 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1387 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1395 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1400 Indica que a partir del byte 12 del archivo de datos, hay 120 bytes libres.
1420 Como se puede observar, para distintas organizaciones el significado de
1421 los registros en este archivo es diferente y se utilizará de distinta manera
1425 Funciones principales
1428 Las declaraciones e implementación se pueden encontrar en
1442 \labelwidthstring 00.00.0000
1448 Ante la operación de alta de un registro en el archivo de datos, se realizará
1449 la búsqueda de espacio libre donde este podrá ser insertado.
1450 En el caso de organizaciones con bloques, se buscará en que
1454 se posee espacio suficiente para albergar el nuevo registro (o a partir
1463 bloques consecutivos libres).
1464 En el caso de organización sin bloque, se buscará un gap o espacio libre
1465 en el archivo, obteniéndose en consecuencia, el
1474 emufs_fsc_buscar_lugar(), emufs_fsc_buscar_n_lugares()
1476 \labelwidthstring 00.00.0000
1482 Luego de una operación de baja o alta de un registro en el archivo de datos
1487 ), incrementará o decrementará respectivamente el espacio libre en el archivo
1488 de datos, y esto deberá ser registrado, agregando un nuevo registro en
1489 el archivo de espacios libres (
1493 ) o bien modificándolo.
1497 En el caso de organizaciones con bloques, se actualizará el valor del espacio
1502 en el bloque (ya sea incrementándolo o decrementándolo) o bien se insertará
1503 un nuevo registro en caso de que se esté creando un nuevo bloque en el
1504 archivo de datos (en este caso no será debido a un alta o baja de registro
1505 como se mencionó al principio).
1509 Para el caso de organización sin bloques, en el caso de baja de un registro
1514 ) se insertará un nuevo registro en el
1518 dando cuenta de la aparición de un nuevo gap en el archivo de datos (
1522 ), y en caso de estar este lindante con otro gap, se realizará el merge
1524 (esto esta explicado más en profundidad en los casos particulares de organizaci
1525 ón física, registros variables sin bloques).
1526 Para el caso de una alta en el archivo de datos (
1530 ), el valor del gap donde se haya insertado se actualizará.
1535 emufs_fsc_agregar(), emufs_fsc_agregar_gap(), emufs_fsc_actualizar(), emufs_fsc_
1538 \labelwidthstring 00.00.0000
1544 : Únicamente para el caso de una organización que presente gaps en el archivo,
1545 se podrá dar a lugar la eliminación de un registro del archivo de espacios
1551 Esta situación tendrá efecto cuando se inserte un registro que entre perfecto
1552 en un gap disponible, y por ende el gap desaparecerá.
1556 emufs_fsc_borrar_gap()
1560 \begin_inset LatexCommand \label{sec:did}
1564 Archivo de id's recuperables
1567 El archivo de Id's liberado (
1571 ) llevará cuenta de aquellos Id's de registros (
1575 ) que ya no se encuentran siendo utilizados y fueron liberados por registros
1576 eliminados previamente.
1577 A través del mismo, se podrá realizar la reutilización de Id's ante la
1578 alta de nuevos registros.
1581 A nivel físico, este archivo poseerá una secuencia de datos del tipo EMUFS_REG_I
1582 D, y el comportamiento del sistema de recuperación de Id's será el de una
1584 Es decir, ante el requerimiento de un
1588 libre por una función del sistema como por ejemplo la alta de un nuevo
1589 registro, el API del archivo (
1593 ), obtendrá el último dato del mismo (el
1597 que fue liberado mas recientemente), y truncará el archivo eliminando el
1602 recuperado de la tabla.
1603 (LIFO, Last in First Out).
1609 Este archivo tiene registros de un solo campo,
1613 el cual simboliza al id que fue liberado en un proceso de baja de registros.
1616 Funciones principales
1619 Las declaraciones e implementación se pueden encontrar en
1633 \labelwidthstring 00.00.0000
1639 Ante la eliminación de un registro del archivo de datos (
1643 ) se procederá al agregado del correspondiente
1647 que fue liberado por dicha operación, al archivo
1661 \labelwidthstring 00.00.0000
1667 Cuando el sistema desee grabar un nuevo registro en el archivo de datos,
1672 disponible para el mismo.
1673 El sistema de administración de Id's libres, obtendrá el último
1677 que se guardó en el archivo (o se eliminó del archivo de datos), y truncará
1678 el archivo eliminándolo.
1686 emufs_did_get_last()
1690 \begin_inset LatexCommand \label{cha:tipo1}
1694 Archivo con bloques parametrizados y registros de longitud variable
1697 Este tipo de archivo tiene varias complicaciones, al tratarse de un punto
1699 \begin_inset LatexCommand \ref{cha:tipo2}
1704 \begin_inset LatexCommand \ref{cha:tipo3}
1708 (cuenta tanto con bloques como con registros variables), hereda los inconvenien
1709 tes (y ventajas) de ambos, más los propios.
1710 Al implementar este tipo de archivo se puso énfasis en la eficiencia mientras
1711 esta no comprometa la mantenibilidad del código, es por esto que en algunas
1712 circunstancias no se hace un uso óptimo del espacio.
1715 La implementación de este tipo de archivo puede ser encontrada en
1719 mientras que su interfaz pública está disponible en
1729 El archivo está compuesto por la
1734 \begin_inset LatexCommand \pageref{sec:cabecera_gral}
1739 El valor que toma en este tipo de archivo es 0 (o el valor simbólico
1748 Luego le sigue una cabecera propia del archivo (un
1752 , 4 bytes) que almacena el tamaño del bloque que usa el archivo.
1753 De esta manera, al abrir un archivo de este tipo no se necesita tener ninguna
1754 información sobre él.
1755 A esta cabecera le siguen cero o más bloques del tamaño fijo especificado
1756 en la cabecera antes mencionada.
1762 +-----------+-----------+------------------------//-+
1765 | tipo | tam_bloque| Cero o más bloques ...
1773 +-----------+-----------+------------------------//-+
1776 /- 4 bytes -/- 4 bytes -/
1779 Organización física de un bloque
1782 Cada bloque no guarda información en sí, sólo se comporta como un contenedor
1784 Esto no significa que un bloque no tenga utilidad, el bloque es utilizado
1785 para proveer un acceso semi-aleatorio a los registros.
1786 Para esto se utiliza el archivo de índice (ver página
1787 \begin_inset LatexCommand \ref{sec:idx}
1791 ), que almacena pares [identificador de registro, número de bloque].
1792 Para que sea suficiente este único índice para hallar un registro (siendo
1793 que puede haber más de un registro por bloque), es necesario
1795 alinear los registros a izquierda
1798 Esto significa que hay que asegurar que siempre los registros en un bloque
1799 se presenten de forma consecutiva, jamás permitiendo que haya un espacio
1800 libre entre registros (en un mismo bloque).
1803 Podemos ver un ejemplo de esto en forma gráfica:
1806 bloque N-1 | bloque N | bloque N+1
1809 /----------+------------+------------+---------------+-----------/
1814 | registro 1 | registro 2 | espacio libre |
1819 /----------+------------+------------+---------------+-----------/
1822 /------------- tamaño del bloque ---------/
1825 De esta forma, una vez obtenido el número de bloque, se pueda recorrer secuencia
1826 lmente hasta encontrar el registro deseado.
1827 A fin de llevar el conteo de espacio libre se utiliza el archivo de control
1828 de espacio libre (ver página
1829 \begin_inset LatexCommand \ref{sec:fsc}
1833 ), de forma tal que no sea necesario recorrer secuencialmente en busca de
1834 espacio libre al hacer una inserción.
1837 Puede darse un caso excepcional en el que un registro sea más grande que
1838 un bloque, en este caso el registro se almacenará en N bloques consecutivos
1839 (siendo N la cantidad de bloques que necesita el registro), ocupando completos
1840 los todos los bloques a excepción del último, en el que posteriormente
1841 se pueden agregar más registros.
1842 \layout Subsubsection
1845 \begin_inset LatexCommand \label{sub:tipo1_reg}
1849 Organización física de un registro.
1852 El registro es el que representa al dato realmente que se quiere almacenar.
1853 Para representar ese dato se necesita una determinada información de control,
1854 tanto para poder identificar el registro en un bloque (en búsquedas secuenciale
1855 s dentro del bloque) como para saber su longitud (dado que este tipo de
1856 archivo utiliza registros de tamaño variable).
1859 Siguiendo la metodología general de E
1860 \begin_inset Formula $\mu$
1863 FS, se optó por incluir esta información de control como una cabecera al
1864 comienzo del registro, siguiendo a esta los datos en sí.
1865 La cabecera está compuesta por un identificador (
1869 ) de registro (EMUFS_REG_ID, 4 bytes) seguido por el tamaño (
1873 ) del registros (EMUFS_REG_SIZE, 4 bytes).
1874 Podemos ver gráficamente como se se compone un registro:
1880 +-----------+-----------+------------------+
1883 | id | tamaño | datos ...
1887 +-----------+-----------+------------------+
1890 /- 4 bytes -/- 4 bytes -/- [tamaño] bytes -/
1891 \layout Subsubsection
1894 \begin_inset LatexCommand \label{sub:tipo1_reg_multi}
1898 Organización física de un registro más grande que un bloque (registro
1905 Puede darse el caso excepcional en que un registro sea de mayor longitud
1907 Al ser una situación excepcional, no siempre se resuelve de la forma más
1908 eficiente ni se minimiza el espacio ocupado por datos de control (como
1909 se dijo anteriormente, se prefirió conservar la simpleza del código, adoptando
1910 algoritmos generales aunque no sea de la forma más eficiente o maximizando
1911 el uso del espacio para no perjudicar la mantenibilidad).
1914 Para manejar un registro
1918 se optó por limitarlo a la siguiente estructura (suponiendo que el registro
1919 ocupa N bloques, con N > 1 y que un
1923 es una porción del registro que entra en un bloque):
1930 se almacenan en bloques completos consecutivos.
1933 El último fragmento se almacena al comienzo del bloque inmediatamente posterior
1937 Cada fragmento posee las cabeceras mencionadas en la sección
1938 \begin_inset LatexCommand \ref{sub:tipo1_reg}
1942 , cuyo contenido es el siguiente:
1950 se almacena el identificador único obtenido al hacer el alta.
1957 se almacena el tamaño del
1961 actual más los tamaños de los
1965 posteriores, quedando en el primer
1969 el tamaño completo del registro y en el último sólo el tamaño del
1977 Como puede observarse, la información de control en los
1981 intermedios puede ser redundante, pero se conserva para poder realizar
1982 algoritmos genéricos (que se basan en que al principio de un bloque, si
1983 no está vacío, hay una cabecera de un registro) y para facilitar chequeos
1984 de integridad del archivo.
1987 A continuación se presenta un ejemplo gráfico de un registro multibloque
1988 de 10 bytes (de contenido
1989 \begin_inset Quotes eld
1993 \begin_inset Quotes erd
1996 ) almacenado en un archivo con bloques de 12 bytes (4 para datos):
1999 | bloque 0 | bloque 1 | bloque 2
2002 +-------------------+-------------------+-------------------+-//-+
2005 | registro 0 - 1/3 | registro 0 - 2/3 | registro 0 - 3/3..|
2012 |+----+-----+------+|+----+-----+------+|+----+-----+----+..| // |
2015 || id | tam | datos||| id | tam | datos||| id | tam |dato|..|
2022 ||----+-----+------+||----+-----+------+||----+-----+----+..| // |
2025 || 0 | 10 | 1234 ||| 0 | 6 | 5678 ||| 0 | 2 | 90 |..|
2032 |+----+-----+------+|+----+-----+------+|+----+-----+----+..| // |
2035 +-------------------+-------------------+-------------------+-
2045 2 bytes libres al final del bloque 2
2048 Este es un ejemplo figurativo, ya que se puso como límite mínimo de tamaño
2049 de bloque 16 bytes (para que haya al menos la misma cantidad de espacio
2050 para datos que para información de control).
2051 Este límite mínimo ya roza lo absurdo (es muy ineficiente por la gran cantidad
2052 de accesos a disco que necesita).
2053 El límite físico es de 9 bytes (8 para información de control, 1 para datos).
2056 Funciones principales
2059 Las funciones principales son las necesarias para completar la estructura
2061 \begin_inset LatexCommand \pageref{sub:EMUFS}
2068 Lectura de registros
2071 Para leer un registro se hace uso del archivo de índice (ver página
2072 \begin_inset LatexCommand \pageref{sec:idx}
2076 ), obteniéndose el número de bloque en donde está almacenado el registro
2078 Una vez obtenido, se carga en memoria el bloque entero y se busca secuencialmen
2079 te en él (leyendo la cabecera de cada registro y salteando los datos) hasta
2080 encontrar el registro pedido.
2081 Una vez encontrado se lo copia y devuelve.
2084 Si se tratara de un registro
2089 \begin_inset LatexCommand \ref{sub:tipo1_reg_multi}
2093 ), se procede forma similar, sólo que se cargan en memoria uno a uno los
2094 bloques que componen el registro y se van copiando (y uniendo) los
2103 emufs_tipo1_leer_registro()
2109 Para realizar el alta de un registro, lo primero que se obtiene es un identifica
2110 dor, buscando primero en el archivo de identificadores recuperables (pág.
2112 \begin_inset LatexCommand \ref{sec:did}
2116 ) y de no haber ninguno, buscando el mayor identificador presente en el
2117 archivo de índice (pág.
2119 \begin_inset LatexCommand \ref{sec:idx}
2124 El paso siguiente es buscar un bloque con espacio libre suficiente como
2125 para almacenar el registro (y su cabecera) en el archivo de control de
2128 \begin_inset LatexCommand \ref{sec:fsc}
2132 ) y cargarlo completo en memoria.
2133 De no encontrarse, se crea un bloque nuevo al final de archivo.
2134 En el bloque cargado en memoria, se agrega el registro nuevo (con su cabecera)
2135 al comienzo del espacio libre (calculado a partir del tamaño del bloque
2136 y el espacio libre en bloque) y se lo graba en disco.
2137 Finalmente se agrega (o actualiza) el identificador al archivo índice y
2138 el espacio libre en el bloque.
2141 Si el registro ocupara más de un bloque (ver sección
2142 \begin_inset LatexCommand \ref{sub:tipo1_reg_multi}
2146 ), se buscan N bloques consecutivos (todos los que necesite el registro)
2147 absolutamente libres
2153 Incluso el último bloque debe estar absolutamente libre para cumplir con
2154 las condiciones presentadas en la sección
2155 \begin_inset LatexCommand \ref{sub:tipo1_reg_multi}
2162 y graba bloque a bloque cada
2166 del registro (con sus cabeceras intermedias), al último
2170 se lo trata de forma análoga a un registro
2175 Por cada bloque utilizado se actualiza el archivo de control de espacio
2181 emufs_tipo1_agregar_registro()
2187 Al eliminar un registro lo primero que se hace es actualizar los archivos
2188 de índice y de identificadores recuperables, poniendo como número de bloque
2193 y agregando el identificador del registro a borrar respectivamente.
2194 También se actualiza el archivo de control de espacio libre por cada bloque
2195 (en caso de ser más de uno, en registros
2199 , se actualizan todos los bloques) y se carga el bloque en memoria para
2202 alinear los datos a izquierda
2204 (en caso de ser un registro
2208 , esto se realiza sólo para el último bloque).
2209 Para alinear los datos, se recorre secuencialmente en bloque (leyendo la
2210 cabecera de cada registro y salteando los datos) hasta encontrar el registro
2212 Encontrado el registro, se copian todos los bytes que se encuentran entre
2213 el fin del registro a borrar y el fin del bloque, en el comienzo del bloque
2219 emufs_tipo1_borrar_registro()
2222 Modificación de registros
2225 Se optó por un algoritmo simple y general, que usa las funciones de alto
2226 nivel mencionadas hasta ahora.
2227 Simplemente borra el registro y vuelve a crearlo.
2228 Al recuperar el último identificador de registro borrado, nos aseguramos
2229 de que se mantenga el identificador del registro.
2234 emufs_tipo1_modificar_registro()
2237 Obtención de estadísticas
2240 Es una función bastante simple, con una única complicación que mencionaremos
2244 Para obtener las máximas desviaciones, cantidad total de espacio libre,
2245 cantidad de registros y tamaño de los archivos auxiliares se utilizan las
2246 funciones apropiadas de los archivos auxiliares (ver secciones
2247 \begin_inset LatexCommand \ref{sec:idx}
2252 \begin_inset LatexCommand \ref{sec:fsc}
2257 \begin_inset LatexCommand \ref{sec:did}
2264 Para obtener la cantidad de bloques se hace el siguiente calculo:
2267 cant_bloques = (tamaño_archivo_datos - tamaño_cabecera_archivo_datos)
2273 Hasta aquí no hay mayores inconvenientes.
2274 El problema se presenta para calcular el tamaño de la información de control
2275 utilizada por el archivo de datos; se utiliza el siguiente cálculo:
2278 tam_info_control_datos = tamaño_cabecera_archivo_datos
2281 + cant_registros * tamaño_cabecera_registro;
2284 Aunque a simple vista esto parece acertado, no contempla el caso de los
2290 \begin_inset LatexCommand \pageref{sub:tipo1_reg_multi}
2294 ), estos registros almacenan
2296 tamaño_cabecera_registro * N
2302 es la cantidad de bloques que ocupan.
2303 Salvar este caso sería muy costoso, porque habría que recorrer el archivo
2304 registro a registro,
2312 e ir contando todas las cabeceras de registro que aparecen (similar a lo
2313 que se hace en la compactación, ver sección
2314 \begin_inset LatexCommand \ref{sub:tipo1_compact}
2319 Al tratarse este de un caso excepcional, se optó por mantener la función
2320 simple ya que funciona bien en la mayoría de los casos.
2325 emufs_tipo1_leer_estadisticas()
2329 \begin_inset LatexCommand \label{sub:tipo1_compact}
2333 Compactación del archivo de datos
2336 Esta función es una de las más simples, porque se limita a un algoritmo
2337 muy simple que utiliza las funciones de
2341 antes nombradas para realizar su tarea.
2342 Básicamente recorre el archivo de índices de registros, de comienzo a fin,
2343 leyendo el registro, borrándolo y volviéndolo a insertar.
2344 Si había espacio libre en un bloque anterior al que estaba, será insertado
2345 en él, si no volverá a grabarse en el lugar en que estaba.
2346 De esta forma se aprovechan todos los espacios libres intermedios, concluyendo
2347 con un archivo igual o más pequeño que el original.
2350 Esta implementación no es la más eficiente, pero siendo que esta es una
2351 operación costosa y excepcional por naturaleza, se optó por mantener el
2352 algoritmo simple a costo de un poco de eficiencia.
2357 emufs_tipo1_compactar()
2360 Detalles de implementación (funciones internas, ver si lo ponemos o no)
2364 \begin_inset LatexCommand \label{cha:tipo2}
2368 Archivo sin bloques y registros de longitud variable
2371 Este tipo de archivo nos traerá a la mesa la particularidad de grabar registros
2372 de longitud variable sin realizar su agrupación en bloques, y como veremos
2373 en la siguiente sección, también permitirá la administración de gaps que
2374 queden en el archivo luego de operaciones de baja de registros.
2380 Este tipo de archivo realizará el almacenamiento de registros de longitud
2381 variable en disco, su borrado y modificación sin la utilización de bloques
2383 Su implementación se encuentra en los archivos fuente (
2394 Los archivos del tipo 2, presentarán al comienzo del mismo un header compuesto
2395 simplemente por un dato del tipo EMUFS_Tipo (int) el cual indicará el tipo
2396 de archivo en cuestión.
2399 Para poder entender mejor la organización física de este tipo de archivo,
2400 tomemos el caso hipotético en el que se encuentran grabados
2404 (comenzando desde registro 0) de
2413 Supongamos también que entre el registro 0 y 1 se encontraba un
2415 registro de 10 bytes
2430 Si miramos al archivo de datos (.dat) en el disco nos encontraremos con
2432 \begin_inset Float figure
2439 Organización física de los registros en disco
2443 \begin_inset Graphics
2444 filename graphics/Example1.png
2455 Como se puede observar, a nivel físico cada registro grabado esta compuesto
2456 por un Header cuyo tamaño total es de 8 bytes (
2464 ), y posteriormente el registro (bloque de datos) en sí.
2465 Luego se encuentra el espacio libre de 18 bytes dejado por el registro
2466 de 10 bytes eliminado (10 bytes de datos + header de 8 bytes) y finalmente
2467 el segundo registro mencionado.
2470 Comportamiento Particular de los Archivos Auxiliares
2473 Como fue explicado al inicio de la documentación, la implementación de cualquier
2474 a de las tres organizaciones físicas de archivos presenta la necesidad de
2475 poseer tres archivos auxiliares que actuarán como índice de direcciones
2480 ), administrador de espacio libre (
2484 ) y administrador de Id's liberados (
2491 No obstante, cada tipo de organización presentara sus particularidades respecto
2492 de estos tres archivos, las cuales describiremos a continuación en caso
2494 \layout Subsubsection
2496 Archivo índice o de posiciones relativas (.idx)
2503 ), permite la localización de los registros en el .DAT de forma directa,
2504 mediante la obtención de su offset o posición relativa respecto del inicio
2509 en donde se encuentra un registro dado, indicado por su ID.
2512 Así pues, si tomamos el ejemplo descripto al inicio de este capítulo, tendremos
2513 las siguientes entradas en el archivo índice
2518 \begin_inset Float table
2525 Organización física del archivo de índice o posiciones relativas.
2529 \begin_inset Tabular
2530 <lyxtabular version="3" rows="3" columns="3">
2532 <column alignment="center" valignment="top" leftline="true" width="0">
2533 <column alignment="center" valignment="top" leftline="true" width="0">
2534 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
2535 <row topline="true" bottomline="true">
2536 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2546 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2556 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
2564 <row topline="true">
2565 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2575 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2585 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
2590 El primer registro (reg0) comienza en el byte 4
2594 <row topline="true" bottomline="true">
2595 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2603 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2613 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
2618 El segundo registro (reg1) comienza en el byte 60
2638 LOCATION indica donde comienza el header del registro buscado, y por consiguien
2639 te luego del header tendremos el registro en sí (los datos).
2640 \layout Subsubsection
2642 Archivo de Gaps / Espacios Libres (.fsc)
2645 El archivo de espacios libres o gaps (.fsc), tiene como función la administración
2646 del espacio libre o gaps (agujeros), generados por previas eliminaciones
2647 de registros en el archivo de datos.
2648 El mismo, nos indicará donde hay lugar para insertar un nuevo registro
2649 (se podrán insertar en algún gap acorde, o bien al final del archivo).
2650 Este archivo será utilizado también para el proceso de compactación de
2651 un archivo, explicado luego.
2654 Así pues, si tomamos el ejemplo descripto al inicio del documento, tendremos
2655 las siguientes entradas en el archivo índice
2660 \begin_inset Float table
2667 Organización física del archivo de
2671 o control de espacio libre.
2675 \begin_inset Tabular
2676 <lyxtabular version="3" rows="2" columns="3">
2678 <column alignment="center" valignment="top" leftline="true" width="0">
2679 <column alignment="center" valignment="top" leftline="true" width="0">
2680 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
2681 <row topline="true" bottomline="true">
2682 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2692 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2702 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
2710 <row topline="true" bottomline="true">
2711 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2721 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2731 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
2736 18 bytes libres a partir del byte 42 del .dat
2756 Por requerimiento del algoritmo de compactación, los gaps se graban en
2757 forma ordenada en el (.fsc).
2758 (El orden se corresponde con lo que hay en el
2763 \layout Subsubsection*
2768 Si bien la utilización concreta de los GAPS será explicada posteriormente
2769 en la ALTA y BAJA de registros, debemos remarcar la funcionalidad de MERGING
2770 que posee nuestro sistema FSC.
2773 Ante la eliminación de un registro del archivo de datos, se generara por
2774 consiguiente un gap o espacio libre en alguna posición del archivo.
2775 Ese gap deberá ser registrado en el archivo de gaps (.fsc).
2776 Ahora bien, nuestro sistema de gaps, contemplará como es debido, la posibilidad
2777 de que se haya eliminado un registro que posee un GAP por delante, un GAP
2778 por detrás, o bien un GAP por delante y por detrás del mismo.
2781 Nuestro sistema actuará en consecuencia, realizando un merge de los espacios
2782 libres, y unificándolos en una ÚNICA entrada en el archivo .fsc, que contendrá
2783 como dato de freespace, la suma correspondiente de los espacios libres
2785 \layout Subsubsection
2787 Archivo de ID's liberados (.did)
2790 El archivo de ID's liberados no presenta ningún aspecto particular en este
2791 tipo de organización.
2792 Remitirse al capítulo correspondiente a los archivos auxiliares para consultar
2793 su estructura y funcionamiento.
2796 Funciones Principales
2811 se encuentran las cabeceras y la implementación de las funciones principales
2812 respectivamente, las cuales dan funcionalidad a esta organización.
2816 A continuación se comentará el funcionamiento algunas de las mas importantes.
2819 Lectura de registros
2822 Como se vio al comienzo, los registros en este tipo de archivo no se encuentran
2823 agrupados en bloques de ninguna índole y están dispersos a lo largo del
2824 archivo, con la particularidad de que pueden existir gaps o espacio libre,
2825 entre dos registros dados.
2828 Por ende la lectura de registros en este tipo de organización es muy simple
2829 y dada la inexistencia de bloques, el procedimiento será el siguiente:
2832 Se determina el offset en bytes, donde comienza el registro deseado, a través
2833 de su ID, buscando la misma en el archivo índice (
2840 Ya determinada la posición física del registro dentro del archivo de datos
2845 ), nos posicionamos en la misma, y leemos el header del registro (
2854 Contando así con el tamaño del registro, procedemos a leer el mismo (los
2855 datos), dando por finalizada la lectura.
2860 emufs_tipo2_leer_registro()
2866 En el proceso de alta de registros entrarán en juego dos archivos descriptos
2869 sección de archivos auxiliares
2871 , siendo estos el archivo índice (
2875 ), y el archivo de gaps / espacios libres (
2882 Así pues, a la hora de realizar una inserción de un registro en el archivo
2883 de datos, el procedimiento será el siguiente:
2886 Calculamos el espacio que necesitaremos para el registro: sizeof(
2894 ) + sizeof(registro).
2897 Determinamos donde debemos insertar el registro, ya sea un gap donde entre,
2898 o bien al final del archivo.
2901 Insertamos el registro e información de control (
2909 ), en la posición indicada en el paso 2.
2912 En caso de haber utilizado un GAP, actualizamos el espacio libre restante
2913 en el mismo y en caso de que se haya utilizado al totalidad del GAP, se
2914 lo elimina del archivo (
2921 Actualizamos la entrada correspondiente al registro ingresado (determinada
2922 por su RegID), en el archivo índice (
2926 ), indicando su offset donde podrá ser accedido luego.
2931 emufs_tipo2_agregar_registro()
2937 En el proceso de baja de registros entrarán en juego los tres archivos descripto
2940 sección de archivos auxiliares
2942 , siendo estos el archivo índice (
2946 ), el archivo de gaps / espacios libres (
2950 ) y el archivo de ID's liberados (
2957 Dado que en la implementación de este tipo de organización física contamos
2958 con los gaps o espacios libres entre registros, no se eliminará físicamente
2959 el registro del archivo de datos (
2963 ), pues entonces carecería de sentido el archivo anteriormente mencionado
2969 En cambio, se agrega el gap dejado por la eliminación a dicho archivo,
2970 y se marca físicamente en el archivo de datos la eliminación mediante un
2971 fill de los bytes correspondientes con un caracter nulo.
2972 (hexa 00 y con el propósito de probar fehacientemente que el sistema funciona).
2975 El proceso de baja o eliminación de un registro constará luego de los siguientes
2979 Se obtiene el offset o posición relativa en donde se encuentra grabado el
2980 registro dentro del archivo de datos.
2983 Se obtiene el tamaño del registro y se realiza un dummyfill del sector del
2984 archivo correspondiente al registro que se está dando de baja.
2985 (Se rellena la zona correspondiente a su header+data).
2988 Se agrega el GAP generado al archivo de gaps o espacios libres, y en caso
2989 de haberse generado un GAP lindante con otro GAP, se realizará un merge
2990 de los mismos y se los registrará bajo una única entrada en el archivo
2991 de espacios libres (.fsc).
2994 Se agrega el ID que fue liberado, al archivo de ID's liberados (
2998 ), al final del mismo (
3005 Se marca en el archivo índice (
3009 ) la eliminación, mediante el valor ¨-1¨ en el registro correspondiente
3010 al registro recién eliminado (se le cambia el valor al n-esimo registro,
3011 donde N = IDReg del reg eliminado).
3016 emufs_tipo2_borrar_registro()
3019 Modificación de registros
3022 Dada la naturaleza del archivo de ID's liberados, y el manejo de espacio
3023 libre del que consta esta organización de archivo, el proceso de modificación
3024 de un registro se limita a los siguientes pasos:
3027 Se realiza la lectura del registro, mediante el respectivo procedimiento
3028 ya desarrollado anteriormente.
3031 Una vez que se cuenta con los nuevos datos modificados, se procede a dar
3032 de baja el registro que ha sido modificado, e inmediatamente después se
3033 realiza una inserción con los nuevos datos.
3042 Como fue indicado, dada la naturaleza de PILA del subsistema de administración
3043 de ID liberados, es asegurado que la nueva inserción del registro modificado
3044 se realizará con el mismo RegID.
3049 emufs_tipo2_modificar_registro()
3052 Obtención de estadísticas
3055 Se puede tener acceso a las estadísticas generales del archivo, por ejemplo,
3056 cantidad de bloques, cantidad de registros, espacio libre total, espacio
3057 libre promedio, espacio libre máximo y mínimo, etc.
3060 Esta información es el resultado de ciertos cálculos realizados tanto en
3061 el archivo de datos como en los archivos índice.
3064 Completa una estructura del tipo EMUFS_Estadisticas con las estadísticas
3065 del archivo de datos, espacio libre total, cantidad de registros, cantidad
3066 de bloques, tamaño del archivo en bytes, relaciones entre tamaños y espacios
3072 emufs_tipo2_leer_estadisticas()
3075 Compactación del archivo de datos
3078 Así como los otros dos tipos de datos, el que nos compete también cuenta
3079 con la posibilidad de realizar la compactación de datos cuando el usuario
3080 lo desee, justificando todos los registros a izquierda, eliminando así
3081 los gaps existentes y decrementando el tamaño del archivo en disco (truncándolo
3085 Para poder comprender como hemos implementado el proceso de re-compactación
3086 en nuestro tipo de archivo 2, nos ayudaremos de esquemas a través de los
3087 cuales iremos describiendo el proceso.
3088 Notemos antes, que el proceso de compactación esta directamente ligado
3089 con el archivo de gaps o espacios libres (
3096 Comencemos con el siguiente cuadro situacional:
3097 \begin_inset Float figure
3104 Archivo con gaps entre registros previo a compactación
3108 \begin_inset Graphics
3109 filename graphics/Compact1.png
3121 Partiendo de esta base, el algoritmo de compactación tomará en su inicio
3122 al primer gap existente dentro del archivo de datos, en este caso llamado
3128 Luego, establecerá que el
3132 a partir de donde se quieren mover datos, sera:
3135 StartGap0 + SizeGap0 = EndGap0 = Source
3138 Lo cual no es nada más y nada menos que lo obvio, la fuente a partir de
3139 donde se mueven los datos, sera el fin del primer gap, donde comienzan
3145 ) del movimiento, se establece inicialmente, el inicio del gap, o sea
3147 StartGap0 = Destination
3152 Luego, el algoritmo entrara en un bucle while (mientras haya bucles por
3153 levantar), el cual trabajara hasta el final de la compactación de la siguiente
3164 Se levanta el próximo gap al levantado en una instancia previa.
3165 En este ejemplo, durante el primer loop del while, se levantará
3170 Luego, se calcula cuantos bytes hay que mover hacia el Destination de la
3194 Lo cual nuevamente es lógico pues querremos mover lo que se encuentra entre
3195 el final del primer gap levantado y el inicio del siguiente).
3198 Se realiza el movimiento de los datos, utilizando las direcciones
3206 , así como la variable
3210 que nos indica cuantos bytes transferir.
3216 La transferencia se hace de a chunks de 25 bytes + un resto segun el valor
3220 Se establece como gap de referencia, al ultimo gap leído (En este caso se
3233 ) y termina el código de repetición del bucle, dando lugar a la carga del
3234 siguiente gap en el inicio del mismo.
3242 Luego del primer bucle, el archivo se vera de la siguiente forma:
3243 \begin_inset Float figure
3250 Archivo con gaps en disco luego del primer bucle de compactación
3254 \begin_inset Graphics
3255 filename graphics/Compact2.png
3266 Notemos que al final de la porción de datos de los bytes movidos (donde
3271 ), hay basura que será pisada por el próximo movimiento.
3274 En el próximo loop, el bucle levantará un nuevo gap, y utilizando el gap
3275 anterior (En esta caso el Gap anterior será
3279 ) como referencia, realizará los mismos cálculos, desde donde transferir
3280 y cuantos bytes mover.
3281 (El destino es solo establecido inicialmente por código, y para el resto
3282 del algoritmo es el lugar donde quedo el puntero destination luego de la
3286 Una vez que se salga del bucle while, se realizará un último movimiento
3287 preprogramado, donde la fuente (
3291 ) será el final del ultimo gap, y la cantidad de bytes a mover será lo que
3292 se encuentre luego del mismo hasta el fin de archivo.
3295 Source = StartLastGap + SizeLastGap = EndLastGap
3298 Mustmove_bytes = Datsize - Source
3301 Damos por terminada así, la explicación del algoritmo de compresión el cual
3302 para el caso del tipo 2, es realmente bastante sencillo.
3307 emufs_tipo2_compactar()
3310 Consideraciones y Políticas de Diseño
3313 Se han tomado ciertas consideraciones para algunos casos particulares que
3314 se pueden presentar durante el uso/ejecución de la aplicación, así como
3315 también políticas respecto del diseño e implementación del sistema:
3318 En la organización física tipo 2 para los registros que se graban en disco
3319 hemos decidido utilizar como encabezado de cada uno de ellos, los datos
3320 [ID_REG][REG_SIZE], los cuales fueron detallados previamente.
3321 Si bien se podría haber descartado el grabado del ID del registro en el
3322 archivo de datos y puede parecer redundante, dado que poseemos el archivo
3323 índice con el offset directo, el mismo se lo graba por distintos motivos:
3327 A) En caso de la corrupción del archivo índice (.idx), podremos gracias a
3328 que poseemos en el archivo de datos, el ID de cada registro, recrear dicho
3329 índice, ayudándonos del archivo de espacios libres (
3333 ), para poder saltear los espacios libres y e ir recorriendo secuencialmente
3334 los registros, reconstruyendo así el índice en cuestión.
3335 (esta función de reconstrucción no pudo ser implementada para esta entrega,
3336 pero es una posibilidad real).
3340 B) Luego de un proceso de re-compactación, los espacios libres que pudieron
3341 haber existido en el archivo de datos (
3345 ), son eliminados y los registros han cambiado de posición.
3346 Por ello, recorriendo secuencialmente por única vez el archivo de datos,
3347 se procede a la actualización / reconstrucción del índice de direcciones
3355 Si se desea insertar un registro y no se puede hallar un gap o espacio libre
3356 donde quepa, se los inserta al final del archivo.
3359 Ante una operación de baja de un registro, el mismo no es físicamente borrado
3360 del archivo de datos (
3364 ), simplemente los bytes que ocupa son llenados con hexa (00).
3365 Paralelamente, se procede a actualiza el archivo índice, insertando como
3366 valor de OFFSET para el registro eliminado, el valor ¨-1¨, indicando así
3367 la inexistencia del registro para el futuro, y por otro lado se genera
3368 la entrada de espacio libre en el archivo de gaps (
3375 La reutilización de ID's liberados por previas operaciones de baja de registros,
3376 se ve implementada por el archivo de ID liberados (.did), y su comportamiento
3377 es el de una pila por lo que el último ID liberado, sera el próximo a ser
3381 Como fue explicado en la implementación del archivo índice, existe una correspon
3382 dencia 1 a 1 entre los registros allí presentes (en el .idx) y los ID's de
3383 los registros, por lo cual el registro N-ésimo del archivo índice, será
3384 el correspondiente al registro de datos cuyo ID es igual a N.
3387 El proceso de compactación de archivos, realiza los movimientos de información
3388 requeridos para dicho propósito de a chunks de 25 bytes por vez.
3389 Este valor es fijo, pero se lo podría hacer parametrizable mediante la
3390 GUI en próximas entregas.
3394 \begin_inset LatexCommand \label{cha:tipo3}
3398 Archivo con bloques parametrizados y registros de longitud constante
3401 Las distintas organizaciones de archivos buscan aprovechar al máximo el
3402 espacio del archivo.
3405 En este caso veremos que sucede luego de agregar y borrar una gran cantidad
3406 de registros del archivo, lo que provoca como consecuencia directa la fragmenta
3407 ción del archivo, es decir, quedan huecos entre un registro y otro, lo que
3408 produce un desperdicio de espacio.
3411 La implementación de este tipo de archivo puede ser encontrada en
3415 mientras que su interfaz pública está disponible en
3425 Esta organización guarda los registros pertenecientes al archivo en bloques
3426 de tamaño parametrizado, de modo que intentará guardar la mayor cantidad
3427 de registros que quepan en un bloque.
3431 Así como los graba, también tendrá la posibilidad de leer registros y borrarlos
3435 El archivo estará compuesto por una cabecera que da información sobre el
3436 tipo (2, o el valor T3 del tipo
3440 en este caso) de organización, el tamaño de los bloques y el tamaño de
3447 +-----------+-----------+-----------+------------------------//-+
3450 | tipo | tam_bloque| tam_reg | Cero o más bloques ...
3458 +-----------+-----------+-----------+------------------------//-+
3461 /- 4 bytes -/- 4 bytes -/- 4 bytes -/
3464 Organización Física de un Bloque
3467 Cada bloque será capaz de contener la cantidad de registros enteros que
3469 De esta manera un registro que no entre completamente en el bloque deberá
3470 almacenarse en un bloque diferente.
3473 Los bloques no contienen ninguna información adicional, solo se conoce su
3474 tamaño y se usa para delimitar
3475 \begin_inset Quotes eld
3479 \begin_inset Quotes erd
3482 zonas en el archivo y obtener de esta manera acceso semi-aleatorio a los
3486 bloque N-1 | bloque N | bloque N+1
3489 /----------+------------+------------+---------------+-----------/
3494 | registro 1 | registro 2 | espacio libre |
3499 /----------+------------+------------+---------------+-----------/
3502 /------------- tamaño del bloque ---------/
3505 Organización Física de Registros
3508 Cada registro se almacena en un bloque, y contiene una cabecera que indica
3513 por este motivo al realizar la búsqueda de espacio en un bloque se lo hará
3514 preguntando por el tamaño del registro más
3516 sizeof(EMUFS_REG_ID).
3522 +-----------+-------------------+
3529 +-----------+-------------------+
3532 /- 4 bytes -/- [tam_reg] bytes -/
3535 Organización Física de Registros
3540 Al ser los registros de longitud constante, se ha adoptado que un registro
3545 nunca podrá estar almacenado en algún lugar que no sea el comienzo de un
3547 De esta manera se puede calcular cuantos bloques ocupará un registro y
3548 se podrá solicitar lugar para almacenarlo con la ayuda de la función
3550 emufs_fsc_buscar_n_lugares(),
3552 que es muy importante para evitar el solapamiento de registros.
3553 Esta consideración acarrea como consecuencia directa un alto costo en términos
3554 del espacio desperdiciado.
3557 A continuación se presenta un ejemplo gráfico de un registro multibloque
3558 de 26 bytes (de contenido
3559 \begin_inset Quotes eld
3562 12345678901234567890123456
3563 \begin_inset Quotes erd
3566 ) almacenado en un archivo con bloques de bytes 14 bytes (10 para datos)
3567 y registros de 38 bytes:
3570 | bloque 0 | bloque 1 | bloque 2
3573 +-------------------+-------------------+-------------------+-//-+
3576 | registro 0 - 1/3 | registro 0 - 2/3 | registro 0 - 3/3..|
3583 |+----+------------+|+----+------------+|+----+--------+....| // |
3586 || id | datos ||| id | datos ||| id | datos |....|
3593 ||----+------------+||----+------------+||----+--------+....| // |
3596 || 0 | 1234567890 ||| 0 | 1234567890 ||| 0 | 123456 |....|
3603 |+----+------------+|+----+------------+|+----+--------+....| // |
3606 +-------------------+-------------------+-------------------+-
3616 4 bytes libres (e inutilizables) al final del bloque 2
3619 Funciones Principales
3630 se encuentran las cabeceras y la implementación de las funciones principales
3631 respectivamente, las cuales dan funcionalidad a esta organización.
3634 A continuación se comentará la descripción de algunas acciones importantes.
3637 Lectura de registros
3640 La lectura de un registro se realiza con la ayuda del archivo .
3644 el cual contiene la información de la posición del registro dentro del
3646 Una vez leída esta información, se recupera el bloque (en su totalidad)
3647 del archivo y se busca secuencialmente el registro con el
3656 emufs_tipo3_leer_registro()
3662 Graba un registro en un bloque donde haya espacio suficiente, y si no crea
3663 un nuevo bloque y lo agrega al final del archivo.
3666 Luego de grabar un registro, actualiza los archivos de índice .idx y .fsc
3667 para mantener la coherencia.
3670 Cuando nos encontramos con registros multibloque, se calcula cuantos bloques
3671 ocupará el registro de la siguiente manera:
3673 Cantidad de Bloques = 1 + Tamaño del Registro/(Tamaño del Bloque-Sizeof(EMUFS_RE
3677 Esta ecuación solo falla en el caso que el tamaño del registro y el tamaño
3678 del bloque sean iguales, en tal caso, se coloca el valor 1 en
3685 Y con esta información se realiza un ciclo
3689 que grabará tantas veces como sea necesario levantando y grabando los bloques
3695 emufs_tipo3_grabar_registro()
3701 Borra un registro del archivo de datos, para esto levanta el bloque al que
3702 pertenece el archivo y ajusta los demás registros justificándolos hacia
3706 Cabe destacar que para dar de baja un registro no hace falta borrarlo del
3707 archivo de datos, solo es necesario borrar las entradas en los archivos
3708 de índice, pero cuando se realiza el ajuste el algoritmo toma porciones
3709 del bloque del tamaño de un registro mas su encabezado - comenzando desde
3710 el siguiente al que fue borrado - y copia (sobreescribe) sobre el anterior.
3711 De esta manera, la información correspondiente al registro borrado no estará
3712 presente en el archivo de datos.
3713 Esto es una consecuencia del ajuste al borrar un registro, pudiendo no
3714 ser así, si no se realizara el mismo.
3717 En el caso de los registros multibloque, se eliminará la porción del registro
3718 contenida en el primer bloque y se actualizarán de manera conveniente los
3719 archivos índice, para restaurarlos a un valor verdadero.
3724 emufs_tipo3_borrar_registro()
3727 Obtención de estadísticas
3730 Se puede tener acceso a las estadísticas generales del archivo, por ejemplo,
3731 cantidad de bloques, cantidad de registros, espacio libre total, espacio
3732 libre promedio, espacio libre máximo y mínimo, etc.
3735 Esta información es el resultado de ciertos cálculos realizados tanto en
3736 el archivo de datos como en los archivos índice.
3739 Completa una estructura del tipo EMUFS_Estadisticas con las estadísticas
3740 del archivo de datos, espacio libre total, cantidad de registros, cantidad
3741 de bloques, tamaño del archivo en bytes, relaciones entre tamaños y espacios
3747 emufs_tipo3_leer_estadisticas()
3750 Compactación del archivo de datos
3753 Esta función intenta reorganizar el archivo de manera que el espacio libre
3754 sea lo menor posible, recordando siempre que un registro no puede ser almacenad
3755 o en mas de un bloque excepto que el tamaño del registro sea mayor que el
3759 Para realizar esto, se aprovecha la funcionalidad de
3761 emufs_tipo3_grabar_registro()
3763 ya que esta tiene la capacidad de determinar una posición mas eficiente
3764 en el archivo para un registro.
3765 Por esto lo que se hace es levantar uno por uno los registros y volverlos
3766 a grabar, de ese modo todos los
3770 que pudieron haberse formado por la eliminación de registros serán cubiertos
3774 Al estar utilizando recuperación de
3778 borrados, esto me asegura que el registro borrado-guardado conservará el
3782 Al finalizar este proceso se verifica si existen bloques vacíos para truncar
3784 Lo mismo se debe hacer con el archivo de espacios libres .
3788 el cual disminuye su tamaño también.
3793 void emufs_tipo3_compactar()
3796 Consideraciones y Políticas de Diseño
3799 Se han tomado ciertas consideraciones para algunos casos particulares que
3800 se pueden presentar durante el uso/ejecución de la aplicación.
3803 Cada registro tiene un encabezado que indica el
3810 Si el tamaño del registro es mayor que el tamaño del bloque el registro
3811 se particionará en la cantidad de bloques que sea necesario, pero siempre
3812 se guardará desde el comienzo de un bloque, esto quiere decir que nunca
3813 se podrá encontrar un comienzo de registro en algún lugar de un bloque
3814 que no sea el comienzo del mismo.
3817 Si el registro se divide en mas de un bloque, se le coloca el id como encabezado
3818 igualmente, pero en el archivo .
3822 solo se guarda el primer bloque.
3827 se actualizan todos los bloques con el espacio libre que realmente tienen.
3830 EMUFS View (interfaz gráfica)
3836 La interfaz de visualización de EMUFS permite interactuar con los distintos
3837 tipos de archivos para cada conjunto de datos almacenado (ya sean facturas,
3838 articulos, o notas de facturas).
3844 Para poder correr la interfaz gráfica necesitará previamente compilarla
3845 (así como compilar los programas auxiliares), para ello necesitará cumplir
3846 con los siguiente requisitos:
3849 Compilador gcc versión 3.3.x preferentemente.
3850 No podemos garantizar la compatibilidad con otras versiones debido a cambios
3851 drásticos que sufrieron las versiones anteriores.
3854 Parser XML libxml2 versión 2.6.x .
3855 Versiones 2.5 y anteriores son incompatibles en la API y no funcionarán.
3858 libncurses version 5 o superior (probado con 5.4).
3867 Para compilar la GUI solo debe ejecutar el comando make dentro del directorio
3869 Esto compilará primero una biblioteca estática con los manejadores de los
3870 3 tipos de archivo y luego compilará la GUI.
3876 Preparar el banco de pruebas
3879 Antes de comenzar a utilizar la GUI deberá generar los archivo XML desde
3880 donde serán leídos los datos para generar los archivos que luego se utilizará.
3881 Para ello el proceso de compilación creará 2 ejecutable : generar_fact
3882 y generar_art, que se ubicarán en la carpeta generar dentro de emufs_gui.
3885 Estos programas generan facturas y artículos respectivamente en forma aleatorio,
3886 utilizando diccionarios de datos para llenar los campos.
3887 Primero deberá ejecutar generar_art, ya que éste último crea un diccionario
3888 de artículos que luego utilizará generar_fact para los items de las facturas.
3891 Ambos programas reciben 2 parámetros : el nombre de archivo de salida y
3892 la cantidad de entradas a generar.
3895 El generador de facturas fue diseñado para cumplir con los porcentajes pedidos
3896 por el enunciado en algunos aspectos.
3897 La cantidad de facturas por dia del mes es aleatoria.
3903 El programa acepta varios parámetros, algunos de ellos opcionales, otros
3904 obligatorios dependiendo de las elecciones realizadas.
3907 Para obtener una completa descripción de los parámetros el programa acepta
3909 \begin_inset Quotes eld
3913 \begin_inset Quotes erd
3917 \begin_inset Quotes eld
3921 \begin_inset Quotes erd
3924 para mostrar una ayuda en línea.
3927 Si el programa es ejecutado sin parámetros tratará de recuperar los artículos
3928 y las facturas desde archivo previamente creados.
3931 Para crear un archivo de artículos a partir de un archivo XML bien formado,
3932 se debe ejecutar el programa con la opción
3933 \begin_inset Quotes eld
3937 \begin_inset Quotes erd
3941 Dicha opción espera que el siguiente parámetro sea el nombre del archivo
3942 a leer, y que éste útimo tenga extensión xml (notar que es solo minúsculas).
3943 A continuación espera encontrar el tipo de archivo que se quiere crear,
3944 pudiendo ser éste último 1, 2 ó 3.
3945 De ser el tipo de archivo con bloques, se le exigirá que ingrese como último
3946 parámetro el tamaño del mismo.
3949 Para crear el archivo de facturas es el mismo procedimiento, solo que utilizando
3951 \begin_inset Quotes eld
3955 \begin_inset Quotes erd
3959 Luego de los parámetros de tipo y tamaño de bloque debe especificarse el
3960 tipo y tamaño de bloque para el archivo de notas.
3964 Debe saber que estos parámetros no son mutuamente excluyentes, por lo que
3965 podrá utilizarlos al mismo tiempo.
3971 A continuación se da una lista detallada de las operaciones que son posibles
3972 hacerse desde esta interfaz :
3975 Alta, baja y modificación de Artículos.
3976 Para ello se abrirá una ventana donde se podrá editar comodamente los datos.
3979 Alta, baja y modificación
3985 En la modificación de una factura no se podrán cambiar ni la cantidad de
3986 items y los datos de los mismo!.
3987 La nota si podrá ser modificada.
3994 Ver fisicamente los registros de cualquiera de los archivos sin importar
3995 el tipo al que pertenezcan.
3996 Desde aquí podrá tambien eliminar, agregar o modificar el registro actual.
4000 Para aquellos archivos que hallan sido creados con un tipo con bloques,
4001 podrá verlos fisicamente, viendo el bloque actual y los anteriores/posteriores.
4004 Ver las estadísticas de cada archivo según su tipo, para realizar comparativas
4007 Cambiar el formato de cualquier tipo o parametros de archivo.
4010 Compactar los archivos.
4013 Decisiones de Diseño
4016 Durante el desarrollo se han tomado ciertas decisiones en el diseño o restriccio
4018 En este punto nos centraremos en las especificas tomadas por la interfaz
4019 de visualización, y no tomaremos en cuenta las que ponen los tipos de archivo
4023 La cantidad de items por factura es igual a 10 para archivos de registro
4024 de longitud fija y bloque parametrizado (TIPO 3).
4025 Esta decición fue tomada por poner un valor típico de items que puede haber
4026 en una factura, evaluando un caso de un comercio chico.
4027 Como el tipo de archivo permite cortar un registro y guardarlo en varios
4028 bloques consecutivos, la restricción de cantidad solo es un hecho de elección,
4029 y así pusieramos 100, 1000, 10000 no habría diferencia, ya que el tipo
4030 de archivo lo guardaría sin problemas.
4033 Si el archivo es de TIPO 3 y se agregan más de 10 items estos son truncados
4034 y descartados sin aviso al usuario.
4035 Esta fue una desición basada en el tiempo del proyecto.
4036 De tener que validar y consultar al usuario se hubiera perdido tiempo de
4037 mucho valor para completar objetivos más importantes del TP.
4040 Los campos son delimitados por el caracter nulo (en caso de los strings)
4041 y por la longitud del tipo de dato en caso de los campos numéricos.
4042 De esta forma se aprovechan las características de manejo de string en
4049 Un ejemplo de vista de registros es la que se observa a continuación :
4053 \begin_inset Graphics
4054 filename gui_ver_registros.eps
4063 Como puede verse el registro actual se ve resaltado respecto de los demás.
4064 También se puede observar que en este caso (el bloque es de 2000 bytes)
4065 no entra toda la información en pantalla, pero es posible desplazar utilizando
4069 Los datos binarios son convertidos a texto para ser mostrados, siendo la
4070 representación elegida :
4073 (XXX) : Representa un ID.
4074 En el caso de las facturas también aparece en los datos el número de índice
4075 de la nota asociada con esta representación.
4078 {XXX} : Representa el tamaño de los datos.
4079 Esto siempre y cuando el registro sea de longitud variable (TIPO1 y TIPO2).
4082 También es posible ejecutar acciones de edición sobre el registro seleccioado,
4083 así como buscar por ID de registro.
4086 Cuando se procesa la información en crudo (es decir, el area de datos) algunos
4087 bytes son modificados para evitar errores visuales.
4088 Un caso es cuando el bytes es compuesto por 8 bits de valor 0 (caracter
4092 Lo que se hace es cambiarlo por un caracter que tenga representacion visual
4093 (en este caso un *).
4094 Lo mismo suscede para los caracteres de control (
4100 r por ejemplo) y los espacion.
4101 Esta política fue tomada ya que estos caracteres modifican la salida en
4102 pantalla, y de no evitar su envío a la pantalla, producirían resultados
4103 inesperados en la visualización.
4109 A continuación se enumera los errores que sabemos que existen, que no hemos
4110 tenido tiempo de corregir, pero que no hacen al TP en sí :
4113 Si la consola o terminal cambia de tamaño la GUI no sigue el nuevo tamaño,
4114 pudiendose producir defectos visuales.
4115 Esto es debido a que se debe capturar una señal que envia el SO, pero no
4116 pudimos hacer que funciones con todas las terminales bajo X, por lo que
4117 se decidio dejarlo para cuando tengamos tiempo.
4120 Si la GUI fue compilada con -DDEBUG y no se utiliza un PIPE para redirigir
4121 la salida de error estandar, es posible que algun componente del programa
4122 emita un mensaje de debug o warning y esta cause defectos de visualización
4123 o el programa deje directamente de funcionar.
4124 Esto es un defecto de la biblioteca NCurses.
4127 Cuando se cargan datos desde el XML y este contiene caracteres extendidos,
4128 estos son mostrados en UTF8 en la pantalla.
4129 Si no posee una consola configurada en UTF8 verá los caracteres extendidos
4130 en su representación ASCII (2 caracteres por cada caracter extendido).
4131 Esto se da a causa de que la LibXml maneja de forma interna todo en UTF8
4132 sin importar el encoding declarado en el XML.
4133 El encoding solo lo tienen en cuenta para guado se guarde.
4134 No nos hemos tomado el trabajo de hacer la conversión solo por cuestiones
4138 Comparación de tipos de archivo (conclusiones)
4141 Método utilizado para la comparación
4144 Para realizar la comparación entre los distintos tipos de archivo, se generaron
4145 un XML de artículos con 200 entradas y uno de facturas de 1750 entradas.
4146 Los valores fueron arbitrarios y un poco más elevados que los requeridos
4147 en el enunciado para poner a prueba el sistema.
4150 En la tabla que se dará más adelante, se pueden apreciar los datos característic
4151 os de cada tipo de archivo.
4152 El método de prueba fue el siguiente :
4155 Para cada tipo de archivo se cargaron los archivos XML de prueba.
4158 Se anotaron las estadísticas que entrega la GUI.
4161 Se eliminaron alrededor de 50 artículos y 200 facturas.
4162 El valor no es exacto, puesto que al ser pseudo-aleatoria la cantidad borrada
4163 puede no ser 50 o 200.
4166 Se anotaron las estadísticas nuevamente.
4169 Ahora, los tamaños de bloque para los archivos con bloques fueron tomados
4170 de 512 bytes, por ser una unidad típica de dispositivos de almacenamiento,
4171 y nos pareció lógico dada la similitud utilizar esta unidad.
4178 \begin_inset Float table
4185 Artículos con archivos con tamaño de bloque 512 (cuando aplica)
4191 \begin_inset Tabular
4192 <lyxtabular version="3" rows="8" columns="7">
4193 <features islongtable="true">
4194 <column alignment="left" valignment="top" leftline="true" width="0">
4195 <column alignment="center" valignment="top" leftline="true" width="0">
4196 <column alignment="center" valignment="top" leftline="true" width="0">
4197 <column alignment="center" valignment="top" leftline="true" width="0">
4198 <column alignment="center" valignment="top" leftline="true" width="0">
4199 <column alignment="center" valignment="top" leftline="true" width="0">
4200 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4201 <row topline="true" bottomline="true">
4202 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4212 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4222 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4232 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4242 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4252 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4262 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4273 <row topline="true" bottomline="true">
4274 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4281 Tamaño de bloque: 512
4284 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4294 <cell multicolumn="2" alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4301 <cell multicolumn="2" alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4308 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
4318 <cell multicolumn="2" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4325 <cell multicolumn="2" alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4333 <row topline="true">
4334 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4344 <cell multicolumn="1" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4354 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4364 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4374 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4384 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4394 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4405 <row topline="true">
4406 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4413 Tamaño Datos de Control
4416 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4426 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4436 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4446 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4456 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4466 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4477 <row topline="true">
4478 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4488 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4498 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4508 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4518 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4528 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4538 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4549 <row topline="true">
4550 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4557 Media de Espacio Libre
4560 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4570 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4580 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4590 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4600 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4610 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4621 <row topline="true">
4622 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4629 Máximo de Espacio Libre
4632 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4642 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4652 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4662 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4672 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4682 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4693 <row topline="true" bottomline="true">
4694 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4701 Mínimo de Espacio Libre
4704 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4714 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4724 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4734 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4744 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4754 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4773 \begin_inset Float table
4780 Artículos con archivos con tamaño de bloque 1024 (cuando aplica)
4786 \begin_inset Tabular
4787 <lyxtabular version="3" rows="8" columns="7">
4788 <features islongtable="true">
4789 <column alignment="left" valignment="top" leftline="true" width="0">
4790 <column alignment="center" valignment="top" leftline="true" width="0">
4791 <column alignment="center" valignment="top" leftline="true" width="0">
4792 <column alignment="center" valignment="top" leftline="true" width="0">
4793 <column alignment="center" valignment="top" leftline="true" width="0">
4794 <column alignment="center" valignment="top" leftline="true" width="0">
4795 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
4796 <row topline="true" bottomline="true">
4797 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4807 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4815 <cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4823 <cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4831 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
4839 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4847 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4856 <row topline="true" bottomline="true">
4857 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4864 Tamaño de bloque: 1024
4867 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4877 <cell multicolumn="2" alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4884 <cell multicolumn="2" alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4891 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
4901 <cell multicolumn="2" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4908 <cell multicolumn="2" alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4916 <row topline="true">
4917 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4927 <cell multicolumn="1" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4937 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4947 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4957 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4967 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4977 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4988 <row topline="true">
4989 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4996 Tamaño Datos de Control
4999 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5009 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5019 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5029 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5039 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5049 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5060 <row topline="true">
5061 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5071 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5081 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5091 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5101 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5111 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5121 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5132 <row topline="true">
5133 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5140 Media de Espacio Libre
5143 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5153 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5163 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5173 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5183 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5193 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5204 <row topline="true">
5205 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5212 Máximo de Espacio Libre
5215 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5225 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5235 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5245 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5255 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5265 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5276 <row topline="true" bottomline="true">
5277 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5284 Mínimo de Espacio Libre
5287 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5297 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5307 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5317 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5327 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5337 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5358 Evidentemente para el caso de artículos, una muy mala elección sería utilizar
5359 el archivo de tipo3, puesto que al usar registros constantes es posible
5360 que se desperdicie mucho espacio si ocurren muchas eliminaciones (como
5361 se observa en la tabla).
5362 Entre los tipos 1 y 2 no existe mucha diferencia en los números, por lo
5363 que la decisión podría ser tomada en base a los tiempos de acceso.
5364 Tomando este criterio el T2 sería la mejor forma de almacenar los datos
5365 si lo más frecuente son lecturas, ya que al leer se puede obtener el offset
5366 desde el principio del registro, mientras que en el tipo1 se debe hacer
5367 una búsqueda secuencial sobre el bloque, y de ser éste último muy grande
5368 el tiempo de acceso puede ser elevado.
5371 Para operaciones que requiera muchas bajas de elementos el tipo 2 no sería
5372 la mejor opción, puesto que la liberación es compleja, ya que cuando se
5373 da de baja un registro se debe verificar si dicho espacio se solapa con
5374 algún espacio libre actual, de manera de mantener espacios libres como
5375 lo hacen los sistemas de archivo ext2, manteniendo la lista de los offsets
5376 y tamaño de espacios libres, a fin de buscar el que mejor ajuste en caso
5380 Para el caso de artículos, donde puede haber un continuo cambio en la oferta
5381 de nuestro negocio, nos inclinaremos por el tipo de archivo 1, con un tamaño
5383 Solo recordaremos compactar el archivo periódicamente a fin de minimizar
5384 el espacio desperdiciado.
5391 \begin_inset Float table
5398 Facturas con archivos con tamaño de bloque 512 (cuando aplica)
5404 \begin_inset Tabular
5405 <lyxtabular version="3" rows="8" columns="7">
5406 <features islongtable="true">
5407 <column alignment="left" valignment="top" leftline="true" width="0">
5408 <column alignment="center" valignment="top" leftline="true" width="0">
5409 <column alignment="center" valignment="top" leftline="true" width="0">
5410 <column alignment="center" valignment="top" leftline="true" width="0">
5411 <column alignment="center" valignment="top" leftline="true" width="0">
5412 <column alignment="center" valignment="top" leftline="true" width="0">
5413 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
5414 <row topline="true" bottomline="true">
5415 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5425 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
5435 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
5445 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
5455 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5465 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5475 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5486 <row topline="true" bottomline="true">
5487 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5494 Tamaño de bloque = 512
5497 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
5507 <cell multicolumn="2" alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
5514 <cell multicolumn="2" alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
5521 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
5531 <cell multicolumn="2" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5538 <cell multicolumn="2" alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5546 <row topline="true">
5547 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5557 <cell multicolumn="1" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5567 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5577 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5587 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5597 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5607 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5618 <row topline="true">
5619 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5626 Tamaño Datos de Control
5629 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5639 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5649 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5659 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5669 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5679 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5690 <row topline="true">
5691 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5701 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5711 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5721 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5731 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5741 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5751 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5762 <row topline="true">
5763 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5770 Media de Espacio Libre
5773 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5783 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5793 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5803 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5813 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5823 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5834 <row topline="true">
5835 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5842 Máximo de Espacio Libre
5845 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5855 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5865 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5875 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5885 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5895 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5906 <row topline="true" bottomline="true">
5907 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5914 Mínimo de Espacio Libre
5917 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5927 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5937 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5947 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5957 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
5967 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
5986 \begin_inset Float table
5993 Artículos con archivos con tamaño de bloque 1024 (cuando aplica)
5999 \begin_inset Tabular
6000 <lyxtabular version="3" rows="8" columns="7">
6001 <features islongtable="true">
6002 <column alignment="left" valignment="top" leftline="true" width="0">
6003 <column alignment="center" valignment="top" leftline="true" width="0">
6004 <column alignment="center" valignment="top" leftline="true" width="0">
6005 <column alignment="center" valignment="top" leftline="true" width="0">
6006 <column alignment="center" valignment="top" leftline="true" width="0">
6007 <column alignment="center" valignment="top" leftline="true" width="0">
6008 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
6009 <row topline="true" bottomline="true">
6010 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6018 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
6026 <cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
6034 <cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
6042 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
6050 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6058 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
6067 <row topline="true" bottomline="true">
6068 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6082 Tamaño de bloque: 1024
6085 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
6102 <cell multicolumn="2" alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
6109 <cell multicolumn="2" alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
6116 <cell multicolumn="1" alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
6133 <cell multicolumn="2" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6140 <cell multicolumn="2" alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
6148 <row topline="true">
6149 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6159 <cell multicolumn="1" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6169 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6179 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6189 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6199 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6209 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
6220 <row topline="true">
6221 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6228 Tamaño Datos de Control
6231 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6241 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6251 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6261 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6271 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6281 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
6292 <row topline="true">
6293 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6303 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6313 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6323 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6333 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6343 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6353 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
6364 <row topline="true">
6365 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6372 Media de Espacio Libre
6375 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6385 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6395 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6405 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6415 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6425 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
6436 <row topline="true">
6437 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6444 Máximo de Espacio Libre
6447 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6457 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6467 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6477 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6487 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6497 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
6508 <row topline="true" bottomline="true">
6509 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6516 Mínimo de Espacio Libre
6519 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6529 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6539 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6549 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6559 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
6569 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
6590 Primero descartaremos al tipo 3 como un buen modo de almacenar las facturas,
6591 por el sólo hecho de que la cantidad de ítems que puede tener una factura
6592 está limitada al tamaño de registro utilizado.
6593 Esto sólo sería razonable en un contexto en donde la variabilidad del registro
6594 no sea drástica como es el caso de las facturas.
6595 De tomar valores grande de registros, se corre el riesgo de tener mucho
6596 espacio desperdiciado en los datos, y tomando valores pequeños de registro
6597 se limita el sistema en cuanto a cantidad de ítems a colocar en una factura
6599 Se puede notar una leve baja en el espacio libre, y aumentar el tamaño
6600 del bloque quizás más haga que este valor baje, pero se aumentaría el tiempo
6601 de acceso a los registros.
6604 Nuevamente tenemos una disputa entre el los tipo 1 y 2.
6607 Idealmente, si sólo tuviéramos altas el mejor tipo sería el 2 sin dudarlo,
6608 ya que aprovecha el máximo espacio al no tener pérdidas, debido a que los
6609 registros van uno a continuación del otro.
6610 También tenemos la ventaja de que el acceso es directo.
6611 Para un caso teórico donde las facturas no se dan de baja, esto sería ideal.
6612 Hasta aquí solo hemos visto comparaciones con la carga inicial.
6615 Analizaremos ahora que pasa luego de borrar varios registros en posiciones
6617 Primeramente se puede observar que el tamaño de datos de control es similar
6618 (recordar que se guarda el id del registro para poder realizar tareas de
6619 recuperación de datos en caso de que el índice se dañe).
6620 El máximo espacio libre no nos da mucha información, ya que en el caso
6621 del tipo 1 podríamos tener n bloques consecutivos libres y tener posiciones
6622 para almacenar registros grandes en ambos casos (recordar que tipo1 tiene
6623 recuperación de espacio libre para n bloques consecutivos, no siempre se
6625 De todos determinar un espacio libre para un archivo de tipo 2 es mucho
6626 más rápido que para tipo1 si el tamaño del registro es grande, ya que el
6627 archivo de tipo1 debe hacer una búsqueda sobre n bloques, mientras que
6628 el tipo 2 encuentra un gap de tamaño suficiente más rápido.
6631 Pero no todo es color de rosa en el mundo de archivos de tipo2.
6632 Como se dijo anteriormente las bajas de registros requieren de un proceso
6633 grande al actualizar el índice de espacio libre, para asegurarse de tomar
6634 espacios libres consecutivos como un solo espacio libre, y en el caso de
6635 que las bajas y las altas comunes, esto es una pérdida de performance del
6639 En este caso como se trata de facturas, y suponemos que como usuarios de
6640 sistema queremos cancelar pocas facturas (ya que cancelar una factura significa
6641 que se cayó una venta) optamos por que el mejor tipo de archivo para almacenar
6642 las facturas sera el tipo2.