IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

[LIB] librairie de cache en C ?


Sujet :

C

  1. #21
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Ca facilite beaucoup l'accès à ces données plutôt qu'un tableau de void*.
    L'accès est facilité, mais tu dois avoir un nombre de strutures incroyable... si je ne me trompe pas, ca donne quelque chose du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (les nombres choisis sont des exemples)
    Nombre de types différents existants : 3  (int, float, char*)
    Nombre de colones max d'une requète : 5
     
    Nombre de structures possibles :  3^1 + 3^2 + 3^3 + 3^4 + 3^5 !!
    Et puis comment tu parcours un tableau de void* ? je doute que l'accès au 6ème champ (par exemple) se fasse par "champ[5]"...
    Si si, bien sûr, comme pour un tableau de n'importe quel type. Seulement, il va falloir caster ton void* en un type concret (int*, float*, ...) pour pouvoir l'utiliser. Il te faut donc des infos en plus, stockées dans ton resultset, pour savoir de quel type est chaque colone.


    Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    enum type
    {
         entier,
         flottant,
         chaine
    };
     
    struct resultset
    {
            int     nb_colones;
            type*   types_colones;   // tableau des types contenus
            void**  contenu_colones;    // tableau des contenus eux-même (void*)
    };
    Mais j'imagine que tu as déjà un code qui fonctionne pour tout cela. Mais c'est vrai que pour mettre en cache ces resultset différents, en programmation non OO, je ne vois pas de solution évidente, à part ce type de cast peu élégant.

    Peut-être que quelqu'un peut donner son avis la dessus ?

  2. #22
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Par défaut
    Désolé mais on a du mal se comprendre, je n'ai pas un nombre hallucinant de structures différentes, juste autant que de resultset définis dans les procédures stockées (gdb sybase).

    Exemple dans une proc stockée j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select codeHotel, numResa, date, numJour
    from #resa
    Je stockerais chaque ligne dans une structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
      char codeHotel[4];;
      char numResa[12];
      char date[10];
      short numJour;
    } Resa
    et la totalité du resultset dans un tableau de cette structure.

    Si jamais le resultset change, je dois changer la structure bien sûr.


    Pour ce qui est de ta solution, elle est intéressante, puisqu'elle me permet de n'avoir qu'une seule structure pour tous les resultset, mais l'utilisation me paraît assez fastidieuse, à moins de développer une couche englobant l'implémentation de ce système...

    Peux-tu développer un peu plus l'accès à des éléments d'un tableau de void* ?

    Merci

  3. #23
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Ahhhhhh
    D'accord, je ne savais pas que tu disposais d'un nombre de requètes bien fixes. A ce moment là, en effet plus de problème, sauf pour le stockage en cache, ou je ne vois pas comment faire cohabiter ces structures au sein d'une même table de hachage.

    Pour ce qui est du tableau de void*, l'accès se fait comme dans un tableau normal: tab[5]. Mais tu vas obtenir un void* qu'il faut ensuite caster comme il faut il faut donc connaitre le type exact de ce qui se cache derrière, par exemple avec une structure "header" qui indique ce que contiennent tes colones.

    Mais quitte à avoir un "selecteur" pour retrouver le type de chaque colone, autant finalement utiliser une union. Par exemple, en modifiant le code du post précédent:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    // types utilisables
    enum type
    {
         entier,
         flottant,
         chaine
    }; 
     
    // en tête de résultat : les colones
    typedef struct
    {
         int     nb_colones;              // nombre de colones
         type*   types_colones;    // leur type
    } header;
     
     
    // une case de ton tableau final (par ex. ligne 3 colone 2)
    typedef union
    {
        int      entier;
        float    flottant;
        char*   chaine;
    } case;
     
     
    // la totalité des resultats
    typedef struct
    {
         header   entete;
         int       nb_resultsets;    //  nombre de lignes
         case**   resultsets;         //  tableau représentant les lignes (ligne = case*)
    } resultat;
    et maintenant l'utilisation
    par exemple si on a fait une requete de type {int, float, char*}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    resultat  r;
     
    r.entete.nb_colones = 3;  // int, float, et char*
    r.entete.types_colones = malloc( r.entete.nb_colones * sizeof(type) );
    r.entete.types_colones[0] = entier;
    r.entete.types_colones[1] = flottant;
    r.entete.types_colones[2] = chaine;
     
    // on va dire que la requete a retourné 15 lignes
    r.resultsets = malloc( 15 * sizeof(case*) );
    for (int i=0; i<15; ++i)
       r.resultsets[i] = malloc( r.entete.nb_colones * sizeof(case) );
     
    r.resultsets[0][0].entier    = 5;
    r.resultsets[0][1].flottant  = 3.567;
    r.resultsets[0][2].chaine   = ....;
     
    // pour une autre requete qui retourne {char*, int} tu pourrais faire:
    r.resultsets[0][0].chaine  = ...;
    r.resultsets[0][1].entier   = 3;
    // mais avec un header qui reflete bien cette structure !
    Pour les récuperer, il faut simplement tester ce qui se trouve dans le header:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (r.entete.types_colones[0] == entier)
       printf("%d\n", r.resultsets[i][0].entier);
    Voilà, c'était un début d'explication, pas forcément très clair , mais c'est un moyen comme un autre de stocker toutes tes requetes dans la même structure. Et il faut bien sûr penser a libérer la mémoire allouée

    Voilà, avec ça pas de problème pour les stocker dans ta table de hachage. Mais quelqu'un a peut-être une autre idée pour utiliser ta méthode courante, avec plusieurs strcture différentes ?

  4. #24
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Par défaut
    Si si c'est très clair !! Merci pour cette solution intéressante, je vais réfléchir à son intégration.

    En fait là tu n'utilises finalement pas de tableau de void*, la question que je me posait quant à l'utilisation d'un void**, c'est l'accès au données. En effet tu peux faire en sorte de savoir que le 3ème élément du tableau est un type char ou int (peu importe) et donc le caster en conséquence.
    Mais pour y accéder ça me paraît plus hard avec "element[2]" car element[0] peut-être un char[12] et element [1] peut-être un int, donc un taille différente !! Ya une solution à ce genre de problème ?

  5. #25
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Mmmm, si tu as un tableau de void*, tu stockes dedans uniquement des pointeurs. Donc des pointeurs sur int, sur char (pour les chaines), sur float .... A toi de caster ton void* en int*, char*, .... en fonction. Par contre ça implique une allocation dynamique systematique, ce qui n'est vraiment pas top niveau performances (*).

    Pour éviter cette allocation dynamique, en stockant les types POD directement dans le tableau, je pense qu'il faut passer par une union (comme dans le code du post précédent).

    Après, il est même possible de faire une union
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    union
    {
          int entier;
          float flottant;
          char chaine[32];
    };
    mais rappelle-toi que l'union va occuper la place de l'élément le plus gros (logique ...). Donc la elle occupera 32 octets, pour chaque case du tableau, même si il n'y a qu'un int stocké dedans C'est pas top ....

    D'où le char* pour gérer les chaines de caractère dans l'union. Ton union (int,float,char*) ne prendra que 4 octets, donc pas de perte apparente. Et les chaines seront le seul type géré par allocation dynamique dans tes resultset.

    --

    (*) : <mode déconsillé, pas beau, non portable, et illisible>
    Dans le cas d'un tableau de void*, tu "pourrais" te passer de l'allocation dynamique pour les int et les float. Sur une architecture 32 bits classique ils font tous les deux 4 octets, comme un pointeur. Donc il serait possible de les stocker dans le void*, et des les récuperer tels quels. Mais de jamais (!!!) s'en servir comme pointeur. Enfin de toute façon il ne faut pas le faire
    </mode déconsillé, pas beau, non portable, et illisible>

  6. #26
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Par défaut
    Très instructif tout ça, merci !!

  7. #27
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    J'espère que j'ai pas raconté trop de bétises alors ....
    Mais je me suis relu, normalement ça va

    Ca serai sympa d'avoir un autre avis sur la manière dont tu pourrais procéder pour stocker tes resultats dans ta table de hachage... Pour l'instant, je ne vois qu'un changement de structure 1 seule et même structure pour stocker tous les types de résulats.... Il y a peut-être une autre solution...

    Mais c'est vrai que l'avantage de celle-ci, si tu découpes bien ton architecture de manière modulaire, c'est qu'il sera facile de rajouter des requètes, puisqu'il faut simplement créer une nouvelle instance de ta structure, avec le bon header, et elle pourra s'ajouter aux autres de manière transparente.

  8. #28
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Par défaut
    En effet ce serait pratique.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Fichier *.lib (librairie perso)
    Par lecteur1001 dans le forum Simulink
    Réponses: 0
    Dernier message: 28/06/2011, 15h14
  2. Réponses: 4
    Dernier message: 24/10/2008, 11h42
  3. Question sur les librairies .lib
    Par elvivo dans le forum Autres éditeurs
    Réponses: 5
    Dernier message: 05/10/2005, 20h06
  4. inclure une librairie *.lib
    Par darkbm dans le forum C
    Réponses: 2
    Dernier message: 16/12/2002, 22h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo