Serie ficheros virtuales

 

 

 

 

C Ficheros virtuales

 

 

 

 

A.I.4 Ficheros virtuales

 

 A.I.4.1 Introducción

 A.I.4.2 Del caché a los ficheros virtuales

 A.I.4.3 Síntesis del procedimiento de caché

 A.I.4.4 La asignación dinámica de memoria

 A.I.4.5 El mecanismo de búsqueda

 A.I.4.6 Aspectos derivados de la búsqueda dicotómica

 A.I.4.7 El esquema central de los ficheros virtuales

 

                                                                                                 _______

 

 

A.I.4.1 Introducción

 

Este es el capítulo central del libro. Los capítulos anteriores han sido una introducción para llegar a él.

 

Los capítulos posteriores implementan en C ANSI las ideas que se exponen en él y luego las explotan en los distintos ejemplos, hechos en un núcleo C, presentados luego en la primera parte con interfaces en C++ y en la segunda parte en Visual Basic Net.

 

Si el libro se orientase a otro lenguaje, como podría ser el RPG, los demás capítulos deberían ser reescritos en profundidad, pero los cambios en este se reducirían simplemente a la traducción de las referencias a sentencias concretas en C, manteniéndose el resto del contenido.

 

                                                                                                 _______

 

 

A.I.4.2 Del caché a los ficheros virtuales

 

En este capítulo presentaremos la evolución a seguir para pasar de un mecanismo de caché simple hasta obtener un fichero virtual.

 

Para ello, comenzaremos sintetizando el procedimiento de caché presentado en el capítulo anterior resumiéndolo en un esquema de conjunción de las acciones de write y chain.

 

El paso siguiente consiste en añadir a este esquema la ampliación automática del número de registros utilizando la (re)asignación dinámica de memoria.

 

En este punto se le dará a la evolución un salto cualitativo al introducir un mecanismo de búsqueda dicotómica, terminándose con el esquema central resultante del método.

 

En el capítulo siguiente se vestirá esta presentación con el código central de soporte, obteniendo un primer conjunto de servicios que se ampliará en los siguientes capítulos para dotarlo de los servicios que nos permitirán pasar desde un fichero virtual simple a una base de datos virtual completa.

 

                                                                                                 _______

 

 

A.I.4.3 Síntesis del procedimiento de caché

 

La síntesis del procedimiento de caché presentado en el capítulo anterior se resume en el seudo-código siguiente

 

 

 

if chain (clave) fichero

 

  return registro_fichero;

 

else

{

  funcion (clave, datos);

 

  write (registro_fichero) fichero;

}

 

 

 

 

donde registro_fichero = clave + datos;

 

y fichero = {registro_fichero[1..n]}

 

 

 

Aunque los algoritmos internos de recuperación y grabación sean más o menos sofisticados, lo deseable es que el interfaz resultante sea lo más sencillo posible, siguiendo esta síntesis.

 

La síntesis algorítmica es precisamente la esencia de la investigación operativa. Una vez establecido el algoritmo, este puede transcribirse a aquel lenguaje que disponga de los recursos más adecuados a su implementación.

 

                                                                                                 _______

 

 

A.I.4.4 La asignación dinámica de memoria

 

El siguiente problema básico que debe resolver el proceso de caché con vistas a su ampliación a un gestor de ficheros virtuales es el de la asignación dinámica de memoria a fin de despreocuparse de los problemas de límite.

 

Para que el resultado sea lo más general posible, no debe imponer tipos y por tanto debe usar punteros genéricos (void) para manejar claves y datos; lo cual en C puede hacerse gracias a la familia de funciones sobre copia, movimiento y comparación en memoria de objetos:

 

     memcmp, memcpy, memmove y memset.

 

 

Aunque no se llegue a utilizar en la aplicación, conviene señalar que esta familia mem tiene una versión str específica para cadenas:

 

     strcmp, strcpy, strdup, y strset.

 

 

El mecanismo de asignación se concretará aplicando una asignación inicial para un tamaño de bloque, con una instrucción tipo

 

          q = (char *) malloc(lTamAmp * lTamItem * sizeof(char));

 

 

y unas reasignaciones periódicas que se invocarán al agotar el número de posiciones asignados con lTamAmp utilizando una instrucción de tipo

 

          q = (char *) realloc(p, (lTamAnt + lTamAmp) * lTamItem * sizeof(char));

 

 

instrucciones a las que se volverá, presentadas en su contexto, en el próximo capítulo.

 

                                                                                                 _______

 

 

A.I.4.5 El mecanismo de búsqueda

 

Una primera aproximación del problema es la sencilla técnica lineal presentada antes, de hecho permite implementar CHAIN & WRITE satisfactoriamente para un número de ítems no muy grande, por ejemplo varios centenares, pero ésta técnica no lleva más allá, su rendimiento se deteriora rápidamente y se hace preciso optimizarla cambiando el algoritmo.

 

Al optimizar el mecanismo de búsqueda surgen conceptos tales como búsqueda dicotómica, técnicas hash o árboles.

La aplicación opta por un algoritmo de inserción dicotómica en índice que presentaremos en detalle en el próximo capítulo, ahora comentaremos aspectos derivados del mismo.

 

                                                                                                 _______

 

 

A.I.4.6 Aspectos derivados de la búsqueda dicotómica

 

La técnica dicotómica está íntimamente relacionada con el problema de ordenación pues consiste en buscar de forma orientada, dividiendo en cada paso la masa de datos en dónde buscar a la mitad, partiendo del supuesto de que los datos donde se realiza la búsqueda están ordenados.

 

La idea es sencilla y muy efectiva pues si en la búsqueda lineal el nº promedio de búsquedas es de N/2 en la dicotómica es del orden de log2(N) [esto es así porque nos encontramos con la inversa de un espacio 2^N]

 

En contraposición, la servidumbre que conlleva es mantener los datos ordenados; pero ésta aparente desventaja tiene agradables derivaciones, pues si uno se sirve de éste subproducto se encuentra que no sólo es capaz de encadenar por clave, sino que también puede leer ordenadamente, lo que convierte a la aplicación en una poderosa herramienta.

 

La ordenación natural asociada se consigue por inserción; bien directamente sobre el conjunto de claves, o mejor aún, sobre una tabla índice auxiliar.

 

Con ésta última técnica, resulta que utilizando memmove el proceso resulta extraordinariamente rápido y por tanto eminentemente práctico.

 

Las otras técnicas citadas conllevan una implementación más compleja que sólo se justifica en aquellos casos particulares en que el resultado consiga ser más rápido que el memmove, lo que no es fácil, porque las técnicas hash tienen la problemática de las colisiones y los árboles la del desequilibrio; además, la aplicación presentada es de propósito general e incorpora utilidades añadidas difícilmente desarrollables sin disponer de orden implícito.

 

Incluso si se dispone de C++ y de contenedores genéricos iterables, el aplicativo resulta una opción muy atractiva porque es multiplataforma, sencillo de usar y muy versátil, al disponer de las instrucciones usuales que un programador espera encontrar: CHAIN, WRITE, READ, DELETE y sus variantes, sobre una base de datos virtual que se crea dinámicamente, sin el engorro de tener que gestionar objetos físicos, con sus bloqueos, autorizaciones y rendimientos.

                                                                                                 _______

 

 

A.I.4.7 El esquema central de los ficheros virtuales

 

Es interesante señalar que el desarrollo se basa en un pequeño conjunto de mecanismos, establecidos en el seudo código presentado anteriormente.

 

En efecto, partiendo simplemente de cuatro elementos:

   - Un mecanismo de archivo WRITE(1),

   - Otro de recuperación CHAIN(2)

   - La disposición de una función de orden para comparar claves [memcmp](3)

   - Y de las funciones básicas de gestión de memoria[malloc, memcpy, memmove, realloc] (4)

 

Que podemos esquematizar como sigue:



                        Registros
                   ___________________
                     Claves    Datos

(1) WRITE          [ K (3)  |    D   ]        (2) CHAIN | (5) SETLL READE UPDATE...
    [. . .                                              | (6) CRTLF CPY SAVF RSTF ...
   
[. . .

    [. . .
  + [. . . (4) [  malloc, memcpy, memmove, realloc  ]

    [. . .
    [. . .
    [. . .


 

Entonces podemos desarrollar en una serie de procedimientos

 - A nivel registro(5)

 - A nivel global de fichero(6)

 

Hasta llegar a tener un gestor de base de datos virtual dotado de la rica familia de funciones que se ha apuntado y que se utilizarán en los ejemplos y anexos de los próximos capítulos.

Estos desarrollos irán agregando servicios al núcleo central WRITE y CHAIN de forma natural, capa a capa, rellenando el esquema anterior.

 

 

 

(3) Nota adicional:

 

Normalmente las claves y los datos estarán compuestas por subestructuras compuestas por campos, lo que gráficamente podemos representar con puntos separadores como sigue:

 

 

       K

         D

111.111

AAA.AAA

222.222

BBB.BBB

333.333

CCC.CCC

444.444

DDD.DDD

555.555

EEE.EEE

    .  .  .

 

 

                                                                                                 _______

 

 

 

En iSeries nos encontramos con otras ventajas, pues en esta plataforma los módulos se implementan como programas de servicio que aúnan las ventajas de los procedimientos encapsulados de las DLL’s de la plataforma MsC++ con la facilidad de la elección del ámbito de permanencia de datos.

 Así, podemos cargar datos en un programa y utilizarlos posteriormente en otro de la misma cadena, o dejarlos reservados para informes de post-producción y análisis post-mortem, prácticamente de la misma manera que se hace con los archivos tradicionales.

 

De hecho, en la práctica, el producto se utiliza fundamentalmente como servicio en la plataforma iSeries para programas en ILE-RPG, con un uso puro en ILE-C mucho menor, particularmente emulando las hojas de cálculo del usuario.

 

En cuanto al detalle de cómo se realiza este particular, el subdominio iSeries.ficherosvirtuales.com se irá dedicando a recoger desarrollos para presentar minuciosamente el uso del sistema de ficheros virtuales desde RPG, más allá de la introducción que se hace en el capítulo

 "A.I.9 Alternativa RPG. El programa de servicio SRAGM " del blog en curso de la serie www.ficherosvirtuales.com

 

 

Serie en la que se irán introduciendo implementaciones paralelas en lenguajes como Cnet , VBA o JavaScript.

 

                                                                                                 _______