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
30 \begin_inset Formula $\mu$
64 es la estuctura principal que encapsula todas las funciones para el manejo
65 de un archivo de datos.
68 Esta estructura consta de:
75 que es un tipo enumerado que indica cual es la organización.
82 indica el tamaño del bloque para los tipos 1 y 3.
89 indica el tamaño del registro, para el tipo 3 que posee tamaño constante.
96 puntero a la función para leer un bloque.
101 void *leer_bloque_raw()
103 puntero a la función para leer un bloque, el anterior y el siguiente.
108 void **leer_registro()
110 puntero a la función para leer un registro.
115 void **leer_registro_raw()
117 puntero a la función para leer un registro con su encabezado.
122 EMUFS_REG_ID *grabar_registro()
124 puntero a la función para grabar un registro.
129 EMUFS_REG_ID *modificar_registro()
131 puntero a la función para modificar un registro.
136 int *borrar_registro()
138 puntero a la función para borrar un registro.
143 EMUFS_Estadisticas *leer_estadisticas()
145 puntero a la función para cargar una estructura con las estadísticas.
152 puntero a la función para compactar un archivo.
159 almacena el nombre del archivo sin extensión.
162 Esta estructura define los valores de sus punteros según el tipo de organización
163 que se desee manejar.
166 Por ejemplo si se desea crear un archivo de nombre
167 \begin_inset Quotes eld
171 \begin_inset Quotes erd
174 organizado de la forma 3, se invoca a la función
176 EMUFS *emufs_crear(const char *filename, EMUFS_Tipo tipo,EMUFS_BLOCK_SIZE
177 tam_bloque, EMUFS_REG_SIZE tam_reg),
183 es el nombre que tendrán los archivos de datos e índice,
187 es el tipo de organización - bloques parametrizados y registros constantes
192 es el tamaño del bloque, y
196 es el tamaño del registro.
199 Para las diferentes organizaciones puede ser que alguno de estos 2 últimos
200 valores no tengan sentido almacenarlas y tomaran un valor por defecto igual
204 Según el tipo de organización, se inicializan los punteros a las funciones.
211 emufs_tipo3_leer_bloque()
213 , y lo mismo sucede con los demás.
229 \begin_inset LatexCommand \label{sec:cabecera_gral}
233 Organización física general de un archivo E
234 \begin_inset Formula $\mu$
241 \begin_inset Formula $\mu$
244 FS está compuesto por 4 archivos a nivel de sistema operativo: archivo de
245 datos (con 3 formatos posibles, ver páginas
246 \begin_inset LatexCommand \pageref{cha:tipo1}
251 \begin_inset LatexCommand \pageref{cha:tipo2}
256 \begin_inset LatexCommand \pageref{cha:tipo3}
260 ), archivo de índice (ver página
261 \begin_inset LatexCommand \pageref{sec:idx}
265 ), archivo de control de espacio libre (ver página
266 \begin_inset LatexCommand \pageref{sec:fsc}
270 ) y archivo de índices recuperables (ver página
271 \begin_inset LatexCommand \pageref{sec:did}
278 El archivo de datos está compuesto por:
289 (4 bytes en plataformas Linux de 32 bits) que representa el tipo de archivo.
292 Datos dependientes del tipo de archivo.
299 es utilizada para poder detectar el formato de un archivo al abrirlo.
300 Los datos dependientes del tipo de archivo serán explicados en sus secciones
307 +-----------+--------------------------------------------//-+
310 | tipo | Datos dependientes del tipo de archivo ...
318 +-----------+--------------------------------------------//-+
327 Acompañando al archivo de datos (
331 ) el cual es responsable de la contención de los registros, tendremos tres
332 archivos auxiliares (
344 ) cuya funcionalidad y propósito pasamos a describir a continuación, sin
345 antes remarcar que los tres archivos poseen una sola implementación para
346 las distintas formas de organización física que hemos implementado (tres
347 para ser mas exactos).
350 Entre las ventajas de poseer la misma implementación se encuentra el tener
351 un API común entre los tres tipos para el manejo de la localización de
352 sus registros, administración de espacio libre e Id's liberados, sin necesidad
353 de realizar n-implementaciones para un mismo objetivo final.
356 Además, la obtención de ciertos datos estadísticos como espacio libre, o
357 cantidad de registros, se realiza a través de la misma interfaz, y también
358 se ha facilitado en cierto grado la re-organización física de un archivo
359 (pasar de un tipo a otro), dado el uso de estos tres archivos auxiliares
360 en común para funciones tan predominantes como índexación, administración
361 de espacio libre y recuperación de Id's.
365 \begin_inset LatexCommand \label{sec:idx}
372 El archivo índice (.idx), permite la localización de los registros en el
373 .DAT de forma directa, mediante la obtención de su offset respecto del inicio
374 del .dat, o nro bloque (segun el tipo de organización física) en donde se
375 encuentra un registro dado, indicado por su
380 Los registros de este archivo se encuentran representados una estructura
381 que indica un número de registro y el bloque u offset en donde se encuentra
385 Es necesario que este archivo esté ordenado por
389 , ya que esto permitirá el acceso directo al mismo, para la rápida obtención
390 del nro de bloque u offset y posterior búsqueda de un registro en el archivo
397 Los registros de este archivo se encuentran representados a nivel codigo
398 por el siguiente tipo de dato interno (
405 typedef unsigned long EMUFS_REG_ID;
408 typedef unsigned long EMUFS_OFFSET;
411 typedef struct emufs_idx_t {
417 EMUFS_OFFSET location;
426 Ejemplo de registro en archivo índice (.idx), para un archivo de organizacion
436 <lyxtabular version="3" rows="2" columns="3">
438 <column alignment="center" valignment="top" leftline="true" width="0">
439 <column alignment="center" valignment="top" leftline="true" width="0">
440 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
441 <row topline="true" bottomline="true">
442 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
450 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
458 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
466 <row topline="true" bottomline="true">
467 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
475 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
483 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
488 Indica que el registro de id_reg = 5, se encuentra en el bloque 54
505 Ejemplo de registro en archivo índice (.idx), para un archivo de organizacion
515 <lyxtabular version="3" rows="2" columns="3">
517 <column alignment="center" valignment="top" leftline="true" width="0">
518 <column alignment="center" valignment="top" leftline="true" width="0">
519 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
520 <row topline="true" bottomline="true">
521 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
529 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
537 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
545 <row topline="true" bottomline="true">
546 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
554 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
562 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
567 Indica que el registro de id_reg = 5, se encuentra en el bloque 54
587 Como se puede observar, para distintas organizaciones el significado de
588 los registros en este archivo es diferente y se utilizará de distinta manera
595 Las declaraciones e implementación se pueden encontrar en
609 \labelwidthstring 00.00.0000
617 Los registros del archivo indice (
621 ), poseen una correspondencia 1 a 1, con los Id's de los registros en el
627 Con esto, queremos decir que el N-ésimo registro del archivo índice, será
628 aquél que posea la información para localizar al registro cuyo
632 es N, dentro del archivo de datos (
641 NOTA: Cabe aclarar que por si bien el indice se encuentra ordenado por
645 , los registros en el archivo de datos, por lo general no lo estarán.
651 emufs_idx_buscar_registro()
653 \labelwidthstring 00.00.0000
659 Ante la alta de un registro en el archivo de datos, se insetará un nuevo
660 registro en el archivo índice, con el id_reg del registro en cuestion,
661 y el offset u bloque donde se lo haya grabado en disco.
667 \labelwidthstring 00.00.0000
673 Ante el borrado de un registro del archivo de datos, se accederá el registro
674 correspondiente en el índice, y se actualizara su LOCATION, estableciendolo
675 en el valor -1 UL, el cual indica que ese registro ha sido eliminado y
676 por ende no se lo podrá localizar en el futuro.
677 Como se verá mas adelante, según el tipo de organización física, el registro
678 puede ser borrado concretamente del .
689 \labelwidthstring 00.00.0000
695 Ante la modificación en la posición física de un registro dentro del archivo
696 de datos (por ejemplo luego del proceso de recompactación, se realizará
697 la modificación respectiva del campo
705 emufs_idx_actualizar()
709 \begin_inset LatexCommand \label{sec:fsc}
713 Archivo de control de espacio libre
716 El archivo de espacio libre (
720 ) (espacio por bloque o gaps en archivo, según el tipo de organización física),
721 tiene como función la administración del espacio libre, generado por previas
722 eliminaciones de registros en el archivo de datos.
723 El mismo, nos indicará donde hay lugar para insertar un nuevo registro.
726 Para el caso de una organización por bloque, nos dirá en que bloque o si
727 se debe generar un nuevo bloque.
728 En el caso de la organización sin bloques, nos indicará en que gap o si
729 al final del archivo.
732 Los registros de este archivo se encuentran representados una estructura
733 que indica un número de bloque u offset y el espacio libre disponible en
734 el mismo (o apartir del mismo en el caso del offset).
743 : Por requerimiento del algoritmo de compactación el tipo de organización
744 física con reg long var, sin bloques, los gaps se graban en forma ordenada
746 (El orden se corresponde con lo que hay en el .dat).
752 Los registros de este archivo se encuentran representados a nivel codigo
753 por el siguiente tipo de dato interno (
760 typedef struct emufs_fsc_t {
763 unsigned long int marker;
766 unsigned long int freespace;
775 Ejemplo de registro en archivo de espacio libre en bloque (.fsc), para un
776 archivo de organizacion Tipo 1 y 3:
785 <lyxtabular version="3" rows="2" columns="3">
787 <column alignment="center" valignment="top" leftline="true" width="0">
788 <column alignment="center" valignment="top" leftline="true" width="0">
789 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
790 <row topline="true" bottomline="true">
791 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
799 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
807 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
815 <row topline="true" bottomline="true">
816 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
824 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
832 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
837 Indica que en el bloque 12, hay 120 bytes libres al final del mismo.
854 Ejemplo de registro en archivo de gaps o espacios libres en archivo (.fsc),
855 para un archivo de organizacion Tipo 2:
864 <lyxtabular version="3" rows="2" columns="3">
866 <column alignment="center" valignment="top" leftline="true" width="0">
867 <column alignment="center" valignment="top" leftline="true" width="0">
868 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
869 <row topline="true" bottomline="true">
870 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
878 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
886 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
894 <row topline="true" bottomline="true">
895 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
903 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
911 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
916 Indica que a partir del byte 12 del archivo de datos, hay 120 bytes libres.
936 Como se puede observar, para distintas organizaciones el significado de
937 los registros en este archivo es diferente y se utilizará de distinta manera
944 Las declaraciones e implementación se pueden encontrar en
958 \labelwidthstring 00.00.0000
964 Ante la operación de alta de un registro en el archivo de datos, se realizará
965 la búsqueda de espacio libre donde este podrá ser insertado.
966 En el caso de organizaciones con bloques, se buscará en que
970 se posee espacio suficiente para albergar el nuevo registro.
971 En el caso de organizacion sin bloque, se buscará un gap o espacio libre
972 en el archivo, obteniéndose en consecuencia, el
980 emufs_fsc_buscar_lugar()
982 \labelwidthstring 00.00.0000
988 Luego de una operación de baja o alta de un registro en el archivo de datos
993 ), incrementará o decrementará respectivamente el espacio libre en el archivo
994 de datos, y esto deberá ser registrado, agregando un nuevo registro en
995 el archivo de espacios libres (
999 ) o bien modificandoló.
1003 En el caso de organizaciónes con bloques, se actualizará el valor del espacio
1008 en el bloque (ya sea incrementandoló o decrementandoló) o bien se insertará
1009 un nuevo registro en caso de que se esté creando un nuevo bloque en el
1010 archivo de datos (en este caso no será debido a un alta o baja de registro
1011 como se mencionó al principio).
1015 Para el caso de organización sin bloques, en el caso de baja de un registro
1020 ) se insertará un nuevo registro en el
1024 dando cuenta de la aparición de un nuevo gap en el archivo de datos (
1028 ), y en caso de estar este lindante con otro gap, se realizará el merge
1030 (esto esta explicado más en profundidad en los casos particulares de organizaci
1031 ón fisica, registros variables sin bloques).
1032 Para el caso de una alta en el archivo de datos (
1036 ), el valor del gap donde se haya insertado se actualizará.
1041 emufs_fsc_agregar(), emufs_fsc_agregar_gap(), emufs_fsc_actualizar(), emufs_fsc_
1044 \labelwidthstring 00.00.0000
1050 : Unicamente para el caso de una organización que presente gaps en el archivo,
1051 se podrá dar a lugar la eliminación de un registro del archivo de espacios
1057 Esta situación tendrá efecto cuando se inserte un registro que entre perfecto
1058 en un gap disponible, y por ende el gap desaparecerá.
1062 emufs_fsc_borrar_gap()
1066 \begin_inset LatexCommand \label{sec:did}
1070 Archivo de id's recuperables
1073 El archivo de Id's liberado (
1077 ) llevará cuenta de aquellos Id's de registros (
1081 ) que ya no se encuentran siendo utilizados y fueron liberados por registros
1082 eliminados previamente.
1083 A través del mismo, se podrá realizar la reutilización de Id's ante la
1084 alta de nuevos registros.
1087 A nivel físico, este archivo poseerá una secuencia de datos del tipo EMUFS_REG_I
1088 D, y el comportamiento del sistema de recuperación de Id's será el de una
1090 Es decir, ante el requerimiento de un
1094 libre por una función del sistema como por ejemplo la alta de un nuevo
1095 registro, el API del archivo (
1099 ), obtendrá el último dato del mismo (el
1103 que fue liberado mas recientemente), y truncará el archivo eliminando el
1108 recuperado de la tabla.
1109 (LIFO, Last in First Out).
1115 Este archivo tiene registros de un solo campo,
1119 el cual simboliza al id que fue liberado en un proceso de baja de registros.
1125 Las declaraciones e implementación se pueden encontrar en
1139 \labelwidthstring 00.00.0000
1145 Ante la eliminación de un registro del archivo de datos (
1149 ) se procederá al agregado del correspondiente
1153 que fue liberado por dicha operación, al archivo
1167 \labelwidthstring 00.00.0000
1169 Baja Cuando el sistema desee grabar un nuevo registro en el archivo de datos,
1174 disponible para el mismo.
1175 El sistema de administración de Id's libres, obtendrá el último
1179 que se guardó en el archivo (o se eliminó del archivo de datos), y truncará
1180 el archivo eliminandolo.
1188 emufs_did_get_last()
1192 \begin_inset LatexCommand \label{cha:tipo1}
1196 Archivo con bloques parametrizados y registros de longitud variable
1199 Este tipo de archivo tiene varias complicaciones, al tratarse de un punto
1201 \begin_inset LatexCommand \ref{cha:tipo2}
1206 \begin_inset LatexCommand \ref{cha:tipo3}
1210 (cuenta tanto con bloques como con registros variables), hereda los inconvenien
1211 tes (y ventajas) de ambos, más los propios.
1212 Al implementar este tipo de archivo se puso enfásis en la eficiencia mientras
1213 esta no comprometa la mantenibilidad del código, es por esto que en algunas
1214 circunstancias no se hace un uso óptimo del espacio.
1217 La implementación de este tipo de archivo puede ser encontrada en
1221 mientras que su interfaz pública está disponible en
1231 El archivo está compuesto por la
1236 \begin_inset LatexCommand \pageref{sec:cabecera_gral}
1241 El valor que toma en este tipo de archivo es 0 (o el valor simbólico
1250 Luego le sigue una cabecera propia del archivo (un
1254 , 4 bytes) que almacena el tamaño del bloque que usa el archivo.
1255 De esta menera, al abrir un archivo de este tipo no se necesita tener ninguna
1256 información sobre él.
1257 A esta cabecera le siguen cero o más bloques del tamaño fijo especificado
1258 en la cabecera antes mencionada.
1264 +-----------+-----------+------------------------//-+
1267 | tipo | tam bloque| Cero o más bloques ...
1275 +-----------+-----------+------------------------//-+
1278 /- 4 bytes -/- 4 bytes -/
1281 Organización física de un bloque
1284 Cada bloque no guarda información en sí, sólo se comporta como un contenedor
1286 Esto no significa que un bloque no tenga utilidad, el bloque es utilizado
1287 para proveer un acceso semi-aleatorio a los registros.
1288 Para esto se utiliza el archivo de índice (ver página
1289 \begin_inset LatexCommand \ref{sec:idx}
1293 ), que almacena pares (identificador de registro, número de bloque).
1294 Para que sea suficiente este único índice para hallar un registro (siendo
1295 que puede haber más de un registro por bloque), es necesario
1297 alinear los registros a izquierda
1302 bloque N-1 | bloque N | bloque N+1
1305 /----------+------------+------------+-------------------+-----------/
1310 | registro 1 | registro 2 | espacio libre ...
1313 /----------+------------+------------+-------------------+-----------/
1316 De forma tal que una vez obtenido el número de bloque se pueda recorrer
1317 secuencialmente hasta encontrar el registro deseado.
1318 A fin de llevar el conteo de espacio libre se utiliza el archivo de control
1319 de espacio libre (ver página
1320 \begin_inset LatexCommand \ref{sec:fsc}
1324 ), de forma tal que no sea necesario recorrer secuencialmente en busca de
1325 espacio libre al hacer una inserción.
1328 Puede darse un caso excepcional en el que un registro sea más grande que
1329 un bloque, en este caso el registro se almacenará en N bloques consecutivos
1330 (siendo N la cantidad de bloques que necesita el registro), ocupando completos
1331 los todos los bloques a excepción del último, en el que posteriormente
1332 se pueden agregar más registros.
1335 Comportamiento (funciones de la interfáz)
1338 Detalles de implementación (funciones internas, ver si lo ponemos o no)
1342 \begin_inset LatexCommand \label{cha:tipo2}
1346 Archivo sin bloques y registros de longitud variable
1349 Este tipo de archivo nos traerá a la mesa la particularidad de grabar registros
1350 de longitud variable sin realizar su agrupación en bloques, y como veremos
1351 en la siguiente sección, tambien permitirá la administración de gaps que
1352 queden en el archivo luego de operaciones de baja de registros.
1358 Este tipo de archivo realizará el almacenamiento de registros de longitud
1359 variable en disco, su borrado y modificación sin la utilización de bloques
1361 Su implementación se encuentra en los archivos fuente (
1372 Los archivos del tipo 2, presentarán al comienzo del mismo un header compuesto
1373 simplemente por un dato del tipo EMUFS_Tipo (int) el cual indicará el tipo
1374 de archivo en cuestión.
1377 Para poder entender mejor la organización fisica de este tipo de archivo,
1378 tomemos el caso hipotético en el que se encuentran grabados
1382 (comenzando desde registro 0) de
1391 Supongamos también que entre el registro 0 y 1 se encontraba un
1393 registro de 10 bytes
1408 Si miramos al archivo de datos (.dat) en el disco nos encontraremos con
1410 \begin_inset Float figure
1417 Organización física de los registros en disco
1421 \begin_inset Graphics
1422 filename graphics/Example1.png
1433 Como se puede observar, a nivel físico cada registro grabado esta compuesto
1434 por un Header cuyo tamaño total es de 8 bytes (
1442 ), y posteriormente el registro (bloque de datos) en sí.
1443 Luego se encuentra el espacio libre de 18 bytes dejado por el registro
1444 de 10 bytes eliminado (10 bytes de datos + header de 8 bytes) y finalmente
1445 el segundo registro mencionado.dsds
1448 Comportamiento Particular de los Archivos Auxiliares
1451 Como fue explicado al inicio de la documentación, la implementación de cualquier
1452 a de las tres organizaciones físicas de archivos presenta la necesidad de
1453 poseer tres archivos auxiliares que actuarán como índice de direcciones
1458 ), administrador de espacio libre (
1462 ) y administrador de Id's liberados (
1469 No obstante, cada tipo de organización presentara sus particularidades respecto
1470 de estos tres archivos, las cuales describiremos a continuación en caso
1472 \layout Subsubsection
1474 Archivo índice o de posiciones relativas (.idx)
1481 ), permite la localizacin de los registros en el .DAT de forma directa, mediante
1482 la obtención de su offset o posición relativa respecto del inicio del
1486 en donde se encuentra un registro dado, indicado por su ID.
1489 Así pues, si tomamos el ejemplo descripto al inicio de este capítudlo, tendremos
1490 las siguientes entradas en el archivo indice
1500 \begin_inset Tabular
1501 <lyxtabular version="3" rows="3" columns="3">
1503 <column alignment="center" valignment="top" leftline="true" width="0">
1504 <column alignment="center" valignment="top" leftline="true" width="0">
1505 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
1506 <row topline="true" bottomline="true">
1507 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1517 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1527 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1535 <row topline="true">
1536 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1546 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1556 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1561 El primer registro (reg0) comienza en el byte 4
1565 <row topline="true" bottomline="true">
1566 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1574 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1584 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1589 El segundo registro (reg1) comienza en el byte 60
1609 LOCATION indica donde comienza el header del registro buscado, y por consiguien
1610 te luego del header tendremos el registro en sí (los datos).
1611 \layout Subsubsection
1613 Achivo de Gaps / Espacios Libres (.fsc)
1616 El archivo de espacios libres o gaps (.fsc), tiene como función la administracion
1617 del espacio libre o gaps (agujeros), generados por previas eliminaciones
1618 de registros en el archivo de datos.
1619 El mismo, nos indicará donde hay lugar para insertar un nuevo registro
1620 (se podrán insertar en algún gap acorde, o bien al final del archivo).
1621 Este archivo será utilizado tambien para el proceso de compactación de
1622 un archivo, explicado luego.
1625 Así pues, si tomamos el ejemplo descripto al inicio del documento, tendremos
1626 las siguientes entradas en el archivo índice
1635 \begin_inset Tabular
1636 <lyxtabular version="3" rows="2" columns="3">
1638 <column alignment="center" valignment="top" leftline="true" width="0">
1639 <column alignment="center" valignment="top" leftline="true" width="0">
1640 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
1641 <row topline="true" bottomline="true">
1642 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1652 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1662 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1670 <row topline="true" bottomline="true">
1671 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1681 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1691 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1696 18 bytes libres a partir del byte 42 del .dat
1716 Por requerimiento del algoritmo de compactación, los gaps se graban en
1717 forma ordenada en el (.fsc).
1718 (El orden se corresponde con lo que hay en el .dat)
1719 \layout Subsubsection*
1724 Si bien la utilización concreta de los GAPS será explicada posteriormente
1725 en la ALTA y BAJA de registros, debemos remarcar la funcionalidad de MERGING
1726 que posee nuestro sistema FSC.
1729 Ante la eliminación de un registro del archivo de datos, se generara por
1730 consiguiente un gap o espacio libre en alguna posición del archivo.
1731 Ese gap deberá ser registrado en el archivo de gaps (.fsc).
1732 Ahora bien, nuestro sistema de gaps, contemplará como es debido, la posibilidad
1733 de que se haya eliminado un registro que posee un GAP por delante, un GAP
1734 por detrás, o bien un GAP por delante y por detrás del mismo.
1737 Nuestro sistema actuará en consecuencia, realizando un merge de los espacios
1738 libres, y unificándolos en una UNICA entrada en el archivo .fsc, que contendrá
1739 como dato de freespace, la suma correspondiente de los espacios libres
1741 \layout Subsubsection
1743 Archivo de ID's liberados (.did)
1746 El archivo de ID's liberados no presenta ningún aspecto particular en este
1747 tipo de organización.
1748 Remitirse al capítulo correspondiente a los archivos auxiliares para consultar
1749 su estructura y funcionamiento.
1752 Comportamiento (funciones de la interfaz)
1767 se encuentran las cabeceras y la implementación de las funciones principales
1768 respectivamente, las cuales dan funcionalidad a esta organización.
1772 A continuación se comentará el funcionamiento algunas de las mas importantes.
1775 Lectura de registros
1778 Como se vió al comienzo, los registros en este tipo de archivo no se encuentran
1779 agrupados en bloques de ninguna índole y estan dispersos a lo largo del
1780 archivo, con la particularidad de que pueden existir gaps o espacio libre,
1781 entre dos registros dados.
1784 Por ende la lectura de registros en este tipo de organización es muy simple
1785 y dada la inexistencia de bloques, el procedimiento será el siguiente:
1788 Se determina el offset en bytes, donde comienza el registro deseado, a través
1789 de su ID, buscando la misma en el archivo índice (
1796 Ya determinada la posición física del registro dentro del archivo de datos
1801 ), nos posicionamos en la misma, y leemos el header del registro (
1810 Contando así con el tamaño del registro, procedemos a leer el mismo (los
1811 datos), dando por finalizada la lectura.
1816 emufs_tipo2_leer_registro()
1822 En el proceso de alta de registros entrarán en juego dos archivos descriptos
1825 sección de archivos auxiliares
1827 , siendo estos el archivo índice (
1831 ), y el archivo de gaps / espacios libres (
1838 Así pues, a la hora de realizar una inserción de un registro en el archivo
1839 de datos, el procedimiento será el siguiente:
1842 Calculamos el espacio que necesitaremos para el registro: sizeof(
1850 ) + sizeof(registro).
1853 Determinamos donde debemos insertar el registro, ya sea un gap donde entre,
1854 o bien al final del archivo.
1857 Insertamos el registro e información de control (
1865 ), en la posición indicada en el paso 2.
1868 En caso de haber utilizado un GAP, actualizamos el espacio libre restante
1869 en el mismo y en caso de que se haya utilizado al totalidad del GAP, se
1870 lo elimina del archivo (
1877 Actualizamos la entrada correspondiente al registro ingresado (determinada
1878 por su RegID), en el archivo índice (
1882 ), indicando su offset donde podrá ser accedido luego.
1887 emufs_tipo2_agregar_registro()
1893 En el proceso de baja de registros entrarán en juego los tres archivos descripto
1896 sección de archivos auxiliares
1898 , siendo estos el archivo índice (
1902 ), el archivo de gaps / espacios libres (
1906 ) y el archivo de ID's liberados (
1913 Dado que en la implementación de este tipo de organización física contamos
1914 con los gaps o espacios libres entre registros, no se eliminará fisicamente
1915 el registro del archivo de datos (
1919 ), pues entonces carecería de sentido el archivo anteriormente mencionado
1925 En cambio, se agrega el gap dejado por la eliminación a dicho archivo,
1926 y se marca fisicamente en el archivo de datos la eliminación mediante un
1927 fill de los bytes correspondientes con un caracter nulo.
1928 (hexa 00 y con el propósito de probar fehacientemente que el sistema funciona).
1931 El proceso de baja o eliminación de un registro constará luego de los siguientes
1935 Se obtiene el offset o posición relativa en donde se encuentra grabado el
1936 registro dentro del archivo de datos.
1939 Se obtiene el tamaño del registro y se realiza un dummyfill del sector del
1940 archivo correspondiente al registro que se está dando de baja.
1941 (Se rellena la zona correspondiente a su header+data).
1944 Se agrega el GAP generado al archivo de gaps o espacios libres, y en caso
1945 de haberse generado un GAP lindante con otro GAP, se realizará un merge
1946 de los mismos y se los registrará bajo una única entrada en el archivo
1947 de espacios libres (.fsc).
1950 Se agrega el ID que fue liberado, al archivo de ID's liberados (
1954 ), al final del mismo (
1961 Se marca en el archivo índice (
1965 ) la eliminación, mediante el valor ¨-1¨ en el registro correspondiente
1966 al registro recién eliminado (se le cambia el valor al n-esimo registro,
1967 donde N = IDReg del reg eliminado).
1972 emufs_tipo2_borrar_registro()
1975 Modificación de registros
1978 Dada la naturaleza del archivo de ID's liberados, y el manejo de espacio
1979 libre del que consta esta organización de archivo, el proceso de modificación
1980 de un registro se limita a los siguientes pasos:
1983 Se realiza la lectura del registro, mediante el respectivo procedimiento
1984 ya desarollado anteriormente.
1987 Una vez que se cuenta con los nuevos datos modificados, se procede a dar
1988 de baja el registro que ha sido modificado, e inmediatamente después se
1989 realiza una inserción con los nuevos datos.
1998 Como fue indicado, dada la naturaleza de PILA del subsistema de administración
1999 de ID liberados, es asegurado que la nueva inserción del registro modificado
2000 se realizará con el mismo RegID.
2005 emufs_tipo2_modificar_registro()
2008 Obtención de estadísticas
2011 Se puede tener acceso a las estadísticas generales del archivo, por ejemplo,
2012 cantidad de bloques, cantidad de registros, espacio libre total, espacio
2013 libre promedio, espacio libre máximo y mínimo, etc.
2016 Esta información es el resultado de ciertos cálculos realizados tanto en
2017 el archivo de datos como en los archivos índice.
2020 Completa una estructura del tipo EMUFS_Estadisticas con las estadísticas
2021 del archivo de datos, espacio libre total, cantidad de registros, cantidad
2022 de bloques, tamaño del archivo en bytes, relaciones entre tamaños y espacios
2028 emufs_tipo2_leer_estadisticas()
2031 Compactación del archivo de datos
2034 Asi como los otros dos tipos de datos, el que nos compete también cuenta
2035 con la posibilidad de realizar la compactación de datos cuando el usuario
2036 lo desee, justificando todos los registros a izquierda, eliminando así
2037 los gaps existentes y decrementando el tamaño del archivo en disco (truncandolo
2041 Para poder comprender como hemos implementado el proceso de recompactación
2042 en nuestro tipo de archivo 2, nos ayudaremos de esquemas a través de los
2043 cuales iremos describiendo el proceso.
2044 Notemos antes, que el proceso de compactación esta directamente ligado
2045 con el archivo de gaps o espacios libres (
2052 Comenzemos con el siguiente cuadro situacional:
2053 \begin_inset Float figure
2060 Archivo con gaps entre registros previo a compactación
2064 \begin_inset Graphics
2065 filename graphics/Compact1.png
2077 Partiendo de esta base, el algoritmo de compactación tomará en su inicio
2078 al primer gap existente dentro del archivo de datos, en este caso llamado
2084 Luego, establecerá que el
2088 a partir de donde se quieren mover datos, sera:
2091 StartGap0 + SizeGap0 = EndGap0 = Source
2094 Lo cual no es nada más y nada menos que lo obvio, la fuente a partir de
2095 donde se mueven los datos, sera el fin del primer gap, donde comienzan
2101 ) del movimiento, se establece inicialmente, el inicio del gap, o sea
2103 StartGap0 = Destination
2108 Luego, el algoritmo entrara en un bucle while (mientras haya bucles por
2109 levantar), el cual trabajara hasta el final de la compactación de la siguiente
2120 Se levanta el proximo gap al levantado en una instancia previa.
2121 En este ejemplo, durante el primer loop del while, se levantará
2126 Luego, se calcula cuantos bytes hay que mover hacia el Destination de la
2150 Lo cual nuevamente es lógico pues querremos mover lo que se encuentra entre
2151 el final del primer gap levantado y el inicio del siguiente).
2154 Se realiza el movimiento de los datos, utilizando las direcciones
2162 , así como la variable
2166 que nos indica cuantos bytes transferir.
2172 La transferencia se hace de a chunks de 25 bytes + un resto segun el valor
2176 Se establece como gap de referencia, al ultimo gap leido (En este caso se
2189 ) y termina el código de repetición del bucle, dando lugar a la carga del
2190 siguiente gap en el inicio del mismo.
2198 Luego del primer bucle, el archivo se vera de la siguiente forma:
2199 \begin_inset Float figure
2206 Archivo con gaps en disco luego del primer bucle de compactación
2210 \begin_inset Graphics
2211 filename graphics/Compact2.png
2222 Notemos que al final de la porción de datos de los bytes movidos (donde
2227 ), hay basura que será pisada por el próximo movimiento.
2230 En el próximo loop, el bucle levantará un nuevo gap, y utilizando el gap
2231 anterior (En esta caso el Gap anterior será
2235 ) como referencia, realizará los mismos cálculos, desde donde transferir
2236 y cuantos bytes mover.
2237 (El destino es solo establecido inicialmente por código, y para el resto
2238 del algoritmo es el lugar donde quedo el puntero destination luego de la
2242 Una vez que se salga del bucle while, se realizará un último movimiento
2243 preprogramado, donde la fuente (
2247 ) será el final del ultimo gap, y la cantidad de bytes a mover será lo que
2248 se encuentre luego del mismo hasta el fin de archivo.
2251 Source = StartLastGap + SizeLastGap = EndLastGap
2254 Mustmove_bytes = Datsize - Source
2257 Damos por terminada así, la explicación del algoritmo de compresión el cual
2258 para el caso del tipo 2, es realmente bastante sencillo.
2263 void emufs_tipo2_compactar()
2266 Consideraciones y Políticas de Diseño
2269 Se han tomado ciertas consideraciones para algunos casos particulares que
2270 se pueden presentar durante el uso/ejecución de la aplicación, así como
2271 tambien politicas respecto del diseño e implementación del sistema:
2274 En la organización física tipo 2 para los registros que se graban en disco
2275 hemos decidido utilizar como encabezado de cada uno de ellos, los datos
2276 [ID_REG][REG_SIZE], los cuales fueron detallados previamente.
2277 Si bien se podría haber descartado el grabado del ID del registro en el
2278 archivo de datos y puede parecer redundante, dado que poseemos el archivo
2279 índice con el offset directo, el mismo se lo graba por distintos motivos:
2283 A) En caso de la corrupción del archivo índice (.idx), podremos gracias a
2284 que poseemos en el archivo de datos, el ID de cada registro, recrear dicho
2285 índice, ayudándonos del archivo de espacios libres (
2289 ), para poder saltear los espacios libres y e ir recorriendo secuencialmente
2290 los registros, reconstruyendo así el índice en cuestión.
2291 (esta función de reconstrucción no pudo ser implementada para esta entrega,
2292 pero es una posibilidad real).
2296 B) Luego de un proceso de recompactación, los espacios libres que pudieron
2297 haber existido en el archivo de datos (
2301 ), son eliminados y los registros han cambiado de posición.
2302 Por ello, recorriendo secuencialmente por única vez el archivo de datos,
2303 se procede a la actualización / reconstrucción del índice de direcciones
2311 Si se desea insertar un registro y no se puede hayar un gap o espacio libre
2312 donde quepa, se los inserta al final del archivo.
2315 Ante una operación de baja de un registro, el mismo no es físicamente borrado
2316 del archivo de datos (
2320 ), simplemente los bytes que ocupa son llenados con hexa (00).
2321 Paralelamente, se procede a actualiza el archivo índice, insertando como
2322 valor de OFFSET para el registro eliminado, el valor ¨-1¨, indicando así
2323 la inexistencia del registro para el futuro, y por otro lado se genera
2324 la entrada de espacio libre en el archivo de gaps (
2331 La reutilización de ID's liberados por previas operaciones de baja de registros,
2332 se ve implementada por el archivo de ID liberados (.did), y su comportamiento
2333 es el de una pila por lo que el último ID liberado, sera el próximo a ser
2337 Como fue explicado en la implementación del archivo índice, existe una correspon
2338 dencia 1 a 1 entre los registros allí presentes (en el .idx) y los ID's de
2339 los registros, por lo cual el registro N-ésimo del archivo índice, será
2340 el correspondiente al registro de datos cuyo ID es igual a N.
2343 El proceso de compactación de archivos, realiza los movimientos de información
2344 requeridos para dicho propósito de a chunks de 25 bytes por vez.
2345 Este valor es fijo, pero se lo podría hacer parametrizable mediante la
2346 GUI en próximas entregas.
2350 \begin_inset LatexCommand \label{cha:tipo3}
2354 Archivo con bloques parametrizados y registros de longitud constante
2357 Las distintas organizaciones de archivos buscan aprovechar al máximo el
2358 espacio del archivo.
2361 En este caso veremos que sucede luego de agregar y borrar una gran cantidad
2362 de registros del archivo, lo que provoca como consecuencia directa la fragmenta
2363 ción del archivo, es decir, quedan huecos entre un registro y otro, lo que
2364 produce un desperdicio de espacio.
2370 Esta organización guarda los registros pertenecientes al archivo en bloques
2371 de tamaño parametrizado, de modo que intentará guardar la mayor cantidad
2372 de registros que quepan en un bloque.
2376 Así como los graba, también tendrá la posibilidad de leer registros y borrarlos
2380 Comportamiento Particular de los Archivos Auxiliares
2381 \layout Subsubsection
2383 Archivo de Bloques y Registros (.idx)
2386 buscar algun caso extraordinario.
2387 \layout Subsubsection
2389 Archivo de Bloques y Espacio Libre (.fsc)
2390 \layout Subsubsection
2392 Archivo de Id`s Borrados (.did)
2395 El comportamiento de este archivo, es común para todas las organizaciones
2396 y se ha explicado en 3.3.2.
2399 Funciones Principales
2413 se encuentran las cabeceras y la implementación de las funciones principales
2414 respectivamente, las cuales dan funcionalidad a esta organización.
2417 A continuación se comentará la descripción de algunas acciones importantes.
2418 \layout Subsubsection
2423 La lectura de un registro se realiza con la ayuda del archivo .
2427 el cual contiene la información de la posición del registro dentro del
2429 Una vez leida esta información, se recupera el bloque (en su totalidad)
2430 del archivo y se busca secuencialmente el registro con el
2439 emufs_tipo3_leer_registro()
2440 \layout Subsubsection
2445 Graba un registro en un bloque donde haya espacio suficiente, y si no crea
2446 un nuevo bloque y lo agrega al final del archivo.
2449 Luego de grabar un registro, actualiza los archivos de índice .idx y .fsc
2450 para mantener la coherencia.
2455 emufs_tipo3_grabar_registro()
2456 \layout Subsubsection
2461 Borra un registro del archivo de datos, para esto levanta el bloque al que
2462 pertenece el archivo y ajusta los demás registros justificandolos hacia
2466 Cabe destacar que para dar de baja un registro no hace falta borrarlo del
2467 archivo de datos, solo es necesario borrar las entradas en los archivos
2468 de índice, pero cuando se realiza el ajuste el algoritmo toma porciones
2469 del bloque del tamaño de un registro mas su encabezado - comenzando desde
2470 el siguiente al que fue borrado - y copia (sobreescribe) sobre el anterior.
2471 De esta manera, la información correspondiente al registro borrado no estará
2472 presente en el archivo de datos.
2473 Esto es una consecuencia del ajuste al borrar un registro, pudiendo no
2474 ser así, si no se realizara el mismo.
2475 \layout Subsubsection
2480 Se puede tener acceso a las estadísticas generales del archivo, por ejemplo,
2481 cantidad de bloques, cantidad de registros, espacio libre total, espacio
2482 libre promedio, espacio libre máximo y mínimo, etc.
2485 Esta información es el resultado de ciertos cálculos realizados tanto en
2486 el archivo de datos como en los archivos índice.
2489 Completa una estructura del tipo EMUFS_Estadisticas con las estadísticas
2490 del archivo de datos, espacio libre total, cantidad de registros, cantidad
2491 de bloques, tamaño del archivo en bytes, relaciones entre tamaños y espacios
2497 emufs_tipo3_leer_estadisticas()
2498 \layout Subsubsection
2500 Compactar el Archivo
2503 Esta función intenta reorganizar el archivo de manera que el espacio libre
2504 sea lo menor posible, recordando siempre que un registro no puede ser almacenad
2505 o en mas de un bloque excepto que el tamaño del registro sea mayor que el
2509 Para realizar esto, se aprovecha la funcionalidad de
2511 emufs_tipo3_grabar_registro()
2513 ya que esta tiene la capacidad de determinar una posición mas eficiente
2514 en el archivo para un registro.
2515 Por esto lo que se hace es levantar uno por uno los registros y volverlos
2516 a grabar, de ese modo todos los
2520 que pudieron haberse formado por la eliminación de registros serán cubiertos
2524 Al estar utilizando recuperación de
2528 borrados, esto me asegura que el registro borrado-guardado conservará el
2532 Al finalizar este proceso se verifica si existen bloques vacios para truncar
2534 Lo mismo se debe hacer con el archivo de espacios libres .
2538 el cual disminuye su tamaño también.
2543 void emufs_tipo3_compactar()
2546 Consideraciones y Políticas de Diseño
2549 Esto para mi va en organización física.
2552 Se han tomado ciertas consideraciones para algunos casos particulares que
2553 se pueden presentar durante el uso/ejecución de la aplicación.
2556 Cada registro tiene un encabezado que indica el
2563 Si el tamaño del registro es mayor que el tamaño del bloque el registro
2564 se particionará en la cantidad de bloques que sea necesario, pero siempre
2565 se guardará desde el comienzo de un bloque, esto quiere decir que nunca
2566 se podrá encontrar un comienzo de registro en algún lugar de un bloque
2567 que no sea el comienzo del mismo.
2570 Si el registro se divide en mas de un bloque, se le coloca el id como encabezado
2571 igualmente, pero en el archivo .
2575 solo se guarda el primer bloque.
2580 se actualizan todos los bloques con el espacio libre que realmente tienen.
2586 Las comparaciones, pruebas, etc...