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 Por que los 3 tipos usan lo mismo.
328 Ventajas y desventajas.
332 \begin_inset LatexCommand \label{sec:idx}
339 Con la ayuda de un archivo de bloques y registros (de extensión .idx), podremos
340 ubicar cualquier registro existente dentro del archivo.
343 El archivo de índice contiene una estructura que contiene el id de un registro
344 y el número de bloque al que pertenece.
345 Este archivo esta ordenado por
349 , de modo que incrementa su tamaño cada vez que se grabe en el archivo de
350 datos un nuevo registro, excepto que un registro haya sido borrado con
351 anterioridad lo cual produce que al guardar un nuevo registro se actualice
355 Si un registro es borrado del archivo de datos, debe actualizarse el índice,
356 esto se logra colocando un flag que indique que el
360 no pertenece a ningún bloque, hemos adoptado poner -1 en el campo location
368 Es necesario que este archivo esté ordenado por
372 de registro, ya que esto permitirá el acceso directo para la búsqueda de
373 un registro en el archivo de datos.
383 define la estuctura de los registros de este archivo.
386 Esta estructura está compuesta por:
404 location número de bloque donde se encuentra el registro.
423 Comportamiento (funciones generales)
427 \begin_inset LatexCommand \label{sec:fsc}
431 Archivo de control de espacio libre
434 El archivo de de espacios libres permite decidir a la hora de guardar un
435 registro, donde será guardado.
439 La estructura de este archivo está formada por un número que indica el bloque
440 y otro que indica el espacio libre en él.
443 De esta manera al querer guardar un registro este archivo informará donde
444 cabe el mismo, previa invocación al la función
446 EMUFS_BLOCK_ID emufs_fsc_buscar_lugar(EMUFS *, EMUFS_FREE, EMUFS_FREE*)
452 la cual devuelve el número de bloque donde entra el registro o -1 si no
453 hay un bloque con lugar suficiente, y toma como parámetros una estructura
462 donde el segndo parámetro es el tamaño buscado, y el tercero devuelve el
466 De la misma manera, al borrar un registro este archivo debe ser actualizado
467 colocando el nuevo espacio libre en el bloque.
473 La estuctura que define este archivo es la siguiente:
487 indica el número de bloque
494 freespace indica la cantidad de espacio libre que queda en el bloque.
514 \begin_inset LatexCommand \label{sec:did}
518 Archivo de índices recuperables
521 Este archivo funciona como una pila de i
525 borrados, es decir, cuando se borra un registro el
529 se almacena en este archivo y será recuperado cuando se desee grabar un
530 registro nuevo, de esta manera se aprovechan todos los
534 sin necesidad de crear uno nuevo cada vez que se borra y graba un registro.
540 Este archivo tiene registros de un solo campo,
544 el cual simboliza al id almacenado.
550 Las declaraciones e implementación se pueden encontrar en
569 al archivo, el cual será el primero recuperado.
572 Ver: emufs_did_agregar()
583 que se guardó en el archivo (o se eliminó del archivo de datos), y trunca
587 Ver: emufs_did_get_last()
591 \begin_inset LatexCommand \label{cha:tipo1}
595 Archivo con bloques parametrizados y registros de longitud variable
598 Este tipo de archivo tiene varias complicaciones, al tratarse de un punto
600 \begin_inset LatexCommand \ref{cha:tipo2}
605 \begin_inset LatexCommand \ref{cha:tipo3}
609 (cuenta tanto con bloques como con registros variables), hereda los inconvenien
610 tes (y ventajas) de ambos, más los propios.
611 Al implementar este tipo de archivo se puso enfásis en la eficiencia mientras
612 esta no comprometa la mantenibilidad del código, es por esto que en algunas
613 circunstancias no se hace un uso óptimo del espacio.
616 La implementación de este tipo de archivo puede ser encontrada en
620 mientras que su interfaz pública está disponible en
630 El archivo está compuesto por la
635 \begin_inset LatexCommand \pageref{sec:cabecera_gral}
640 El valor que toma en este tipo de archivo es 0 (o el valor simbólico
649 Luego le sigue una cabecera propia del archivo (un
653 , 4 bytes) que almacena el tamaño del bloque que usa el archivo.
654 De esta menera, al abrir un archivo de este tipo no se necesita tener ninguna
655 información sobre él.
656 A esta cabecera le siguen cero o más bloques del tamaño fijo especificado
657 en la cabecera antes mencionada.
663 +-----------+-----------+------------------------//-+
666 | tipo | tam bloque| Cero o más bloques ...
674 +-----------+-----------+------------------------//-+
677 /- 4 bytes -/- 4 bytes -/
680 Organización física de un bloque
683 Cada bloque no guarda información en sí, sólo se comporta como un contenedor
685 Esto no significa que un bloque no tenga utilidad, el bloque es utilizado
686 para proveer un acceso semi-aleatorio a los registros.
687 Para esto se utiliza el archivo de índice (ver página
688 \begin_inset LatexCommand \ref{sec:idx}
692 ), que almacena pares (identificador de registro, número de bloque).
693 Para que sea suficiente este único índice para hallar un registro (siendo
694 que puede haber más de un registro por bloque), es necesario
696 alinear los registros a izquierda
701 bloque N-1 | bloque N | bloque N+1
704 /----------+------------+------------+-------------------+-----------/
709 | registro 1 | registro 2 | espacio libre ...
712 /----------+------------+------------+-------------------+-----------/
715 De forma tal que una vez obtenido el número de bloque se pueda recorrer
716 secuencialmente hasta encontrar el registro deseado.
717 A fin de llevar el conteo de espacio libre se utiliza el archivo de control
718 de espacio libre (ver página
719 \begin_inset LatexCommand \ref{sec:fsc}
723 ), de forma tal que no sea necesario recorrer secuencialmente en busca de
724 espacio libre al hacer una inserción.
727 Puede darse un caso excepcional en el que un registro sea más grande que
728 un bloque, en este caso el registro se almacenará en N bloques consecutivos
729 (siendo N la cantidad de bloques que necesita el registro), ocupando completos
730 los todos los bloques a excepción del último, en el que posteriormente
731 se pueden agregar más registros.
734 Comportamiento (funciones de la interfáz)
737 Detalles de implementación (funciones internas, ver si lo ponemos o no)
741 \begin_inset LatexCommand \label{cha:tipo2}
745 Archivo sin bloques y registros de longitud variable
748 Este tipo de archivo nos traerá a la mesa la particularidad de grabar registros
749 de longitud variable sin realizar su agrupación en bloques, y como veremos
750 en la siguiente sección, tambien permitirá la administración de gaps que
751 queden en el archivo luego de operaciones de baja de registros.
757 Este tipo de archivo realizará el almacenamiento de registros de longitud
758 variable en disco, su borrado y modificación sin la utilización de bloques
760 Su implementación se encuentra en los archivos fuente (
771 Los archivos del tipo 2, presentarán al comienzo del mismo un header compuesto
772 simplemente por un dato del tipo EMUFS_Tipo (int) el cual indicará el tipo
773 de archivo en cuestión.
776 Para poder entender mejor la organización fisica de este tipo de archivo,
777 tomemos el caso hipotético en el que se encuentran grabados
781 (comenzando desde registro 0) de
790 Supongamos también que entre el registro 0 y 1 se encontraba un
807 Si miramos al archivo de datos (.dat) en el disco nos encontraremos con
809 \begin_inset Float figure
816 Organización física de los registros en disco
820 \begin_inset Graphics
821 filename graphics/Example1.png
832 Como se puede observar, a nivel físico cada registro grabado esta compuesto
833 por un Header cuyo tamaño total es de 8 bytes (
841 ), y posteriormente el registro (bloque de datos) en sí.
842 Luego se encuentra el espacio libre de 18 bytes dejado por el registro
843 de 10 bytes eliminado (10 bytes de datos + header de 8 bytes) y finalmente
844 el segundo registro mencionado.dsds
847 Comportamiento Particular de los Archivos Auxiliares
850 Como fue explicado al inicio de la documentación, la implementación de cualquier
851 a de las tres organizaciones físicas de archivos presenta la necesidad de
852 poseer tres archivos auxiliares que actuarán como índice de direcciones
857 ), administrador de espacio libre (
861 ) y administrador de Id's liberados (
868 No obstante, cada tipo de organización presentara sus particularidades respecto
869 de estos tres archivos, las cuales describiremos a continuación en caso
871 \layout Subsubsection
873 Archivo índice o de posiciones relativas (.idx)
880 ), permite la localizacin de los registros en el .DAT de forma directa, mediante
881 la obtención de su offset o posición relativa respecto del inicio del
885 en donde se encuentra un registro dado, indicado por su ID.
888 Así pues, si tomamos el ejemplo descripto al inicio de este capítudlo, tendremos
889 las siguientes entradas en el archivo indice
900 <lyxtabular version="3" rows="3" columns="3">
902 <column alignment="center" valignment="top" leftline="true" width="0">
903 <column alignment="center" valignment="top" leftline="true" width="0">
904 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
905 <row topline="true" bottomline="true">
906 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
916 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
926 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
935 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
945 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
955 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
960 El primer registro (reg0) comienza en el byte 4
964 <row topline="true" bottomline="true">
965 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
973 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
983 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
988 El segundo registro (reg1) comienza en el byte 60
1008 LOCATION indica donde comienza el header del registro buscado, y por consiguien
1009 te luego del header tendremos el registro en sí (los datos).
1010 \layout Subsubsection
1012 Achivo de Gaps / Espacios Libres (.fsc)
1015 El archivo de espacios libres o gaps (.fsc), tiene como función la administracion
1016 del espacio libre o gaps (agujeros), generados por previas eliminaciones
1017 de registros en el archivo de datos.
1018 El mismo, nos indicará donde hay lugar para insertar un nuevo registro
1019 (se podrán insertar en algún gap acorde, o bien al final del archivo).
1020 Este archivo será utilizado tambien para el proceso de compactación de
1021 un archivo, explicado luego.
1024 Así pues, si tomamos el ejemplo descripto al inicio del documento, tendremos
1025 las siguientes entradas en el archivo índice
1034 \begin_inset Tabular
1035 <lyxtabular version="3" rows="2" columns="3">
1037 <column alignment="center" valignment="top" leftline="true" width="0">
1038 <column alignment="center" valignment="top" leftline="true" width="0">
1039 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
1040 <row topline="true" bottomline="true">
1041 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1051 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1061 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1069 <row topline="true" bottomline="true">
1070 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1080 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1090 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1095 18 bytes libres a partir del byte 42 del .dat
1115 Por requerimiento del algoritmo de compactación, los gaps se graban en
1116 forma ordenada en el (.fsc).
1117 (El orden se corresponde con lo que hay en el .dat)
1118 \layout Subsubsection*
1123 Si bien la utilización concreta de los GAPS será explicada posteriormente
1124 en la ALTA y BAJA de registros, debemos remarcar la funcionalidad de MERGING
1125 que posee nuestro sistema FSC.
1128 Ante la eliminación de un registro del archivo de datos, se generara por
1129 consiguiente un gap o espacio libre en alguna posición del archivo.
1130 Ese gap deberá ser registrado en el archivo de gaps (.fsc).
1131 Ahora bien, nuestro sistema de gaps, contemplará como es debido, la posibilidad
1132 de que se haya eliminado un registro que posee un GAP por delante, un GAP
1133 por detrás, o bien un GAP por delante y por detrás del mismo.
1136 Nuestro sistema actuará en consecuencia, realizando un merge de los espacios
1137 libres, y unificándolos en una UNICA entrada en el archivo .fsc, que contendrá
1138 como dato de freespace, la suma correspondiente de los espacios libres
1140 \layout Subsubsection
1142 Archivo de ID's liberados (.did)
1145 El archivo de ID's liberados no presenta ningún aspecto particular en este
1146 tipo de organización.
1147 Remitirse al capítulo correspondiente a los archivos auxiliares para consultar
1148 su estructura y funcionamiento.
1151 Comportamiento (funciones de la interfaz)
1166 se encuentran las cabeceras y la implementación de las funciones principales
1167 respectivamente, las cuales dan funcionalidad a esta organización.
1171 A continuación se comentará el funcionamiento algunas de las mas importantes.
1174 Lectura de registros
1177 Como se vió al comienzo, los registros en este tipo de archivo no se encuentran
1178 agrupados en bloques de ninguna índole y estan dispersos a lo largo del
1179 archivo, con la particularidad de que pueden existir gaps o espacio libre,
1180 entre dos registros dados.
1183 Por ende la lectura de registros en este tipo de organización es muy simple
1184 y dada la inexistencia de bloques, el procedimiento será el siguiente:
1187 Se determina el offset en bytes, donde comienza el registro deseado, a través
1188 de su ID, buscando la misma en el archivo índice (
1195 Ya determinada la posición física del registro dentro del archivo de datos
1200 ), nos posicionamos en la misma, y leemos el header del registro (
1209 Contando así con el tamaño del registro, procedemos a leer el mismo (los
1210 datos), dando por finalizada la lectura.
1215 emufs_tipo2_leer_registro()
1221 En el proceso de alta de registros entrarán en juego dos archivos descriptos
1224 sección de archivos auxiliares
1226 , siendo estos el archivo índice (
1230 ), y el archivo de gaps / espacios libres (
1237 Así pues, a la hora de realizar una inserción de un registro en el archivo
1238 de datos, el procedimiento será el siguiente:
1241 Calculamos el espacio que necesitaremos para el registro: sizeof(
1249 ) + sizeof(registro).
1252 Determinamos donde debemos insertar el registro, ya sea un gap donde entre,
1253 o bien al final del archivo.
1256 Insertamos el registro e información de control (
1264 ), en la posición indicada en el paso 2.
1267 En caso de haber utilizado un GAP, actualizamos el espacio libre restante
1268 en el mismo y en caso de que se haya utilizado al totalidad del GAP, se
1269 lo elimina del archivo (
1276 Actualizamos la entrada correspondiente al registro ingresado (determinada
1277 por su RegID), en el archivo índice (
1281 ), indicando su offset donde podrá ser accedido luego.
1286 emufs_tipo2_agregar_registro()
1292 En el proceso de baja de registros entrarán en juego los tres archivos descripto
1295 sección de archivos auxiliares
1297 , siendo estos el archivo índice (
1301 ), el archivo de gaps / espacios libres (
1305 ) y el archivo de ID's liberados (
1312 Dado que en la implementación de este tipo de organización física contamos
1313 con los gaps o espacios libres entre registros, no se eliminará fisicamente
1314 el registro del archivo de datos (
1318 ), pues entonces carecería de sentido el archivo anteriormente mencionado
1324 En cambio, se agrega el gap dejado por la eliminación a dicho archivo,
1325 y se marca fisicamente en el archivo de datos la eliminación mediante un
1326 fill de los bytes correspondientes con un caracter nulo.
1327 (hexa 00 y con el propósito de probar fehacientemente que el sistema funciona).
1330 El proceso de baja o eliminación de un registro constará luego de los siguientes
1334 Se obtiene el offset o posición relativa en donde se encuentra grabado el
1335 registro dentro del archivo de datos.
1338 Se obtiene el tamaño del registro y se realiza un dummyfill del sector del
1339 archivo correspondiente al registro que se está dando de baja.
1340 (Se rellena la zona correspondiente a su header+data).
1343 Se agrega el GAP generado al archivo de gaps o espacios libres, y en caso
1344 de haberse generado un GAP lindante con otro GAP, se realizará un merge
1345 de los mismos y se los registrará bajo una única entrada en el archivo
1346 de espacios libres (.fsc).
1349 Se agrega el ID que fue liberado, al archivo de ID's liberados (
1353 ), al final del mismo (
1360 Se marca en el archivo índice (
1364 ) la eliminación, mediante el valor ¨-1¨ en el registro correspondiente
1365 al registro recién eliminado (se le cambia el valor al n-esimo registro,
1366 donde N = IDReg del reg eliminado).
1371 emufs_tipo2_borrar_registro()
1374 Modificación de registros
1377 Dada la naturaleza del archivo de ID's liberados, y el manejo de espacio
1378 libre del que consta esta organización de archivo, el proceso de modificación
1379 de un registro se limita a los siguientes pasos:
1382 Se realiza la lectura del registro, mediante el respectivo procedimiento
1383 ya desarollado anteriormente.
1386 Una vez que se cuenta con los nuevos datos modificados, se procede a dar
1387 de baja el registro que ha sido modificado, e inmediatamente después se
1388 realiza una inserción con los nuevos datos.
1397 Como fue indicado, dada la naturaleza de PILA del subsistema de administración
1398 de ID liberados, es asegurado que la nueva inserción del registro modificado
1399 se realizará con el mismo RegID.
1404 emufs_tipo2_modificar_registro()
1407 Obtención de estadísticas
1410 Se puede tener acceso a las estadísticas generales del archivo, por ejemplo,
1411 cantidad de bloques, cantidad de registros, espacio libre total, espacio
1412 libre promedio, espacio libre máximo y mínimo, etc.
1415 Esta información es el resultado de ciertos cálculos realizados tanto en
1416 el archivo de datos como en los archivos índice.
1419 Completa una estructura del tipo EMUFS_Estadisticas con las estadísticas
1420 del archivo de datos, espacio libre total, cantidad de registros, cantidad
1421 de bloques, tamaño del archivo en bytes, relaciones entre tamaños y espacios
1427 emufs_tipo2_leer_estadisticas()
1430 Compactación del archivo de datos
1433 Asi como los otros dos tipos de datos, el que nos compete también cuenta
1434 con la posibilidad de realizar la compactación de datos cuando el usuario
1435 lo desee, justificando todos los registros a izquierda, eliminando así
1436 los gaps existentes y decrementando el tamaño del archivo en disco (truncandolo
1440 Para poder comprender como hemos implementado el proceso de recompactación
1441 en nuestro tipo de archivo 2, nos ayudaremos de esquemas a través de los
1442 cuales iremos describiendo el proceso.
1443 Notemos antes, que el proceso de compactación esta directamente ligado
1444 con el archivo de gaps o espacios libres (
1451 Comenzemos con el siguiente cuadro situacional:
1452 \begin_inset Float figure
1459 Archivo con gaps entre registros previo a compactación
1463 \begin_inset Graphics
1464 filename graphics/Compact1.png
1476 Partiendo de esta base, el algoritmo de compactación tomará en su inicio
1477 al primer gap existente dentro del archivo de datos, en este caso llamado
1483 Luego, establecerá que el
1487 a partir de donde se quieren mover datos, sera:
1490 StartGap0 + SizeGap0 = EndGap0 = Source
1493 Lo cual no es nada más y nada menos que lo obvio, la fuente a partir de
1494 donde se mueven los datos, sera el fin del primer gap, donde comienzan
1500 ) del movimiento, se establece inicialmente, el inicio del gap, o sea
1502 StartGap0 = Destination
1507 Luego, el algoritmo entrara en un bucle while (mientras haya bucles por
1508 levantar), el cual trabajara hasta el final de la compactación de la siguiente
1519 Se levanta el proximo gap al levantado en una instancia previa.
1520 En este ejemplo, durante el primer loop del while, se levantará
1525 Luego, se calcula cuantos bytes hay que mover hacia el Destination de la
1549 Lo cual nuevamente es lógico pues querremos mover lo que se encuentra entre
1550 el final del primer gap levantado y el inicio del siguiente).
1553 Se realiza el movimiento de los datos, utilizando las direcciones
1561 , así como la variable
1565 que nos indica cuantos bytes transferir.
1571 La transferencia se hace de a chunks de 25 bytes + un resto segun el valor
1575 Se establece como gap de referencia, al ultimo gap leido (En este caso se
1588 ) y termina el código de repetición del bucle, dando lugar a la carga del
1589 siguiente gap en el inicio del mismo.
1597 Luego del primer bucle, el archivo se vera de la siguiente forma:
1598 \begin_inset Float figure
1605 Archivo con gaps en disco luego del primer bucle de compactación
1609 \begin_inset Graphics
1610 filename graphics/Compact2.png
1621 Notemos que al final de la porción de datos de los bytes movidos (donde
1626 ), hay basura que será pisada por el próximo movimiento.
1629 En el próximo loop, el bucle levantará un nuevo gap, y utilizando el gap
1630 anterior (En esta caso el Gap anterior será
1634 ) como referencia, realizará los mismos cálculos, desde donde transferir
1635 y cuantos bytes mover.
1636 (El destino es solo establecido inicialmente por código, y para el resto
1637 del algoritmo es el lugar donde quedo el puntero destination luego de la
1641 Una vez que se salga del bucle while, se realizará un último movimiento
1642 preprogramado, donde la fuente (
1646 ) será el final del ultimo gap, y la cantidad de bytes a mover será lo que
1647 se encuentre luego del mismo hasta el fin de archivo.
1650 Source = StartLastGap + SizeLastGap = EndLastGap
1653 Mustmove_bytes = Datsize - Source
1656 Damos por terminada así, la explicación del algoritmo de compresión el cual
1657 para el caso del tipo 2, es realmente bastante sencillo.
1662 void emufs_tipo2_compactar()
1665 Consideraciones y Políticas de Diseño
1668 Se han tomado ciertas consideraciones para algunos casos particulares que
1669 se pueden presentar durante el uso/ejecución de la aplicación, así como
1670 tambien politicas respecto del diseño e implementación del sistema:
1673 En la organización física tipo 2 para los registros que se graban en disco
1674 hemos decidido utilizar como encabezado de cada uno de ellos, los datos
1675 [ID_REG][REG_SIZE], los cuales fueron detallados previamente.
1676 Si bien se podría haber descartado el grabado del ID del registro en el
1677 archivo de datos y puede parecer redundante, dado que poseemos el archivo
1678 índice con el offset directo, el mismo se lo graba por distintos motivos:
1682 A) En caso de la corrupción del archivo índice (.idx), podremos gracias a
1683 que poseemos en el archivo de datos, el ID de cada registro, recrear dicho
1684 índice, ayudándonos del archivo de espacios libres (
1688 ), para poder saltear los espacios libres y e ir recorriendo secuencialmente
1689 los registros, reconstruyendo así el índice en cuestión.
1690 (esta función de reconstrucción no pudo ser implementada para esta entrega,
1691 pero es una posibilidad real).
1695 B) Luego de un proceso de recompactación, los espacios libres que pudieron
1696 haber existido en el archivo de datos (
1700 ), son eliminados y los registros han cambiado de posición.
1701 Por ello, recorriendo secuencialmente por única vez el archivo de datos,
1702 se procede a la actualización / reconstrucción del índice de direcciones
1710 Si se desea insertar un registro y no se puede hayar un gap o espacio libre
1711 donde quepa, se los inserta al final del archivo.
1714 Ante una operación de baja de un registro, el mismo no es físicamente borrado
1715 del archivo de datos (
1719 ), simplemente los bytes que ocupa son llenados con hexa (00).
1720 Paralelamente, se procede a actualiza el archivo índice, insertando como
1721 valor de OFFSET para el registro eliminado, el valor ¨-1¨, indicando así
1722 la inexistencia del registro para el futuro, y por otro lado se genera
1723 la entrada de espacio libre en el archivo de gaps (
1730 La reutilización de ID's liberados por previas operaciones de baja de registros,
1731 se ve implementada por el archivo de ID liberados (.did), y su comportamiento
1732 es el de una pila por lo que el último ID liberado, sera el próximo a ser
1736 Como fue explicado en la implementación del archivo índice, existe una correspon
1737 dencia 1 a 1 entre los registros allí presentes (en el .idx) y los ID's de
1738 los registros, por lo cual el registro N-ésimo del archivo índice, será
1739 el correspondiente al registro de datos cuyo ID es igual a N.
1742 El proceso de compactación de archivos, realiza los movimientos de información
1743 requeridos para dicho propósito de a chunks de 25 bytes por vez.
1744 Este valor es fijo, pero se lo podría hacer parametrizable mediante la
1745 GUI en próximas entregas.
1749 \begin_inset LatexCommand \label{cha:tipo3}
1753 Archivo con bloques parametrizados y registros de longitud constante
1756 Las distintas organizaciones de archivos buscan aprovechar al máximo el
1757 espacio del archivo.
1760 En este caso veremos que sucede luego de agregar y borrar una gran cantidad
1761 de registros del archivo, lo que provoca como consecuencia directa la fragmenta
1762 ción del archivo, es decir, quedan huecos entre un registro y otro, lo que
1763 produce un desperdicio de espacio.
1769 Esta organización guarda los registros pertenecientes al archivo en bloques
1770 de tamaño parametrizado, de modo que intentará guardar la mayor cantidad
1771 de registros que quepan en un bloque.
1775 Así como los graba, también tendrá la posibilidad de leer registros y borrarlos
1779 Comportamiento Particular de los Archivos Auxiliares
1780 \layout Subsubsection
1782 Archivo de Bloques y Registros (.idx)
1785 buscar algun caso extraordinario.
1786 \layout Subsubsection
1788 Archivo de Bloques y Espacio Libre (.fsc)
1789 \layout Subsubsection
1791 Archivo de Id`s Borrados (.did)
1794 El comportamiento de este archivo, es común para todas las organizaciones
1795 y se ha explicado en 3.3.2.
1798 Funciones Principales
1812 se encuentran las cabeceras y la implementación de las funciones principales
1813 respectivamente, las cuales dan funcionalidad a esta organización.
1816 A continuación se comentará la descripción de algunas acciones importantes.
1817 \layout Subsubsection
1822 La lectura de un registro se realiza con la ayuda del archivo .
1826 el cual contiene la información de la posición del registro dentro del
1828 Una vez leida esta información, se recupera el bloque (en su totalidad)
1829 del archivo y se busca secuencialmente el registro con el
1838 emufs_tipo3_leer_registro()
1839 \layout Subsubsection
1844 Graba un registro en un bloque donde haya espacio suficiente, y si no crea
1845 un nuevo bloque y lo agrega al final del archivo.
1848 Luego de grabar un registro, actualiza los archivos de índice .idx y .fsc
1849 para mantener la coherencia.
1854 emufs_tipo3_grabar_registro()
1855 \layout Subsubsection
1860 Borra un registro del archivo de datos, para esto levanta el bloque al que
1861 pertenece el archivo y ajusta los demás registros justificandolos hacia
1865 Cabe destacar que para dar de baja un registro no hace falta borrarlo del
1866 archivo de datos, solo es necesario borrar las entradas en los archivos
1867 de índice, pero cuando se realiza el ajuste el algoritmo toma porciones
1868 del bloque del tamaño de un registro mas su encabezado - comenzando desde
1869 el siguiente al que fue borrado - y copia (sobreescribe) sobre el anterior.
1870 De esta manera, la información correspondiente al registro borrado no estará
1871 presente en el archivo de datos.
1872 Esto es una consecuencia del ajuste al borrar un registro, pudiendo no
1873 ser así, si no se realizara el mismo.
1874 \layout Subsubsection
1879 Se puede tener acceso a las estadísticas generales del archivo, por ejemplo,
1880 cantidad de bloques, cantidad de registros, espacio libre total, espacio
1881 libre promedio, espacio libre máximo y mínimo, etc.
1884 Esta información es el resultado de ciertos cálculos realizados tanto en
1885 el archivo de datos como en los archivos índice.
1888 Completa una estructura del tipo EMUFS_Estadisticas con las estadísticas
1889 del archivo de datos, espacio libre total, cantidad de registros, cantidad
1890 de bloques, tamaño del archivo en bytes, relaciones entre tamaños y espacios
1896 emufs_tipo3_leer_estadisticas()
1897 \layout Subsubsection
1899 Compactar el Archivo
1902 Esta función intenta reorganizar el archivo de manera que el espacio libre
1903 sea lo menor posible, recordando siempre que un registro no puede ser almacenad
1904 o en mas de un bloque excepto que el tamaño del registro sea mayor que el
1908 Para realizar esto, se aprovecha la funcionalidad de
1910 emufs_tipo3_grabar_registro()
1912 ya que esta tiene la capacidad de determinar una posición mas eficiente
1913 en el archivo para un registro.
1914 Por esto lo que se hace es levantar uno por uno los registros y volverlos
1915 a grabar, de ese modo todos los
1919 que pudieron haberse formado por la eliminación de registros serán cubiertos
1923 Al estar utilizando recuperación de
1927 borrados, esto me asegura que el registro borrado-guardado conservará el
1931 Al finalizar este proceso se verifica si existen bloques vacios para truncar
1933 Lo mismo se debe hacer con el archivo de espacios libres .
1937 el cual disminuye su tamaño también.
1942 void emufs_tipo3_compactar()
1945 Consideraciones y Políticas de Diseño
1948 Esto para mi va en organización física.
1951 Se han tomado ciertas consideraciones para algunos casos particulares que
1952 se pueden presentar durante el uso/ejecución de la aplicación.
1955 Cada registro tiene un encabezado que indica el
1962 Si el tamaño del registro es mayor que el tamaño del bloque el registro
1963 se particionará en la cantidad de bloques que sea necesario, pero siempre
1964 se guardará desde el comienzo de un bloque, esto quiere decir que nunca
1965 se podrá encontrar un comienzo de registro en algún lugar de un bloque
1966 que no sea el comienzo del mismo.
1969 Si el registro se divide en mas de un bloque, se le coloca el id como encabezado
1970 igualmente, pero en el archivo .
1974 solo se guarda el primer bloque.
1979 se actualizan todos los bloques con el espacio libre que realmente tienen.
1985 Las comparaciones, pruebas, etc...