Serie ficheros virtuales

 

 

 

 

C Ficheros virtuales

 

 

 

 

A.I.6 Extensión. SRRCN como implementación de fichero virtual

 

 A.I.6.1 Introducción

 A.I.6.2 Fichero de soporte interno de la implementación

 A.I.6.3 Las funciones de posicionamiento y lectura por clave

 A.I.6.4 Implementación

 

                                                                                                                _________

 

A.I.6.1 Introducción

 

En SRRCM se implementan las funciones básicas de acceso a fichero tal como WRITE, CHAIN y READ, pero en los problemas prácticos surge inmediatamente la necesidad de disponer de un mecanismo de lectura por clave igual.

 

Así ocurre en los ejemplos que se presentan en capítulos posteriores, donde aparecen situaciones en que de forma recurrente unas veces se precisa recorrer todos los ítems de una misma columna en una matriz de datos, y en otras todos los de una misma fila, y en general se centran en resolver problemas utilizando de una u otra manera ciclos de lectura y proceso por clave igual, ascendente o descendente.

 

Por ello se desarrolló SRRCN, que recoge las rutinas de lectura por igual hacia delante y hacia atrás que redondean el uso de SRRCM como fichero virtual.

 

Siguiendo la filosofía del desarrollo incremental, en vez de ampliar directamente SRRCM, que estaba funcionando de forma satisfactoria, pareció más conveniente agregar las nuevas funciones en una capa externa SRRCN, preservando así al núcleo de la aplicación de posibles errores de desarrollo.

 

Tenemos entonces una aplicación compartimentada en capas en vez de un solo programa, con las ventajas de mantenimiento y estructuración que este tipo de desarrollo conlleva.

 

SRRCN es una primera ampliación, la perspectiva se incrementará hasta llegar a una verdadera base de datos virtual, lo que será objeto del resto de la aplicación que se presentará en los servicios de la siguiente capa de programación, SRRCW, objeto del capítulo siguiente.

 

                                                                                                                _________


 

La idea que se plasma en SRRCN es sencilla, se basa en conjugar el acceso por clave y la lectura secuencial posterior verificando que se mantenga la clave solicitada.

 

Para ello utiliza SRRCM para generar un fichero virtual en donde se van guardando las relaciones entre cada fichero y su índice de lectura en curso. El método se concreta entonces en la grabación del índice de posición que se consigue con las rutinas SETLL y al que se acude en las rutinas READ para verificar el mantenimiento del enlace.

 

Es interesante señalar que a cambio del pequeño desarrollo de esta sencilla idea que veremos en detalle un poco más adelante, se obtengan las poderosas rutinas de lectura por clave, fundamentales para el tratamiento asequible de algoritmos cíclicos, contrapunto a su alternativa clásica de uso de series que para conseguir, con suerte, el mismo efecto conlleva anidamientos verdaderamente engorrosos.

 

 

                                                                                                                _________

 

A.I.6.2 Fichero de soporte interno de la implementación

 

La implementación utiliza un fichero virtual para archivar la relación entre ficheros e índices de lectura por clave, que se identifica con la variable lNIDI:

 

 

   static long lNIDI; // Identificador del fichero de relaciones fichero-índice para SETLL/READE

 

 

Y se crea con la instrucción

 

   lNIDI = SRRCM_NEW(sizeof(long), sizeof(long));

 

 

Se trata entonces de un fichero muy compacto preparado para archivar claves y datos de tipo long, y en donde lo que se va a guardar específicamente son los identificadores de fichero que se vayan utilizando en las operaciones de posicionamiento y lectura por clave, y los índices de posición en curso para la lectura siguiente por clave en esos mismos ficheros.

 

Para fijar las ideas supongamos que estuviéramos trabajando con dos ficheros, a los que el usuario les haya denominado “UNO” y “DOS” y que el sistema les asigne los identificadores 1 y 2 (Conviene decir aquí que la utilidad de poder denominar a los ficheros a conveniencia del usuario es un anticipo de lo que sucede en el próximo capítulo) y que tengan archivados los siguientes datos:

 

 

 

Fichero

Identificador

Relativo de registro

Clave

Datos

UNO

1

1

01 01

EJEMPLO UNO 01 01

UNO

1

2

01 02

EJEMPLO UNO 01 02

UNO

1

3

01 03

EJEMPLO UNO 01 03

UNO

1

4

01 04

EJEMPLO UNO 01 04

UNO

1

5

01 05

EJEMPLO UNO 01 05

UNO

1

6

01 06

EJEMPLO UNO 01 06

UNO

1

7

01 07

EJEMPLO UNO 01 07

UNO

1

8

01 08

EJEMPLO UNO 01 08

UNO

1

9

01 09

EJEMPLO UNO 01 09

UNO

1

10

01 10

EJEMPLO UNO 01 10

-

 

 

 

 

UNO

1

11

10 01

EJEMPLO UNO 10 01

UNO

1

12

10 02

EJEMPLO UNO 10 02

UNO

1

13

10 03

EJEMPLO UNO 10 03

UNO

1

14

10 04

EJEMPLO UNO 10 04

UNO

1

15

10 05

EJEMPLO UNO 10 05

-

 

 

 

 

UNO

1

16

11 01

EJEMPLO UNO 11 01

UNO

1

17

11 02

EJEMPLO UNO 11 02

-

 

 

 

 

UNO

1

18

12 01

EJEMPLO UNO 12 01

 

 

 

 

 

. . .

 

 

 

 

 

 

 

 

 

DOS

2

1

01 01

EJEMPLO DOS 01 01

DOS

2

2

01 02

EJEMPLO DOS 01 02

DOS

2

3

01 03

EJEMPLO DOS 01 03

DOS

2

4

01 04

EJEMPLO DOS 01 04

DOS

2

5

01 05

EJEMPLO DOS 01 05

DOS

2

6

01 06

EJEMPLO DOS 01 06

DOS

2

7

01 07

EJEMPLO DOS 01 07

DOS

2

8

01 08

EJEMPLO DOS 01 08

DOS

2

9

01 09

EJEMPLO DOS 01 09

DOS

2

10

01 10

EJEMPLO DOS 01 10

-

 

 

 

 

DOS

2

11

05 01

EJEMPLO DOS 05 01

DOS

2

12

05 02

EJEMPLO DOS 05 02

DOS

2

13

05 03

EJEMPLO DOS 05 03

DOS

2

14

05 04

EJEMPLO DOS 05 04

DOS

2

15

05 05

EJEMPLO DOS 05 05

DOS

2

16

05 06

EJEMPLO DOS 05 06

DOS

2

17

05 07

EJEMPLO DOS 05 07

DOS

2

18

05 08

EJEMPLO DOS 05 08

DOS

2

19

05 09

EJEMPLO DOS 05 09

DOS

2

20

05 10

EJEMPLO DOS 05 10

-

 

 

 

 

DOS

2

21

10 01

EJEMPLO DOS 10 01

DOS

2

22

10 02

EJEMPLO DOS 10 02

DOS

2

23

10 03

EJEMPLO DOS 10 03

DOS

2

24

10 04

EJEMPLO DOS 10 04

DOS

2

25

10 05

EJEMPLO DOS 10 05

DOS

2

26

10 06

EJEMPLO DOS 10 06

DOS

2

27

10 07

EJEMPLO DOS 10 07

DOS

2

28

10 08

EJEMPLO DOS 10 08

DOS

2

29

10 09

EJEMPLO DOS 10 09

DOS

2

30

10 10

EJEMPLO DOS 10 10

-

 

 

 

 

DOS

2

31

11 01

EJEMPLO DOS 11 01

DOS

2

32

11 02

EJEMPLO DOS 11 02

DOS

2

33

11 03

EJEMPLO DOS 11 03

-

 

 

 

 

DOS

2

34

12 01

EJEMPLO DOS 12 01

 

 

 

 

 

. . .

 

 

 

 

 

                                                                                                                _________

 

 

Entonces tendremos una tabla inicial de relaciones fichero-índice archivada en “lNIDI “, como la siguiente:

 

 

 

Clave (Identificador)

Datos (Posición del índice)

1 [“UNO”]

0

2 [“DOS”]

0

 

 

 

Si se emiten operaciones de posicionamiento y lectura por clave=10 hacia adelante, la tabla evolucionará como en el ejemplo que sigue:

 

 

 

Clave(Identificador)

Datos(Posición del índice)

 

 

1 [“UNO”]

11 [Tras emitir SETLL en UNO]

2 [“DOS”]

21 [Tras emitir SETLL en DOS]

 

 

1 [“UNO”]

12 [Tras emitir READE en UNO]

2 [“DOS”]

22 [Tras emitir READE en DOS]

 

 

1 [“UNO”]

13 [Tras emitir READE en UNO]

2 [“DOS”]

23 [Tras emitir READE en DOS]

 

 

1 [“UNO”]

14 [Tras emitir READE en UNO]

2 [“DOS”]

24 [Tras emitir READE en DOS]

 

 

1 [“UNO”]

15 [Tras emitir READE en UNO]

2 [“DOS”]

25 [Tras emitir READE en DOS]

 

 

                                                                                                                _________

 

 

En cada lectura por clave, se verifica si la clave solicitada se sigue manteniendo en el registro leído, actualizando “lNIDI” con el valor del índice a leer en la siguiente lectura, hasta que la relación se agote y se devuelva EOF de un lado, y de otro se deje “lNIDI” con un valor nulo 0, a la espera de una nueva operación SETLL, así, en la siguiente lectura resultaría:

 

 

 

1 [“UNO”]

0 [Tras emitir READE en UNO con EOF]

2 [“DOS”]

26 [Tras emitir READE en DOS sin EOF]

 

 

El esquema de funcionamiento es el mismo para las lecturas hacia detrás, pero en ellas el índice se hace progresar en sentido contrario como vamos a ver ahora.

 

Si se emiten operaciones de posicionamiento y lectura por clave=11 hacia detrás, la tabla evolucionará como en el ejemplo que sigue:

 

 

 

Clave (Identificador)

Datos (Posición del índice)

 

 

1 [“UNO”]

17 [Tras emitir SETGT en UNO]

2 [“DOS”]

33 [Tras emitir SETGT en DOS]

 

 

1 [“UNO”]

16 [Tras emitir READPE en UNO]

2 [“DOS”]

32 [Tras emitir READPE en DOS]

 

 

1 [“UNO”]

15 [Tras emitir READPE en UNO]

2 [“DOS”]

31 [Tras emitir READPE en DOS]

 

                                                                                                                _________

 

 

Como en las lecturas hacia delante, en cada lectura por clave hacia detrás, se verifica si la clave solicitada se sigue manteniendo en el registro leído, actualizando “lNIDI” con el valor del índice a leer en la siguiente lectura, hasta que la relación se agote y se devuelva EOF de un lado, y de otro se deje “lNIDI” con el valor nulo -1, a la espera de una nueva operación SETGT. Por tanto, en la siguiente lectura resultaría:

 

 

1 [“UNO”]

-1 [Tras emitir READPE en UNO con EOF]

2 [“DOS”]

30 [Tras emitir READPE en DOS sin EOF]

 

En este caso un valor resultado 0 no es marca de error, pues indica que después de la lectura que se acaba de emitir se tendría que leer el registro 0, y es al intentarlo cuando se devolvería -1 como marca de Eof absoluto. Esto sucedería si se pidiese un bucle hacia detrás por clave 01 en el ejemplo, como se muestra a continuación:

 

 

Clave (Identificador)

Datos (Posición del índice)

 

 

1 [“UNO”]

10 [Tras emitir SETGT en UNO]

1 [“UNO”]

9 [Tras emitir READPE en UNO]

1 [“UNO”]

8 [Tras emitir READPE en UNO]

1 [“UNO”]

7 [Tras emitir READPE en UNO]

1 [“UNO”]

6 [Tras emitir READPE en UNO]

1 [“UNO”]

5 [Tras emitir READPE en UNO]

1 [“UNO”]

4 [Tras emitir READPE en UNO]

1 [“UNO”]

3 [Tras emitir READPE en UNO]

1 [“UNO”]

2 [Tras emitir READPE en UNO]

1 [“UNO”]

1 [Tras emitir READPE en UNO]

1 [“UNO”]

0 [Tras emitir READPE en UNO]

1 [“UNO”]

-1 [Tras intentar emitir READPE en UNO]

 

                                                                                                                _________

 

En aras a la sencillez de la implementación no se ha incorporado un mecanismo de cambio automático entre lecturas hacia delante y hacia detrás consecutivas como si se hace en los sistemas físicos.

 

Para su implementación habría que hacer ciertas ampliaciones en la estructura de soporte y en su lógica asociada.

 

Pero como esta situación no es habitual, pues casi siempre se emiten bucles completos o bien de lecturas hacia delante o bien sus recíprocos, pero sin mixtura intermedia, finalmente no se ha llegado a implementar como mecanismo automático, teniendo en cuenta además que si se precisa, hay dos alternativas manuales para hacerlo, la más elegante consiste en emitir un posicionamiento antes del cambio de giro para garantizar la respuesta buscada. Alternativamente se pueden emitir dos lecturas de tipo contrario para acceder al registro previo por clave según la dirección de lectura actual.

                                                                                                                _________

 

 

Veamos a continuación las funciones que implementa SRRCN para responder a este esquema de funcionamiento

 

 

A.I.6.3 Las funciones de posicionamiento y lectura por clave

 

 

- Funciones de posicionamiento

 

 

SRRCN_SETLL(long lNIDp, const void *vCLVp, long lLong)

Situar por menor o igual

SRRCN_SETEQ(long lNIDp, const void *vCLVp, long lLong)

Situar por igual

SRRCN_SETGT(long lNIDp, const void *vCLVp, long lLong)

Situar por mayor

SRRCN_SETGTT(long lNIDp, const void *vCLVp, long lLong)

Situar por mayor +

 

 

Estas funciones localizan el ítem indicado con la orientación pedida y lo reservan en el fichero de relaciones, para poder ser utilizado en el siguiente grupo de funciones.

 

Así, SETLL sitúa a partir del primer ítem con la misma o superior clave que la solicitada, SETEQ solo sitúa si hay un ítem de la misma clave, SETGT sitúa en el último ítem de un grupo de la misma clave, dejando el sistema preparado para efectuar un bucle completo hacia detrás de todos los ítems del mismo grupo; mientras que SETGTT deja al sistema situado en el ítem siguiente, dejándolo preparado para leer el primer ítem de clave superior a la proporcionada.

 

Con este juego de funciones se cubre el repertorio completo de situaciones en las que nos encontraremos a la hora de emitir bucles de proceso, compaginándolas con las del siguiente grupo:

 

 

- Funciones de lectura, hacia delante y hacia atrás

 

 

SRRCN_READE(long lNIDp, const void *vCLVp, long lLong, void *vDato, void *vClav)

Lectura por igual hacia adelante

SRRCN_READPE(long lNIDp, const void *vCLVp, long lLong, void *vDato, void *vClav)

Lectura por igual hacia atrás

 

 

Que se encargan de emitir la lectura solicitada verificando el mantenimiento de la relación.


                                                                                                               
_________

 

A.I.6.4 Implementación

 

El código central de las rutinas se explica a continuación para la rutina de lectura por igual hacia delante. El proceso para la lectura por igual hacia detrás es similar y se presenta más adelante.

 

 

Cuando se va a proceder a un bucle de lectura por clave, la primera tarea es situarse en el archivo.

 

Se invoca entonces a la rutina de posicionamiento por menor o igual:

 

//-------------------------------------------------------------------------------------

// Función SRRCN_SETLL

//

// Descripción: Sitúa en el índice de memoria-clave + próximo inferior (+ 1) o en el

//              índice exacto del ítem, dejando a SRRCN preparado para responder al

//              SRRCN_READE siguiente

//

// Parámetros

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

//

// Retorno

//         0: Error de proceso (No encontrado...)

//        >0: Índice en memoria-clave + próximo inferior (+1), formato 1..N

//-------------------------------------------------------------------------------------

 

SRRCN_SETLL(long lNIDp, const void *vCLVp, long lLong);

 

 

Donde, en esencia, se ejecutan las sentencias siguientes:

 

...

 

// Valor significativo de clave

 

memset(cClavW, '\x00', iDimC);

memcpy(cClavW, cCLVp, lLong);

 

 

// Posicionamiento inferior + 1

 

lINDI = SRRCM_SETLL(lNIDp, cClavW) + 1;  // Busca el índice de situación

lResult = SRRCN_SavIndSet(lNIDp, lINDI); // y lo guarda para el reade posterior del siguiente registro

 

...

                                                                                                                _________

 

 

 

A continuación se emiten las lecturas que se desean, llamando a la rutina

 

//-------------------------------------------------------------------------------------

// Función SRRCN_READE

//

// Descripción: Recupera el siguiente ítem de memoria, manteniendo clave igual

//

// Parámetros

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

// (salida) *vDato: Datos del ítem

//          *vClav: Valor de clave completo asociado

//

// Retorno

//               0: Error de proceso (No encontrado...)

//              >0: Índice en memoria-clave de ítem encontrado + 1, formato 1..N,

//                  posición de próxima lectura, se archiva en la variable global

//                  lINDI/W para uso interno posterior en +READE, etc

//-------------------------------------------------------------------------------------

 

SRRCN_READE(long lNIDp, const void *vCLVp, long lLong, void *vDato, void *vClav);

 

 

Donde en esencia se ejecutan las sentencias siguientes

 

...

 

// Recupera el índice de lectura en curso

 

lINDI = SRRCN_RtvIndSet(lNIDp); // Obtenido en el SETLL o en el READE previo

 

 

// Emite la lectura asociada

 

if (lINDI) er = SRRCM_READC(lNIDp, lINDI, vDato, vClav);

 

 

// Eof absoluto

 

if (er)

{

 lINDI = 0;

 lResult = SRRCN_SavIndSet(lNIDp, lINDI);

 return lINDI;

}

 

 

// Control de clave de lectura errónea

 

iComp = memcmp(vCLVp, cClavW, lLong);

if (iComp)

 

 // Eof por agotamiento de datos de la clave solicitada

{

 lINDI = 0;

 lResult = SRRCN_SavIndSet(lNIDp, lINDI);

 return lINDI;

}

 

 

// Progresa y archiva índice para control de la siguiente lectura

 

++lINDI;

lResult = SRRCN_SavIndSet(lNIDp, lINDI);

 

 

// devuelve índice de próxima lectura del fichero en formato 1..N

 

return lINDI;

 

...

                                                                                                                _________

 

 

Cuando se va a proceder a un bucle de lectura por clave hacia detrás, también la primera tarea es situarse en el archivo.

 

Se invoca entonces a la rutina de posicionamiento por mayor:

 

//-------------------------------------------------------------------------------------

// Función SRRCN_SETGT

//

// Descripción: Sitúa en el índice de memoria-clave en el último elemento más próximo

//              superior, dejando a SRRCN preparado para responder a SRRCN_READPE, etc

//

// Está pensado para seleccionar un subgrupo de ítems y recorrerlo de fin a

// principio, por ello devuelve la posición final del grupo. Si se desea

// dejar situado para leer el siguiente elemento, úsese SRRCN_SEGTT

//

// Parámetros

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

//

// Retorno

//          <0: Error de proceso (No encontrado...)

//         >=0: Índice en memoria-clave + próximo superior, formato 1..N

//-------------------------------------------------------------------------------------

long SRRCN_SETGT(long lNIDp, const void *vCLVp, long lLong)

 

Donde esencialmente se ejecutan las sentencias siguientes, en las que aparecen unas pequeñas diferencias frente a sus correspondientes del posicionamiento directo que se han resaltado en negrita:

 

...

 

char cUltChar; // Variable auxiliar que recoge el último char significativo de la clave

 

...

 

 

// Valor significativo de clave

 

memset(cClavW, '\x00', iDimC);

memcpy(cClavW, cCLVp, lLong);

 

 

 

// Ultimo carácter significativo de clave + 1

 

memcpy(&cUltChar, cClavW + lLong -1, 1);

++cUltChar;

memset(cClavW + lLong - 1, cUltChar, 1);

 

 

 

// Sitúa y pasa índice previo (Será el último + próximo buscado)

 

lINDI = SRRCN_SETLL(lNIDp, cClavW, lLong) - 1; // Busca el índice-1 de situación

lResult = SRRCN_SavIndSet(lNIDp, lINDI);       // y lo guarda para el readpe posterior del siguiente registro

 

...

 

                                                                                                                _________

 

 

A continuación se emiten las lecturas inversas que se deseen, llamando a la rutina

 

//----------------------------------------------------------------------------------

// Función SRRCN_READPE

//

// Descripción: Recupera- un ítem de memoria, manteniendo clave igual

//

// Parámetros

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

// (salida) *vDato: Datos del ítem

//          *vClav: Valor de clave completo asociado

//

// Retorno

//         -1: Error de proceso (No encontrado...)

//        >=0: Índice en memoria-clave de ítem encontrado - 1, formato 1..N,

//             posición de próxima lectura, se archiva en la variable global

//             lINDI/W para uso interno posterior en +READPE, etc

//

// Es importante remarcar que una respuesta nula esta dentro del rango correcto,

// a diferencia de cómo sucede en la rutina de posicionamiento directo

//----------------------------------------------------------------------------------

long SRRCN_READPE(long lNIDp, const void *vCLVp, long lLong, void *vDato, void *vClav)

 

Donde en resumen se ejecutan las sentencias siguientes

 

...

 

// Recupera el índice de lectura en curso

 

lINDI = SRRCN_RtvIndSet(lNIDp);

 

 

// Emite la lectura asociada

 

er = SRRCM_READC(lNIDp, lINDI, vDato, vClav);

 

 

// Eof absoluto

 

if (er)

{

 lINDI = -1;

 lResult = SRRCN_SavIndSet(lNIDp, lINDI);

 return lINDI;

}

 

 

// Control de clave de lectura errónea

 

iComp = memcmp(cCLVp, cClavW, lLong);

if (iComp)

 

 // Eof por agotamiento de datos de la clave solicitada

{

 lINDI = -1;

 lResult = SRRCN_SavIndSet(lNIDp, lINDI);

 return lINDI;

}

 

 

// Progresa y archiva índice para control de la siguiente lectura

 

--lINDI;

lResult = SRRCN_SavIndSet(lNIDp, lINDI);

 

 

// Devuelve índice próxima lectura del fichero en formato 1..N

 

return lINDI;

 

...

                                                                                                                _________

 

En la línea de las opciones de posicionamiento, se tiene por último la siguiente variante del SETGT, el SETGTT, pensada para situarse en el registro siguiente al de la clave solicitada:

 

//----------------------------------------------------------------------------------

// Función SRRCN_SETGTT

//

// Descripción: Sitúa en el índice de memoria-clave en el último elemento más próximo

//              superior, dejando a SRRCN preparado para responder a SRRCN_READE, etc

//

//              La rutina deja situado el índice de lectura en el elemento siguiente

//              al último que hubiera de clave igual a la indicada. Si por el

//              contrario se desea seleccionar un subgrupo de ítems y recorrerlo de

//              fin a principio, utilicese SRRCN_SETGT que, precisamente con esa

//              intención, deja situado el índice al final de un grupo

//

// Parámetros

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

//

// Retorno

//         0: Error de proceso (No encontrado...)

//        >0: Índice en memoria-clave + próximo superior, formato 1..N

//----------------------------------------------------------------------------------

long SRRCN_SETGTT(long lNIDp, const void *vCLVp, long lLong)

{

 long lResul = 0; // Control de resultados

 char *cCLVp = (char *) vCLVp; // Auxiliar para debug

 

 

// Sitúa y pasa índice (modificado +1 hacia adelante)

 

lINDI = SRRCN_SETGT(lNIDp, cCLVp, lLong) + 1;

lResul = SRRCN_SavIndSet(lNIDp, lINDI);

 

return lINDI;

}

                                                                                                                _________

 

 

En cuanto a la codificación de las rutinas de salvado y restauración del índice de emparejamiento, representan buenas muestras del uso directo de SRRCM, que no volveremos a ver en los ejemplos, pues siempre se utilizará su interfaz superior SRRCW.

 

 

La rutina de salvado de enlace se basa en el UPDATE:

 

//----------------------------------------------------------------------------------

// Función SRRCN_SavIndSet

//

// Descripción: Salva índice en curso para resto de funciones SRRCN

//

// Parámetros

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//           lINDp: Índice que se salva

//

// Retorno

//        0: Error de proceso (Memoria agotada,...)

//       >0: Posición en memoria del índice salvado, formato 1..N

//----------------------------------------------------------------------------------

long SRRCN_SavIndSet(long lNIDp, long lINDp)

{

 long lIndiw=0; // Índice auxiliar

 

 

 // Establece NID de índices y graba reg.inicial nulo si procede

 

 if (!lNIDI) return SRRCN_NewIndSet(lNIDp);

 

 

 // Actualiza el valor del índice

 

 lIndiw = SRRCM_UPDATE(lNIDI, &lNIDp, &lINDp);

 if (!lIndiw) lIndiw = SRRCM_WRITE(lNIDI, &lNIDp, &lINDp);

 

 return lIndiw;

}

 

 

Por su parte, la rutina de recuperación del enlace se basa en el CHAIN y se codifica como

 

//----------------------------------------------------------------------------------

// Función SRRCN_RtvIndSet

//

// Descripción: Recupera índice en curso para resto de funciones

//

// Parámetros

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//

// Retorno: Índice buscado

//----------------------------------------------------------------------------------

long SRRCN_RtvIndSet(long lNIDp)

{

 long lIndiw=0;  // Índice auxiliar

 long lResult=0; // Aux.paso resultados de índice intermedio

 

 

 // Establece NID de índices y graba registro inicial nulo si procede

 

 if (!lNIDI) return SRRCN_NewIndSet(lNIDp);

 

 

 // Recupera el valor del índice solicitado

 

 lResult = SRRCM_CHAIN(lNIDI, &lNIDp, &lIndiw);

 

 return lIndiw;

}

                                                                                                                _________

 

 

Ambas rutinas comparten la rutina común de generación del fichero de enlace siguiente, que ya hemos anticipado en parte en la presentación del capítulo

 

//----------------------------------------------------------------------------------

// Función SRRCN_NewIndSet

//

// Descripción: Rutina común de generación del soporte del fichero de relaciones

//

// Parámetros

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//

// Retorno implícito:

//                   lNIDI: Identificador del fichero de relaciones

//----------------------------------------------------------------------------------

long SRRCN_NewIndSet(long lNIDp)

{

 long lIndiw=0; // Índice auxiliar

 long lIndi0=0; // Índice nulo

 

 

 // Establece NID de índices y graba registro inicial nulo

 

 lNIDI = SRRCM_NEW(sizeof(long), sizeof(long));

 lIndiw = SRRCM_WRITE(lNIDI, &lNIDp, &lIndi0);

 

 return 0;

}

 

                                                                                                                _________

 

 

 

Las pruebas de la versión SRRCW de estas funciones se presentan en el programa PruebasW y en múltiples ejemplos de aplicación de la segunda parte de esta zona del libro, así como en los apéndices dedicados a los manuales de usuario.

 

La codificación se ha presentado extractada y con comentarios añadidos para facilitar el seguimiento de la presentación. No debe considerarse como un código plenamente operativo. Se invita a consultar el código completo del módulo SRRCN.cpp , bien directamente o bien desde el capítulo

"C3 Detalle de relación de programas de servicio (DLL) soporte de de los ficheros virtuales"

 

 

 

                                                                                                                _________