Ficheros – PRÁCTICA OBLIGATORIA Clases de Prácticas – 10ª sesión (última) (10ª versión de la aplicación gestora; sistema definitivo) Acceso Invertido. Organizaciones invertidas. El acceso indizado normal consiste en traducir un puntero lógico (simbólico) en uno o varios punteros relativos (posición unívoca del registro). Esto se hace así porque lo que conocemos es el puntero simbólico (por ser parte de la condición de búsqueda) y lo que deseamos averiguar es dónde está el registro (para recuperarlo y mostrarlo). Sin embargo, en ocasiones puede ocurrir lo contrario: que lo que conozcamos sea la posición física y lo que deseemos averiguar sea el puntero simbólico. Esto sucede cuando el usuario no pregunta por todos los datos del registro, sino tan sólo por uno (o dos, o un número reducido de ellos en cualquier caso). Por ejemplo, si el usuario pregunta cuáles son los ‘DNI’ de los poetas que tenemos registrados y tenemos un índice por la clave DNI, se nos plantean dos opciones: (a) recorrer todo el área de datos, mostrando sólo los DNI (b) recorrer el índice DNI , mostrando sólo los DNI (que es la clave de indización) Evidentemente, la opción (b) es mucho más ventajosa que la (a): en primer lugar, porque el índice es mucho más pequeño que el área de datos; y en segundo lugar, porque es posible que muchos de sus bloques (o todos) estén en memoria intermedia (por ser de uso habitual) con lo que el número de accesos sería cero. Esta idea hay que extenderla a procesos selectivos: si en lugar de pedir todos los DNI de todos los poetas, el usuario nos pide sólo los DNI de los poetas de nombre ‘Fulano’. El primer acceso indizado sería el acceso normal (para averiguar la posición de esos registros), obteniendo un conjunto de direcciones donde están esos registros). En el segundo acceso, tendríamos que recorrer todo el índice DNI, seleccionando la clave (el DNI) de aquellas entradas cuyo puntero relativo esté contenido en el conjunto de direcciones obtenido anteriormente. Es necesario realizar la siguiente observación: - En un índice normal, el puntero relativo sólo necesita la parte alta del puntero relativo (qué bloque) para poder filtrar el conjunto resultado. - Sin embargo, los índices destinados a realizar acceso invertido deben tener punteros con parte alta y parte baja: en el cubo de dirección x puede haber tres registros, pero sólo uno de ellos se llama ‘Fulano’ y me interesa sólo su DNI. Estructuras Invertidas Este tipo de procesos puede aprovecharse de algunas características especiales de determinadas organizaciones indizadas. Por ejemplo, los índices secundarios se implementarán siempre con listas de punteros (de partes alta y baja), y que en este caso se van a denominar listas invertidas. Estas no serán otra cosa que índices normales (cualquiera de las implementaciones de índice es aplicable) en las que la particularidad es la entrada: siguen teniendo un valor de clave, pero ahora tienen muchos valores de puntero (de 1 a n). Por ello, el puntero relativo ha de reservar un valor (típicamente el 0) que es la marca de fin de lista (indica que no hay más punteros). También se puede implementar con una marca de longitud_de_lista (pero esto es más infrecuente). Observar que la inserción de un elemento en el índice es bastante grave (aunque no vamos a optimizar en actualización). A menudo se reserva otro valor del puntero (típicamente el 255) para representar un ‘hueco’. Así se puede dejar ‘espacio libre distribuido’, y posibilita el borrado eficiente. Otra estructura interesante para el acceso invertido es el esquema de bits (mapa de bits). Consiste en que la clave (puntero lógico) se registra en mapa de bits, y viene acompañada del correspondiente puntero relativo. Para su consulta, se construyen máscaras que permiten consultar uno o más valores simultáneamente para toda la clave de inversión. Las máscaras pueden ser bivaluadas (1 ó 0 , si la entrada tiene ese valor o no) o trivaluadas (0,1 ó x si el valor no es relevante para nuestra consulta o no está especificado) Se debe observar que estas estructuras sólo serán eficientes si el esquema es pequeño, es decir, el número de posibles valores que puede tomar la clave es reducido. No así la lista invertida (que es más bien al revés). Estas estructuras van a ser accedidas en unas ocasiones a través de la clave, y en otras a partir del puntero. En esto, los esquemas de bits presentan otra ventaja. Por ser su tamaño constante (siempre el mismo número de bits) se pueden organizar en el fichero a partir de su puntero relativo (por así decirlo, vamos a direccionar el archivo índice por esquema de bits, por un direccionamiento directo a celdas). En este caso, dado que el valor del puntero relativo determina la posición del esquema y viceversa, podemos omitir el almacenaje del puntero relativo (va implícito por el direccionamiento). Así, las entradas (y por tanto las celdas) serán aún más pequeñas. Inconvenientes: o es inevitable dejar muchas celdas vacías (e incluso pueden surgir desbordamientos, pero a lo sumo ocuparán un cubo). o los accesos indizados son ineficientes (recorridos seriales de todo). Ventaja: los accesos invertidos son por acceso directo Por tanto, este planteamiento es bueno cuando el índice se usa para el acceso invertido Implementación (obligatoria en la práctica) El usuario impondrá las condiciones de búsqueda en el interfaz (igual que para otras recuperaciones condicionales) y marcará el campo del que desea la información para el acceso invertido (utilizando el símbolo especial ‘\?’, que escribirá en ese campo). Finalmente, para ejecutar la operación, pulsará la opción correspondiente (en el menú o en la barra de herramientas). La interfaz invocará el método correspondiente de la aplicación, facilitándole un buffer con toda la información adquirida de la pantalla, y este devolverá una colección de informaciones (líneas de texto, conteniendo el resultado del acceso invertido). Se realizarán los accesos invertidos explícitos en el enunciado (observar que alguno de ellos puede involucrar varios archivos, o elementos de datos de tipo puntero, sin que esto suponga obstáculo alguno en su implementación).