Sobre implementación de archivo base de datos Arduino

Lucario448:
A diferencia de tu implementación, yo tenía pensado agregar una sección opcional y dos obligatorias en la cabecera: . . . . .
. . . .
Pero bueno, al ser una implementación cuya utilidad aún se cuestiona, todavía hay que pensar detenidamente qué vale la pena agregar y qué no.

Ten en cuenta que esto sería interesante si quieres realizar algún tipo de estándar para poder leerlo desde un ordenador o de forma genérica desde otro arduino. En un arduino la utilidad que puede tener una "base de datos" (la llamaremos así, aunque sabemos que está lejos de serlo) a mi entender, es como forma de guardar y poder rescatar de una forma efectiva una determinada información entre un conjunto grande. Si deseo que esa información sea generable o importable desde un ordenador, por ejemplo; tengo dos opciones: hacer un programa para ordenador que entienda mi estructura de datos, o estudiar e intentar ceñir mi archivo a algún tipo de estructura conocida (dbf, mdb...). Tal vez la segunda opción sería más "rentable", aunque a primera vista parezca más difícil.

Lucario448:
Si el tamaño del registro se declara excesivo, esto no sería posible cuando estamos apretados en RAM.

Ten en cuenta que lo habitual es que al menos tengas una estructura de ese tipo para guardar y/o recuperar registros. Puedes utilizar la misma para poner unos datos de índice, ejecutar búsqueda sobre ella y recuperar los datos del registro. Vamos; que es bastante "reciclable".

Lucario448:
Explícate bien esa parte, que de primera impresión me pareció contradictorio.

Si modifico un registro ya existente, entonces podría deliberadamente arruinar el orden (a menos que se esté aplicando un algoritmo de ordenamiento en cada intento). Para evitar la situación anterior, se lanza un error; por lo tanto... ¿no se pueden modificar registros existentes? :confused:

Supon que tienes como campos de índice (único, no lo olvidemos) Apellido-Nombre-Teléfono. Creas una función que compare esos tres campos y devuelva mayor, menor o igual. El resto de campos no afectan a la ordenación.
Ahora; recuperamos el registro Zutano-Fulano-12345 y cambiamos su dirección, correo electrónico, etc... Guardamos y sobreescribimos sin problema. Sin embargo, ahora tras recuperarlo modificamos, por ejemplo su nombre: Zutano-Mengano-12345. Esto afecta al índice y potencial posición en la ordenación. Entonces, calcula la nueva posición, modifica el registro y mueve el índice a su posión pero, ¿Y si ya existía previamente un Zutano-Mengano-12345? En ese caso no toco nada y retorno error.

Lucario448:
Este siempre está después del último puntero válido del vector, ¿o no?. Si están mezclados, ¿cómo vas a determinar un puntero inválido?

Porque no están mezclados. En la cabecera indico el número de registros válidos y el de registros borrados. Pongamos que tengo 6 índices a válidos y 3 a borrados. Primero calculo en qué posición tiene que ir el índice. Supongamos que tiene que ir a la posición 3. Miro si hay borrados (sí) tomo el primer índice borrado, que estaría en la posición 6 (posición inicio de índices + 6*sizeof(puntero)). Lo leo y veo dónde apuntaba. Escribo la información donde apuntaba este índice, y a continuación tengo que desplazar el índice borrado desde la posición 6 (primer borrado) hasta la posición 3 (lugar que le corresponde por ordenación). Ya sólo queda modificar la información de cabecera (+1Válido, -1Borrado). Del mismo modo, si borro un registro válido, tengo que desplazar su índice hasta el final de los índices válidos, y alterar la cabecera en sentido inverso (-1válido, +1 borrado). Como digo, estas son las operaciones más "penosas" si hay un gran número de registros. Por ejemplo un desplazamiento de 100000 registros arriba o abajo requeriría desplazar cuatro veces (unsigned long) dicha información.

Lucario448:
Entonces haces crecer el archivo según la demanda; en vez de fijar su tamaño inicialmente.

Efectivamente, va creciendo a demanda. Lo que no hace es decrecer a demanda. Implementé el sistema de mover el primer registro de datos al final cuando necesito más espacio para los índices; pero no implementé el método opuesto; es decir, que si creo mil registros y borro quinientos, la tabla no decrecerá de tamaño, aunque los nuevos registros tampoco la harán crecer mientras tenga borrados que machacar.

Lucario448:
En ese caso se me ocurre que la cabecera acabe en un puntero a la tabla de índices

No es necesario en mi caso, porque la posición de la tabla de índices es fija y conocida, a continuación del header. Si quisieras implementar un descriptor de campos sí tendrías que almacenar de alguna manera el inicio de dicha tabla.

Lucario448:
Para esto tendrías que decidir si los registros deben tener una longitud múltiplo de 4, o la tabla deber ser múltiplo del tamaño de los registros

Los registros pueden tener el tamaño que quieras, siempre que sea fijo. Los índices sí tienen tamaño de cuatro bytes.

Lucario448:
Conviene nunca fragmentarla; de lo contrario la tabla pasará a ser una lista enlazada.

Los índices están consecutivos y ordenados (y a continuación los borrados) y no permito fragmentación. Sin embargo los bloques de datos, aunque consecutivos, están desordenados.