.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "fr::crypto::lhash 3SSL" .TH fr::crypto::lhash 3SSL "2015-12-31" "1.0.2a 1.0.2c" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NOM" .IX Header "NOM" lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_error \- table de hachage dynamique .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& #include \& \& DECLARE_LHASH_OF(); \& \& LHASH *lh__new(); \& void lh__free(LHASH_OF( *table); \& \& *lh__insert(LHASH_OF( *table, *data); \& *lh__delete(LHASH_OF( *table, *data); \& *lh_retrieve(LHASH_OF *table, *data); \& \& void lh__doall(LHASH_OF( *table, LHASH_DOALL_FN_TYPE func); \& void lh__doall_arg(LHASH_OF( *table, LHASH_DOALL_ARG_FN_TYPE func, \& , *arg); \& \& int lh__error(LHASH_OF( *table); \& \& typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); \& typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); \& typedef void (*LHASH_DOALL_FN_TYPE)(const void *); \& typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Cette bibliothèque implémente des tables de hachage dynamiques qui ont une vérification de type. Les entrées de la table de hachage peuvent être des structures arbitraires. En général, elles consistent en des champs de clés et de valeurs. .PP h_\fI_new()\fR crée une nouvelle structure \fB\s-1LHASH_OF\s0( pour stocker des données arbitraires et offre les rétroactions « hachage » et « comparer » pour organiser les entrées de la table. La rétroaction \fBhash\fR prend un pointeur vers une entrée de la table comme argument et renvoie un unsigned long haché comme champ clé. La valeur de hachage est normalement tronquée à une puissance de 2, faites donc attention à ce que la fonction de hachage renvoie des bits de poids faibles mélangés. L'appel \fBcompare\fR prends deux arguments (deux pointeurs vers deux entrées de la table de hachage), et renvoie 0 si leurs clés sont différentes, une valeur différente de 0 sinon. Si la table de hachage contient des valeurs d'un type particulier et que \fBhash\fR et \fBcompare\fR hache/compare ces types, alors les macros \fB\s-1DECLARE_LHASH_HASH_FN\s0\fR et \fB\s-1IMPLEMENT_LHASH_COMP_FN\s0\fR peuvent être utilisées pour créer des emballages de rétroaction d'un prototype requis par lh_\fI_new()\fR. Elles offrent un typage par variable avant d'appeler une rétroaction spécifique à un type écrite par l'auteur de l'application. Ces macros, ainsi que celles utilisées pour les appels « doall », sont définies comme suit : .PP .Vb 7 \& #define DECLARE_LHASH_HASH_FN(name, o_type) \e \& unsigned long name##_LHASH_HASH(const void *); \& #define IMPLEMENT_LHASH_HASH_FN(name, o_type) \e \& unsigned long name##_LHASH_HASH(const void *arg) { \e \& const o_type *a = arg; \e \& return name##_hash(a); } \& #define LHASH_HASH_FN(name) name##_LHASH_HASH \& \& #define DECLARE_LHASH_COMP_FN(name, o_type) \e \& int name##_LHASH_COMP(const void *, const void *); \& #define IMPLEMENT_LHASH_COMP_FN(name, o_type) \e \& int name##_LHASH_COMP(const void *arg1, const void *arg2) { \e \& const o_type *a = arg1; \e \& const o_type *b = arg2; \e \& return name##_cmp(a,b); } \& #define LHASH_COMP_FN(name) name##_LHASH_COMP \& \& #define DECLARE_LHASH_DOALL_FN(name, o_type) \e \& void name##_LHASH_DOALL(void *); \& #define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \e \& void name##_LHASH_DOALL(void *arg) { \e \& o_type *a = arg; \e \& name##_doall(a); } \& #define LHASH_DOALL_FN(name) name##_LHASH_DOALL \& \& #define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \e \& void name##_LHASH_DOALL_ARG(void *, void *); \& #define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \e \& void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \e \& o_type *a = arg1; \e \& a_type *b = arg2; \e \& name##_doall_arg(a, b); } \& #define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG \& \& Un exemple de table de hachage qui stocke (des pointeurs vers) des \& structures du type « STUFF » pourrait être défini comme suit : \& \& /* Calcule la valeur de hachage de « tohash » (implémenté ailleurs) */ \& unsigned long STUFF_hash(const STUFF *tohash); \& /* Ordonne « arg1 » et « arg2 » (implémenté ailleurs) */ \& int stuff_cmp(const STUFF *arg1, const STUFF *arg2); \& /* Crée un emballage de fonction ayant un type sûr pour utilisation interne dans LHASH */ \& static IMPLEMENT_LHASH_HASH_FN(stuff, STUFF); \& static IMPLEMENT_LHASH_COMP_FN(stuff, STUFF); \& /* ... */ \& int main(int argc, char *argv[]) { \& /* Crée une nouvelle table de hachage en utilisant les emballages de hachage/comparaison */ \& LHASH_OF(STUFF) *hashtable = lh_STUFF_new(LHASH_HASH_FN(STUFF_hash), \& LHASH_COMP_FN(STUFF_cmp)); \& /* ... */ \& } .Ve .PP lh_\fI_free()\fR libère la structure \fB\s-1LHASH_OF\s0( de \fBtable\fR. Les entrées de la table de hachage allouées ne seront pas libérées ; pensez à utiliser lh_\fI_doall()\fR pour désallouer les entrées restantes dans la table de hachage (voir ci-dessous). .PP lh_\fI_insert()\fR insère la structure pointée par \fBdata\fR dans \&\fBtable\fR. S'il y a déjà une entrée avec la même clé, l'ancienne valeur est remplacée. Notez que lh_\fI_insert()\fR stocke le pointeur, les données ne sont pas copiées. .PP lh_\fI_delete()\fR supprime une entrée de \fBtable\fR. .PP lh_\fI_retrieve()\fR cherche une entée dans \fBtable\fR. Normalement, \fBdata\fR est une structure avec de(s) champ(s) clé(s) initialisés ; la fonction renverra un pointeur vers une structure entièrement peuplée. .PP lh_\fI_doall()\fR fera, pour toutes les entrées de la table de hachage, appel à \fBfunc\fR avec en paramètre l'objet contenant les données. Pour lh_\fI_doall()\fR et lh_\fI_doall_arg()\fR, le forçage de type du pointeur doit être évité dans les rétroactions (voir \fB\s-1NOTE\s0\fR) —  au lieu de cela il faut utiliser les macros de déclaration ou implémentation pour créer des emballages avec un type vérifié qui typent les variables avant d'appeler les rétroactions spécifiques aux types. Un exemple de cela est illustré ici avec une rétroaction qui est utilisée pour nettoyer les ressources pour les objets contenus dans la table de hachage avant que la table elle\-même soit désallouée. .PP .Vb 9 \& /* Nettoie les resources qui appartiennent à S<« a »> (ceci est implémenté ailleurs) */ \& void STUFF_cleanup_doall(STUFF *a); \& /* implémentation d\*(Aqun prototype compatible d\*(Aqemballage pour S<"STUFF_cleanup »> */ \& IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF) \& /* ... puis plus tard dans le code ... */ \& /* pour lancer S<« STUFF_cleanup »> sur toutes les entrées dans la table de hachage ... */ \& lh_STUFF_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); \& /* Puis le hachage de la table peut être désalloué */ \& lh_STUFF_free(hashtable); .Ve .PP Quand vous faites cela, faites attention si vous supprimez des entrées dans la table de hachage dans vos retours de fonction : la table peut rétrécir, ce qui fera changer de place dans la table de hachage l'objet sur lequel vous travaillez en ce moment, — cela peut causer un saut de certaines entrées pendant l'itération. La deuxième meilleure solution est de régler hash\->down_load=0 avant de commencer (ce qui empêchera la table de hachage de se raccourcir). La meilleure solution est probablement d'éviter de supprimer des objets de la table de hachage dans un retour « doall ». .PP lh_\fI_doall_arg()\fR est identique à lh_\fI_doall()\fR sauf que \fBfunc\fR sera appelé avec \fBarg\fR comme second argument et \fBfunc\fR devrait être du type \fB\s-1LHASH_DOALL_ARG_FN_TYPE\s0\fR (un prototype de rétroaction qui est passé à la table d'entrée comme un argument supplémentaire). Pour \fIlh_doall()\fR, il est possible de choisir de déclarer une rétroaction personnelle avec un prototype correspondant aux types présents et déclarer ou implémenter des macros pour créer des emballages qui forcent le type des variables avant d'appeler les rétroactions spécifiques à un type. Un exemple de cela est expliqué ici (affichage de toutes les entrées de la table de hachage vers un \&\s-1BIO\s0 qui est fourni par l'appelant) : .PP .Vb 8 \& /* Imprime l\*(Aqobjet S<« a »> dans S<« output> S (cela est implémenté ailleurs) */ \& void STUFF_print_doall_arg(const STUFF *a, BIO *output_bio); \& /* implémentation d\*(Aqun prototype compatible d\*(Aqemballage pour S<« STUFF_print »> */ \& static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF, const STUFF, BIO) \& /* ... puis plus tard dans le code ... */ \& /* Imprimer toute la table de hachage dans un BIO particulier */ \& lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO, \& logging_bio); .Ve .PP lh_\fI_error()\fR peut être utilisée pour déterminer si une erreur s'est produite dans la dernière opération. lh_\fI_error()\fR est une macro. .SH "VALEURS DE RETOUR" .IX Header "VALEURS DE RETOUR" lh_\fI_new()\fR renvoie \s-1NULL\s0 en cas d'erreur, sinon elle renvoie un pointeur vers la nouvelle structure \fB\s-1LHASH\s0\fR. .PP Quand une entrée d'une table de hachage est remplacée, lh_\fI_insert()\fR renvoie la valeur remplacée. \s-1NULL\s0 est renvoyée lors d'une opération normale et en cas d'erreur. .PP lh_\fI_delete()\fR renvoie l’entrée qui est supprimée. \s-1NULL\s0 est renvoyée si cette valeur n'existe pas dans la table de hachage. .PP lh_\fI_retrieve()\fR renvoie l'entrée de la table de hachage si elle a été trouvée, \s-1NULL\s0 sinon. .PP lh_\fI_error()\fR renvoie 1 si une erreur s'est produite dans la dernière opération, 0 sinon. .PP lh_\fI_free()\fR, lh_\fI_doall()\fR et lh_\fI_doall_arg()\fR ne renvoient pas de valeurs. .SH "NOTE" .IX Header "NOTE" Les différentes macros et les types retour de fonction \s-1LHASH\s0 existent pour faire en sorte de rendre la vérification de type du code possible sans forcer une conversion de type — un mal qui rend l'application du code plus difficile à vérifier et qui offre une fenêtre vers les corruptions de pile et d'autres bogues difficiles à trouver. Cela, apparemment, viole la convention ANSI-C. .PP Le code \s-1LHASH\s0 voit les entrées de la table comme des données constantes. De ce fait, il représente les objets insérés avec \fIlh_insert()\fR avec un type de pointeur « const void * ». C'est pour cela que les rétroactions comme celles utilisées par \fIlh_doall()\fR et \fIlh_doall_arg()\fR déclarent leurs prototypes avec « const », même pour les paramètres qui renvoient les pointeurs vers les objets de table — par esprit de cohérence, les données fournies par l'utilisateur sont toujours considérées « const » pour le code de \&\s-1LHASH.\s0 Mais, comme les appelants fournissent eux\-mêmes ces pointeurs, ils peuvent choisir si tous les paramètres doivent être traités comme constants. .PP Comme exemple, une table de hachage peut être maintenue par du code qui, pour des raisons d'encapsulation, a uniquement un accès « const » aux données qui sont indexées dans la table de hachage (c'est\-à\-dire, il est renvoyé comme « const » dans une autre partie du code) — dans ce cas les prototypes \s-1LHASH\s0 sont corrects tels quels. Inversement, si l'appelant est responsable de la durée de vie des données en question, alors il souhaitera probablement faire des modifications des objets de la table, envoyés dans \&\fIlh_doall()\fR ou \fIlh_doall_arg()\fR de façon rétroactive (voir l'exemple « STUFF_cleanup » ci-dessus). Si c'est le cas, l'appelant peut soit forcer le type (s'il fournit les rétroactions elles\-mêmes) ou utiliser les macros pour déclarer ou implémenter les emballages des fonctions sans les types « const ». .PP Les appelants qui ont seulement un accès à des données « const » dans leurs tables d'indexation, mais qui déclarent des retours sans types constants (ou forcent la suppression de type), créent de ce fait leurs propres risques ou bogues sans y être encouragés par l'\s-1API.\s0 Dans le même ordre d'idées, lespersonnes vérifiant le code doivent porter une attention toute particulière à une quelconque instance des macros DECLARE/IMPLEMENT_LHASH_DOALL_[\s-1ARG_\s0]_FN qui fournissent un type sans qualificatif « const ». .SH "BOGUES" .IX Header "BOGUES" lh_\fI_insert()\fR renvoie \s-1NULL\s0 pour une réussite ou un échec. .SH "FONCTIONNEMENT INTERNE" .IX Header "FONCTIONNEMENT INTERNE" La description suivante est basée sur la documentation de SSLeay : .PP La bibliothèque \fBlhash\fR implémente une table de hachage décrite dans \&\fICommunications of the \s-1ACM\s0\fR en 1991. Ce qui rend cette table de hachage différente est que lors du remplissage de cette table de hachage, sa taille augmente (ou décroît) grâce à \fIOPENSSL_realloc()\fR. Quand un redimensionnement est terminé, au lieu d'avoir une redistribution sur deux fois plus de « compartiments », un compartiment est découpé. De ce fait lorsqu'une « expansion » est faite, le coût de redistribution de certaines valeurs reste minimal. Les insertions suivantes auront pour effet de faire des redistributions sur un seul « compartiment » mais il n'y aura jamais de coût élevé à cause d'une redistribution sur tous les « compartiments ». .PP L'état d'une table de hachage en particulier est gardé dans une structure \&\fB\s-1LHASH\s0\fR. La décision d'agrandir ou de rapetisser la taille de la table de hachage est faite selon la « charge » de cette table de hachage. La charge est le nombre d'objets divisé par la taille de la table de hachage. Les valeurs par défaut sont les suivantes. Si (hash\->up_load < load) =>, agrandir. Si (hash\->down_load > load) =>, rapetisser. La valeur par défaut de \fBup_load\fR est 1 et la valeur par défaut de \fBdown_load\fR est 2. Ces nombres peuvent être modifiés par l'application en jouant sur la valeur des variables \fBup_load\fR et \fBdown_load\fR. La « charge » est gardée sous une forme qui est multipliée par 256. Donc hash\->up_load=8*256; mettra une charge de 8. .PP Si les performances vous intéressent, le champ à regarder est num_comp_calls. La bibliothèque de hachage garde en mémoire toutes les valeurs de hachage pour chaque objet, donc quand une recherche est terminée, les « hachages » sont comparés, s'il y a une correspondance, alors une comparaison entière est faite, et hash\->num_comp_calls est incrémenté. Si num_comp_calls n'est pas égal à num_delete plus num_retrieve, cela veux dire que les fonctions de hachage génèrent des hachages identiques pour des valeurs différentes. Il est probablement préférable de changer vos fonctions de hachage si c'est le cas car si votre table de hachage a 10 objets dans un « compartiment », il peut être recherché avec 10 comparaisons de \fBunsigned long\fR et des traversées de 10 listes chaînées. Le coût sera bien moins élevé que 10 appels à la fonction de comparaison. .PP \&\fIlh_strhash()\fR est un exemple de fonction de hachage de chaîne. .PP .Vb 1 \& unsigned long lh_strhash(const char *c); .Ve .PP Puisque les routines \fB\s-1LHASH\s0\fR sont normalement passées comme structure, cette routine ne serait normalement pas passée à lh_\fI_new()\fR, au lieu de cela elle devrait être utilisée dans la fonction passée à lh_\fI_new()\fR, .SH "VOIR AUSSI" .IX Header "VOIR AUSSI" \&\fIlh_stats\fR\|(3) .SH "HISTORIQUE" .IX Header "HISTORIQUE" La bibliothèque \fBlhash\fR est disponible dans toutes les versions de SSLeay et d'OpenSSL. \fIlh_error()\fR a été ajoutée dans SSLeay 0.9.1b. .PP Cette page man est dérivée de la documentation de SSLeay .PP Dans OpenSSL 0.9.7, toutes les fonctions de hachage qui étaient passées comme pointeurs de fonction ont été modifiées pour une meilleure sécurité de type, et les types de fonction \s-1LHASH_COMP_FN_TYPE, LHASH_HASH_FN_TYPE, LHASH_DOALL_FN_TYPE\s0 et \s-1LHASH_DOALL_ARG_FN_TYPE\s0 sont devenus disponibles. .PP Dans OpenSSL 1.0.0 l'interface lhash a été remaniée pour une meilleure vérification de types. .SH "TRADUCTION" .IX Header "TRADUCTION" La traduction de cette page de manuel est maintenue par les membres de la liste . Veuillez signaler toute erreur de traduction par un rapport de bogue sur le paquet manpages-fr-extra.