120 likes | 226 Views
Gestion de Fichiers. Hachage. Motivation. La recherche séquentielle peut être faite en temps d’accès d’ordre O(N), ce qui veut dire que le nombre de “seeks” augmente au même taux que la taille du fichier.
E N D
Gestion de Fichiers Hachage
Motivation • La recherche séquentielle peut être faite en temps d’accès d’ordre O(N), ce qui veut dire que le nombre de “seeks” augmente au même taux que la taille du fichier. • Les arbres B diminuent ce taux puisqu’ils permettent un temps d’accès d’ordre O(LogkN) ou k est une mesure de la taille d’une feuille (i.e., le nombre d’enregistrements qui peuvent être sauvegardé dans une feuille). Nous verrons les arbres B plutard. • Ce que l’on voudrait, cependant, est un temps d’accès d’ordre O(1) ce qui veut dire que quelque soit la taille du fichier le temps d’accès à un enregistrement est toujours un petit nombre de “seeks”. • Hachage statique est une technique permettant d’atteindre une telle performance si la taille du fichier ne varie pas.
Définition • Une fonction de hachage (“hash function”) est une fonction (mathématique) h qui peut transformer une clé K en une adresse h(K). • Le résultat h(K) du hachage est utilisé pour stockerl’enregistrement corespondant à la clé K. • Le hachage ressemble aux indexes associant une clé avec une adresse relative d’enregistrement. • Hachage versus construction d’indexes: • Avec le hachage, il n’y a pas de connection évidente entre la clé et l’adresse (“randomizing”). • Avec le hachage, deux clés différentes peuvent être transformées en la même adresse (“collision”).
Exemple de fonction de hachage • On veut stocker 75 enreg.s dans un fichier. la clé est le nom de famille. Un espace pour 1000 enreg.s est reservé. • Soit pl(K) := 1ère lettre de K, dl(K) := 2ème lettre de K. • Soit tdl(N) := les trois derniers chiffres de N. • h(K) = tdl(ASCII(pl(K)) * ASCII(dl(K))). • Le résultat h(K) appliquée à une portion du fichier: Nom ASCII(pl(K)) ASCII(dl(K)) Produit Adresse domiciliaire BALL 66 65 66*65 =4290 290 LOWEL 76 79 76*79=6004 004 TREE 84 82 84*82=6888 888 • Les adresses qui apparaissent avoir été trouvés au hasard.
Collisions • Lorsque deux clés différentes produisent la même adresse, il y a une collision. Les clés impliquées dans cette collision s’appellent des synonymes. • Exemple de collision: h(OLIVER) = h(LOWELL) = 004. • Néanmoins, il est très difficile de trouver une fonction de hachage qui évite les collisions (« perfect haching»). Permettre les collision et trouver des moyens de les résoudre est plus simple à faire. • Solutions Possible: • Espacer les enregistrements • Utilisation de mémoire supplémentaire • Placement de plus d’un enregistrement à une adresse.
Collisions: solutions possibles • Espacer les enregistrements: éviter des regroupement d’enregistrements autour d’un nombre réduit d’adresse en cherchant des fonction de hachage qui distribue les enregistrements de la manière la hasardeuse possible. Notre h(K) précédent est mauvais à cet égard car il y a des combinaisons de lettres plus fréquentes que d’autres. • Utiliser de la mémoire supplémentaire: Ceci est possible si l’espace réservé au fichier excède de loin l’espace occupé par les enregistrements. • Placer plus d’un enregistrement à une adresse: réserver suffisament d’espace physique pour enregistrer les plus d’enreg.s logiques possible. Une adresse stockant plusieurs enreg.s est appelée compartiment («bucket»).
Un algorithme simple de hachage • Etape 1:représentation numérique de la clé. Si la clé est déjà en forme numérique, passez à l’étape 2, sinon utilisez toutes les lettres de la clé et transformez les en code ASCII. Par exemple LOWELL 76 79 87 69 76 76 32 32 32 32 32 32 • Ici, nous supposons que le champ-clé a une longeur fixe de 10 octets. “LOWELL” occupant les 6 premiers octets, le reste est un espace vide (“blanks”).
Un algorithme simple de hachage (suite) • Etape 2:plier et ajouter (“fold and add”) . Découpez le résultat de l’étape 1 en pièces de deux nombre ASCII chacune et additionnez ces pièces. P.ex.LOWELL 76 79 | 87 69 | 76 76 | 32 32 | 32 32 | 32 32 • La somme sur l’exemple ci-haut donne:7679+8769+7676+3232+322+32 32 = 33820 • Si p.ex. MaxInt=32767 (15bits), on a un dépassement de capacité ! Un moyen de traiter ce problème est: s’assurer que chaque résultat intermédiaire est plus petit que MaxInt. Une méthode pour ce faire est(((((((7679+8769)mod N)+7676)mod N)+3232) mod N) …+3232) • Le choix de N doit être judicieux et souvent c’est un nombre premier.
Un algorithme simple de hachage (suite) • Etape 3:diviser par la taille du fichier et utiliser le reste comme adresse. L’intuition derrière cette étape est de réduire la taille du nombre produit à l’étape 2 afin que ce nombre n’excède pas la taille du fichier. • Méthode: a = s mod n; a = adresse à produire, s = somme produit à l’étape 2, n = taille du fichier. Notez que a sera un nombre entre 0 et n-1.
Un algorithme simple de hachage (suite) • Ceci est un exemple de code C++ pour l’algorithme simple de hachage utilisant un choix de N=19937 dans l’étape 2. • Int Hash (char key[12], int numUsedAddresses, int maxAddress) { int sum = 0; for (int = 0; j < 12; j += 2) sum = (sum * numUsedAddresses * key[j] * key[j+1]) % 19937; return sum % maxAddress; }
Fonctions hachage et distribution d’enregistrements • Les enregistrements peuvent être distribués sur toutes les adresses de manières différentes: Il peut y avoir (a) aucun synonymes (distribution uniforme); (b) que des synonymes (pire cas); (c) quelques synonymes (cela arrive avec des distributions au hasard – “random distribution”). • Les distributions uniformes pures sont difficiles à obtenir et ne valent pas la peine d’être cherchées. • Les distributions au hasard peut être facilement derivées mais elles ne sont pas parfaites car elles peuvent générer un nombre important de synonymes. • On veut des méthodes de hachage meilleures que cela.
D’autres méthodes de hachage • Bien qu’il n’existe pas de fonction de hachage qui garantisse des distributions meileures que les distributions au hasard dans tous les cas, si on considère le clés qui vont être “hachées”, certaines améliorations sont possibles. • Voici quelques méthodes qui sont potentiellement meilleures que les méthodes au hasard: • Examiner les clés pour trouver un patron • “Plier” certaines parties de la clé • Diviser la clé par un nombre (p.ex. premier) • Elever la clé au carré et prendre le milieu (“mid-square method”): p.ex. K=453 carré=205209 milieu = 52 • “Radix transformation”: 453 382 base 11 382 mod 99.