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 Archivo sin bloques y registros de longitud variable
32 Este tipo de archivo nos traerá a la mesa la particularidad de grabar registros
33 de longitud variablesin realizar su agrupación en bloques, y como veremos
34 en la siguiente sección, tambien permitirá la administración de gaps que
35 queden en el archivo luego de operaciones de baja de registros.
41 Este tipo de archivo realizará el almacenamiento de registros de longitud
42 variable en disco, su borrado y modificación sin la utilización de bloques
44 Su implementación se encuentra en los archivos fuente (
57 Los archivos del tipo 2, presentarán al comienzo del mismo un header compuesto
58 simplemente por un dato del tipo EMUFS_Tipo (int) el cual indicará el tipo
59 de archivo en cuestión.
64 Para poder entender mejor la organización fisica de este tipo de archivo,
65 tomemos el caso hipotético en el que se encuentran grabados
69 (comenzando desde registro 0) de
78 Supongamos también que entre el registro 0 y 1 se encontraba un
95 Si miramos al archivo de datos (.DAT) en el disco nos encontraremos con
101 \begin_inset Graphics
102 filename graphics/Example1.png
111 Como se puede observar, a nivel físico cada registro grabado esta compuesto
112 por un Header cuyo tamaño total es de 8 bytes (
120 ), y posteriormente el registro (bloque de datos) en sí.
121 Luego se encuentra el espacio libre de 18 bytes dejado por el registro
122 de 10 bytes eliminado (10 bytes de datos + header de 8 bytes) y finalmente
123 el segundo registro mencionado.
126 Comportamiento Particular de los Archivos Auxiliares
129 Como fue explicado al inicio de la documentación, la implementacion de cualquier
130 a de las tres organizaciones físicas de archivos presenta la necesidad de
131 poseer tres archivos auxiliares que actuarán como índice de direcciones
136 ), administrador de espacio libre (
140 ) y administrador de Id's liberados (
147 No obstante, cada tipo de organización presentara sus particularidades respecto
148 de estos tres archivos, las cuales describiremos a continuación en caso
150 \layout Subsubsection
152 Archivo índice o de posiciones relativas (.idx)
159 ), permite la localizacin de los registros en el .DAT de forma directa, mediante
160 la obtención de su offset o posición relativa respecto del inicio del
164 en donde se encuentra un registro dado, indicado por su ID.
167 Así pues, si tomamos el ejemplo descripto al inicio de este capítudlo, tendremos
168 las siguientes entradas en el archivo indice
179 <lyxtabular version="3" rows="3" columns="3">
181 <column alignment="center" valignment="top" leftline="true" width="0">
182 <column alignment="center" valignment="top" leftline="true" width="0">
183 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
184 <row topline="true" bottomline="true">
185 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
195 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
205 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
214 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
224 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
234 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
239 El primer registro (reg0) comienza en el byte 4
243 <row topline="true" bottomline="true">
244 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
252 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
262 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
267 El segundo registro (reg1) comienza en el byte 60
287 LOCATION indica donde comienza el header del registro buscado, y por consiguien
288 te luego del header tendremos el registro en sí (los datos).
289 \layout Subsubsection
291 Achivo de Gaps / Espacios Libres (.fsc)
294 El archivo de espacios libres o gaps (.fsc), tiene como función la administracion
295 del espacio libre o gaps (agujeros), generados por previas eliminaciones
296 de registros en el archivo de datos.
297 El mismo, nos indicará donde hay lugar para insertar un nuevo registro
298 (se podrán insertar en algún gap acorde, o bien al final del archivo).
299 Este archivo será utilizado tambien para el proceso de compactación de
300 un archivo, explicado luego.
303 Así pues, si tomamos el ejemplo descripto al inicio del documento, tendremos
304 las siguientes entradas en el archivo índice
314 <lyxtabular version="3" rows="2" columns="3">
316 <column alignment="center" valignment="top" leftline="true" width="0">
317 <column alignment="center" valignment="top" leftline="true" width="0">
318 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
319 <row topline="true" bottomline="true">
320 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
330 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
340 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
348 <row topline="true" bottomline="true">
349 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
359 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
369 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
374 18 bytes libres a partir del byte 42 del .dat
394 Por requerimiento del algoritmo de compactación, los gaps se graban en
395 forma ordenada en el (.fsc).
396 (El orden se corresponde con lo que hay en el .dat)
397 \layout Subsubsection*
402 Si bien la utilización concreta de los GAPS será explicada posteriormente
403 en la ALTA y BAJA de registros, debemos remarcar la funcionalidad de MERGING
404 que posee nuestro sistema FSC.
407 Ante la eliminación de un registro del archivo de datos, se generara por
408 consiguiente un gap o espacio libre en alguna posición del archivo.
409 Ese gap deberá ser registrado en el archivo de gaps (.fsc).
410 Ahora bien, nuestro sistema de gaps, contemplará como es debido, la posibilidad
411 de que se haya eliminado un registro que posee un GAP por delante, un GAP
412 por detrás, o bien un GAP por delante y por detrás del mismo.
415 Nuestro sistema actuará en consecuencia, realizando un merge de los espacios
416 libres, y unificándolos en una UNICA entrada en el archivo .fsc, que contendrá
417 como dato de freespace, la suma correspondiente de los espacios libres
419 \layout Subsubsection
421 Archivo de ID's liberados (.did)
424 El archivo de ID's liberados no presenta ningún aspecto particular en este
425 tipo de organización.
426 Remitirse al capítulo correspondiente a los archivos auxiliares para consultar
427 su estructura y funcionamiento.
430 Comportamiento (funciones de la interfáz)
445 se encuentran las cabeceras y la implementación de las funciones principales
446 respectivamente, las cuales dan funcionalidad a esta organización.
450 A continuación se comentará el funcionamiento algunas de las mas importantes.
456 Como se vió al comienzo, los registros en este tipo de archivo no se encuentran
457 agrupados en bloques de ninguna índole y estan dispersos a lo largo del
458 archivo, con la particularidad de que pueden existir gaps o espacio libre,
459 entre dos registros dados.
464 Por ende la lectura de registros en este tipo de organización es muy simple
465 y dada la inexistencia de bloques, el procedimiento será el siguiente:
468 Se determina el offset en bytes, donde comienza el registro deseado, a través
469 de su ID, buscando la misma en el archivo índice (
476 Ya determinada la posición física del registro dentro del archivo de datos
481 ), nos posicionamos en la misma, y leemos el header del registro (
490 Contando así con el tamaño del registro, procedemos a leer el mismo (los
491 datos), dando por finalizada la lectura y devolviendo el registro pedido.
499 : void *emufs_tipo2_modificar_registro()
505 En el proceso de alta de registros entrarán en juego dos archivos descriptos
508 sección de archivos auxiliares
510 , siendo estos el archivo índice (
514 ), y el archivo de gaps / espacios libres (
524 Así pues, a la hora de realizar una inserción de un registro en el archivo
525 de datos, el procedimiento será el siguiente:
528 Calculamos el espacio que necesitaremos para el registro: sizeof(
536 ) + sizeof(registro).
539 Determinamos donde debemos insertar el registro, ya sea un gap donde entre,
540 o bien al final del archivo.
543 Insertamos el registro e información de control (
551 ), en la posición indicada en el paso 2.
554 En caso de haber utilizado un GAP, actualizamos el espacio libre restante
555 en el mismo y en caso de que se haya utilizado al totalidad del GAP, se
556 lo elimina del archivo (
563 Actualizamos la entrada correspondiente al registro ingresado (determinada
564 por su RegID), en el archivo índice (
568 ), indicando su offset donde podrá ser accedido luego.
576 : EMUFS_REG_ID emufs_tipo2_agregar_registro()
582 En el proceso de baja de registros entrarán en juego los tres archivos descripto
585 sección de archivos auxiliares
587 , siendo estos el archivo índice (
591 ), el archivo de gaps / espacios libres (
595 ) y el archivo de ID's liberados (
604 Dado que en la implementación de este tipo de organización física contamos
605 con los gaps o espacios libres entre registros, no se eliminará fisicamente
606 el registro del archivo de datos (
610 ), pues entonces carecería de sentido el archivo anteriormente mencionado
616 En cambio, se agrega el gap dejado por la eliminación a dicho archivo,
617 y se marca fisicamente en el archivo de datos la eliminación mediante un
618 fill de los bytes correspondientes con un caracter nulo.
619 (hexa 00 y con el propósito de probar fehacientemente que el sistema funciona).
624 El proceso de baja o eliminación de un registro constará luego de los siguientes
628 Se obtiene el offset o posición relativa en donde se encuentra grabado el
629 registro dentro del archivo de datos.
632 Se obtiene el tamaño del registro y se realiza un dummyfill del sector del
633 archivo correspondiente al registro que se está dando de baja.
634 (Se rellena la zona correspondiente a su header+data).
637 Se agrega el GAP generado al archivo de gaps o espacios libres, y en caso
638 de haberse generado un GAP lindante con otro GAP, se realizará un merge
639 de los mismos y se los registrará bajo una única entrada en el archivo
640 de espacios libres (.fsc).
643 Se agrega el ID que fue liberado, al archivo de ID's liberados (
647 ), al final del mismo (
654 Se marca en el archivo índice (
658 ) la eliminación, mediante el valor ¨-1¨ en el registro correspondiente
659 al registro recién eliminado (se le cambia el valor al n-esimo registro,
660 donde N = IDReg del reg eliminado).
668 : int emufs_tipo2_borrar_registro()
671 Modificación de registros
674 Dada la naturaleza del archivo de ID's liberados, y el manejo de espacio
675 libre del que consta esta organización de archivo, el proceso de modificación
676 de un registro se limita a los siguientes pasos:
679 Se realiza la lectura del registro, mediante el respectivo procedimiento
680 ya desarollado anteriormente.
683 Una vez que se cuenta con los nuevos datos modificados, se procede a dar
684 de baja el registro que ha sido modificado, e inmediatamente después se
685 realiza una inserción con los nuevos datos.
694 Como fue indicado, dada la naturaleza de PILA del subsistema de administración
695 de ID liberados, es asegurado que la nueva inserción del registro modificado
696 se realizará con el mismo RegID.
706 : EMUFS_REG_ID emufs_tipo2_modificar_registro()
709 Obtención de estadísticas
712 Se puede tener acceso a las estadísticas generales del archivo, por ejemplo,
713 cantidad de bloques, cantidad de registros, espacio libre total, espacio
714 libre promedio, espacio libre máximo y mínimo, etc.
717 Esta información es el resultado de ciertos cálculos realizados tanto en
718 el archivo de datos como en los archivos índice.
721 Completa una estructura del tipo EMUFS_Estadisticas con las estadísticas
722 del archivo de datos, espacio libre total, cantidad de registros, cantidad
723 de bloques, tamaño del archivo en bytes, relaciones entre tamaños y espacios
734 : EMUFS_Estadisticas emufs_tipo3_leer_estadisticas()
737 Compactación del archivo de datos
740 Asi como los otros dos tipos de datos, el que nos compete también cuenta
741 con la posibilidad de realizar la compactación de datos cuando el usuario
742 lo desee, justificando todos los registros a izquierda, eliminando así
743 los gaps existentes y decrementando el tamaño del archivo en disco (truncandolo
747 Para poder comprender como hemos implementado el proceso de recompactación
748 en nuestro tipo de archivo 2, nos ayudaremos de esquemas a través de los
749 cuales iremos describiendo el proceso.
750 Notemos antes, que el proceso de compactación esta directamente ligado
751 con el archivo de gaps o espacios libres (
760 Comenzemos con el siguiente cuadro situacional:
765 \begin_inset Graphics
766 filename graphics/Compact1.png
777 Partiendo de esta base, el algoritmo de compactación tomará en su inicio
778 al primer gap existente dentro del archivo de datos, en este caso llamado
784 Luego, establecerá que el
788 a partir de donde se quieren mover datos, sera:
812 Lo cual no es nada más y nada menos que lo obvio, la fuente a partir de
813 donde se mueven los datos, sera el fin del primer gap, donde comienzan
819 ) del movimiento, se establece inicialmente, el inicio del gap, o sea
821 StartGap0 = Destination
826 Luego, el algoritmo entrara en un bucle while (mientras haya bucles por
827 levantar), el cual trabajara hasta el final de la compactación de la siguiente
840 Se levanta el proximo gap al levantado en una instancia previa.
841 En este ejemplo, durante el primer loop del while, se levantará
846 Luego, se calcula cuantos bytes hay que mover hacia el Destination de la
870 Lo cual nuevamente es lógico pues querremos mover lo que se encuentra entre
871 el final del primer gap levantado y el inicio del siguiente).
874 Se realiza el movimiento de los datos, utilizando las direcciones
882 , así como la variable
886 que nos indica cuantos bytes transferir.
895 La transferencia se hace de a chunks de 25 bytes + un resto segun el valor
899 Se establece como gap de referencia, al ultimo gap leido (En este caso se
912 ) y termina el código de repetición del bucle, dando lugar a la carga del
913 siguiente gap en el inicio del mismo.
923 Luego del primer bucle, el archivo se vera de la siguiente forma:
928 \begin_inset Graphics
929 filename graphics/Compact2.png
939 Notemos que al final de la porción de datos de los bytes movidos (donde
944 ), hay basura que será pisada por el próximo movimiento.
949 En el próximo loop, el bucle levantará un nuevo gap, y utilizando el gap
950 anterior (En esta caso el Gap anterior será
954 ) como referencia, realizará los mismos cálculos, desde donde transferir
955 y cuantos bytes mover.
956 (El destino es solo establecido inicialmente por código, y para el resto
957 del algoritmo es el lugar donde quedo el puntero destination luego de la
961 Una vez que se salga del bucle while, se realizará un último movimiento
962 preprogramado, donde la fuente (
966 ) será el final del ultimo gap, y la cantidad de bytes a mover será lo que
967 se encuentre luego del mismo hasta el fin de archivo.
974 Source = StartLastGap + SizeLastGap = EndLastGap
979 Mustmove_bytes = Datsize - Source
986 Damos por terminada así, la explicación del algoritmo de compresión el cual
987 para el caso del tipo 2, es realmente bastante sencillo.
997 : void emufs_tipo2_compactar()
1000 Detalles de implementación (funciones internas, ver si lo ponemos o no)