Go Down

Topic: Gestión e indexación de registros de una tabla en SD. (Read 15700 times) previous topic - next topic

maxid

Noter. Le estoy dando caña a la libreria y me pregunto que performance tiene en la busqueda.
Bueno hice una prueba en una base con 4 registros

buscar el registro numero:

3: 152 microsegundos
1: 440 microsegundos
4: 300 microsegundos
2: 296 microsegundos

nuevamente el 3: 152 microsegundos

Registros no encontrados: 440,296,210 depende de que numero intenta comparar

Lo mas importante estos valores se mantienen entre reseteos y reprogramaciones

Espero ayudar con esto

coloco la porcion para calcular el tiempo


Code: [Select]

    unsigned long t0;
    unsigned long t1;
.
.
.
.
.
   t0= micros();
    if (bbdd.EncuentraIndex(nuevo, numRegistro) == FDB_OK)
    {
      t1= micros();   
      Serial.print(F("Encontrado en pos "));
      Serial.println(numRegistro);
      }
      else
      {
        t1= micros();   
        Serial.print(F("No hay coincidencia. Posición registro actual: "));
        Serial.println(numRegistro);
      }
      Serial.print("Tiempo de busqueda: ");
      Serial.println(t1-t0); //imprimo cuanto tarda en encontrar

El que pregunta aprende, el que responde aprende a responder.

noter

Gracias, maxid; aunque con pocos registros no creo que el rendimiento sea superior a una lectura secuencial. Aún no la he puesto a prueba en serio, pero donde debería ser "rentable" es con gran número de registros, ya que con n comparaciones debería poder encontrar un registro indexado entre 2n registros, es decir, que con 16 comparaciones debería poder encontrar un registro entre más de 60000 registros. Ahí sí que debería ser más eficiente que ir leyendo todo.
Aún no he necesitado algo así, pero como dije, creo que puede ser una buena opción para tratar un volumen de datos importante sin necesidad de recurrir a conexión con una bbdd externa.

maxid

Si entiendo Noter, pasa que no me puse a cargar tantos datos.
Y me picaba la curiosidad de cuanto tarda en encontrarlo, mas que todo por la eficiencia de la memoria en modo spi.
En breve si funciona todo tendre funcionando una con cerca de 100 usuarios.

Lo que me interesa si me podes ayudar es a hacer el archivo desde una pc basado en la estructura, facilitaria las pruebas y carga de datos, redueciendo codigo, que ya voy medio ajustado.
El que pregunta aprende, el que responde aprende a responder.

Marcial

En una SD es posible leer una dirección determinada, como si fuera una eeprom?

noter

Efectivamente, Marcial, sí se puede leer una dirección determinada. En eso baso la indexación. El índice es una serie de datos unsigned long (4 bytes) ordenados según nuestro criterio. Cada uno de esos unsigned long apunta a la dirección donde está realmente el registro. De esta forma evito en lo posible mover los registros completos. Si, por ejemplo, quiero insertar un registro, el registro lo coloco directamente al final, en lugar de tener que insertar y mover todos los datos que hay por detrás. En su lugar sólo muevo los índices.
En cuanto a lo que dices tú, maxid, claro que te puedo ayudar, si me explicas qué quieres concretamente; pero en principio no debería ser complicado hacer una rutina que lea datos por serie y te los inserte en la tabla, o un archivo csv o similar y que inserte los registros; y viceversa.

Marcial

Si el fichero no es muy grande, puedes hacer un fichero de acceso random, ocupara muco mas, pero no necesitaras mantener indices

maxid

En cuanto a lo que dices tú, maxid, claro que te puedo ayudar, si me explicas qué quieres concretamente; pero en principio no debería ser complicado hacer una rutina que lea datos por serie y te los inserte en la tabla, o un archivo csv o similar y que inserte los registros; y viceversa.
Lo que decia es un lector de este archivo en pc. No lei el fuente completo para entender la estructura del fichero. Para leerlo o crearlo externamente al equipo arduino.
Pero voy a armar un pequeno programa que por serial le envie comandos de alta y baja.
El que pregunta aprende, el que responde aprende a responder.

noter

Tal y como está ahora la librería, no es posible hacer un "lector de datos FDB" (habría que hacer uno específico para cada archivo), ya que no he incluido (sería posible, pero no sé si merecerá la pena embarcarse) en la cabecera datos que indiquen el nombre y tipo de campo. Ya puestos, lo lógico sería entonces estudiar y tratar de implementar algún tipo de archivo de datos estándar.
Marcial; no entiendo qué quieres decir exactamente con acceso random. Si te refieres simplemente a fichero sin índices, lo lógico es que ocupe menos y en la mayoría de los casos quizás sea lo más adecuado. Con sólo saber el tamaño de registro puedes desplazarte directamente a uno en una posición cualquiera. De hecho la floritura esta que me ha salido, aún no he necesitado utilizarla con fuego real.

maxid

Si no tienen cabecera no hay problemas, en pascal puedo crear una estructura que coincida con la de los datos y asi leerla, por bloques. Solo queria saber hasta donde llega el indice y donde comienza los datos.
El que pregunta aprende, el que responde aprende a responder.

maxid

Tal y como está ahora la librería, no es posible hacer un "lector de datos FDB" (habría que hacer uno específico para cada archivo), ya que no he incluido (sería posible, pero no sé si merecerá la pena embarcarse) en la cabecera datos que indiquen el nombre y tipo de campo. Ya puestos, lo lógico sería entonces estudiar y tratar de implementar algún tipo de archivo de datos estándar.
Marcial; no entiendo qué quieres decir exactamente con acceso random. Si te refieres simplemente a fichero sin índices, lo lógico es que ocupe menos y en la mayoría de los casos quizás sea lo más adecuado. Con sólo saber el tamaño de registro puedes desplazarte directamente a uno en una posición cualquiera. De hecho la floritura esta que me ha salido, aún no he necesitado utilizarla con fuego real.
eso que mencionas es un formato .dbf solo que en dbase se almacena como texto y la cabecera servia para saber como manejarlos, su sucesor fue paradox que manipulaba cada campo como su tipo nativo, haciendo mas eficiente el manejo y podian llegar hasta los 128mb el tamaño del archivo.

Tambien es posible hacrlo de esa manera con un indice externo, y un almacen secuencial. El indice se recrea en cualquier momento releyendo el almacen como hacian en dbf
El que pregunta aprende, el que responde aprende a responder.

Marcial

Noter, long time ago, cuando yo estudie informática y franco era cabo, se llamaban ficheros de acceso random a un tipo de ficheros a los que se podía acceder directamente a cada registro, pero no eran indexados.

El fichero, en función del tamaño del registro y de la clave, reserva espacio suficiente para todos los registros posibles, y la clave servia para calcular la dirección del registro, pero ahora que ni Juan Carlos es rey, a saber como se llaman esos ficheros  :)

noter

Jeje, Marcial. Cuando yo estudié informática franco aún era corneta. Efectivamente, entendí perfectamente a qué te referías. Aunque siendo tiquismiquis, el acceso aleatorio/secuencial no se refiere a cómo se trabaja con una base de datos, sino cómo se puede leer o escribir en un archivo; si puedes acceder a leer o escribir cualquier parte directamente o tienes que comerte la vaca entera... ¿te acuerdas de las cintas del zx81 o spectrum?. Por supuesto que sin acceso aleatorio una base de datos sería una pesadilla, pero con índices, sin índices, archivos de imagen o de cualquier tipo, todos los archivos en disco o SD se pueden acceder aleatoriamente.
Mañana te envío un esquema de cómo va organizado el archivo, aunque si miras la cabecera de la librería verás la estructura header que te puede dar alguna pista (agrego comentarios):

Code: [Select]
struct FDB_Header
{
     unsigned int rec_size; // Posición 0-1, indica qué tamaño va a tener nuestro registro.
     IdReg filledRecords;  // Posición 2-5, número de índices a registros no borrados (a continuación del header)
     IdReg deletedRecords; // Posición 6-9, número de índices a registros borrados (tras los índices no borrados)
     FilePointer dataStart; // Posición 10-13, dirección a partir de donde se encuentran los datos
};


Continuando con el archivo:
- Pos 14 hasta 14+4*filledRecords Índices ordenados de dirección(unsigned long). Cada index apunta a la posición en la que está el dato que indexa.
- Pos 14+4*filledRecords hasta 14+4*(filledRecords+deletedRecords), Índices borrados. El dato sigue en su posición, pero los índices "saltan" a esta zona. Un nuevo registro reutilizará en primer lugar estos índices y su espacio de datos si existen, en lugar de ampliar tamaño de archivo. También cabría la posibilidad de devolver el index a su sitio y deshacer borrados.
- Pos dataStart hasta final de archivo: bloques de datos. Aquí están los registros propiamente dichos. No están ordenados (los índices dicen qué registro va en qué posición). También encontraremos los datos de los registros eliminados, salvo que la escritura de otros los hayan machacado.

El proceso para obtener un registro en posición ordenada n, sería mover la "cabeza lectora" primero a la dirección 14+4*n, leer dirección (unsigned long), mover a la dirección leída, y cargar la estructura.

No sé si te he aclarado algo o te he liado más, pero cualquier cosa que te pueda aclarar, no dudes en consultar.

maxid

Ok, me pongo a ver de a poco como lo hago. Estoy medio apurado con hacer andar esto.
Por ahora lo voy a enviar por serial y depues veo como lo resuelvo.
El que pregunta aprende, el que responde aprende a responder.

noter

Lo dicho. Cualquier ayuda que necesites sólo tienes que pedirla.

maxid

Noter, la libreria viene andando de maravillas por ahora.
Le hice un cambio usando la libreria SdFat que es mejorada y tiene manejo de memorias mas grandes.
Y lo curioso que en el ejemplo de basededatos me bajo -2224 bytes de programa, pero si consume  +12 byte mas de ram.
Y es totalmente compatible, para tenerlo en cuenta.
El que pregunta aprende, el que responde aprende a responder.

Go Up