Referat von Kim Schröer – Intelligente Dateisysteme WS13/14 Hashing Streuwertfunktionen Referat von Kim Schröer – Intelligente Dateisysteme WS13/14
- Übersicht - Hashingfunktionen Ein einfaches Hashing-Schema Kollisionen Ein einfacher Hashing-Algorithmus Progressiver Overflow Buckets Löschen von Datensätzen
produzieren immer dann eine Adresse, wenn ein Schlüssel gegeben wird Hashfunktionen produzieren immer dann eine Adresse, wenn ein Schlüssel gegeben wird
Ein einfaches Hashing-Schema h(k) = a Bsp: LOWELL Name ASCII (2 B.) Product address LOWELL 76 79 76 x 79 = 6004 004 h(LOWELL) = 4 home address = 4 Funktion h(K) verwandelt einen Schlüssel K (Key) in eine Adresse. In dieser Adresse können nun Datensätze abgelegt und wieder aufgerufen werden. Hier als Bsp die Stadt: LOWELL. Der Schlüssel LOWELL wird durch die Hash-Funktion in die Adresse 4 verwandelt. Vorgehensweise: Die ersten 2 Buchstaben des Namens als 2 Zahlen aus der ASCII-Tabelle notieren, diese multiplizieren, die letzten 3 Ziffern des Ergebnisses ist die Adresse.
Ein einfaches Hashing-Schema
Kollisionen LOWELL Adresse = 4 OLIVER Adresse = 4 Synonyme PROBLEM: Kollision => wenn 2 Schlüssel die gleiche Adresse haben
Kollisionen Optimal: eine perfekte Hashfunktion, bei der alle Kollisionen anhand eines Algorithmus gleichzeitig umgangen werden. Dieses ist jedoch fast unmöglich (bei 4000 DS und 5000 Adressen -> nur 1 aus 10^120000 vermeidet alle gleichzeitig). Also besser: auf eine akzeptable Menge reduzieren.
Kollisionen (Vermeidung) Eine perfekte Hash-Funktion Kollisionen reduzieren: Verteilen der Datensätze Extra Speicher verwenden mehr als einen Datensatz einer einzelnen Adresse zuweisen Hierfür 3 Lösungsvorschläge. Zu 1.: mehr als 2 Anfangsbuchstaben verwenden; JO – häufig, XZ – selten Der Algorithmus muss also noch willkürlicher verteilt werden. Zu 2.: wenige DS auf viele Adressen verteilen. Zu 3.: Bsp.: Wenn ein DS 8 Byte groß ist und wir eine Datei mit 512-Byte-DS kreieren, können wir bis zu 6 DS in jede Adresse packen (Buckets).
Ein einfacher Hash-Algorithmus Schritt 1: LOWELL = 76 79 87 69 76 76 32 32 32 32 32 32 L O W E L L |<- Blanks ->| Den Schlüssel in numerischer Form abbilden (mit ASCII). Es sei denn, es handelt sich eh um eine Zahl, dann diesen Schritt überspringen.
Ein einfacher Hashing-Algorithmus Schritt 2: 76 79 | 87 69 | 76 76 | 32 32 | 32 32 | 32 32 7679 + 8769 + 7676 + 3232 + 3232 + 3232 = 33820 Bsp: Grenze von 19937: 7679 + 8769 -> 16448 -> 16448 mod 19937 -> 16448 16448 + 7676 -> 24124 -> 24124 mod 19937 -> 4187 4187 + 3232 -> 7419 -> 7419 mod 19937 -> 7419 7419 + 3232 -> 10651 -> 10651 mod 19937 -> 10651 10651 + 3232 -> 13883 -> 13883 mod 19937 -> 13883 Die Nummern werden getrennt und zusammengezählt. Wichtig: zum Rechnen Integervariablen verwenden! Problem: Für manche Mikrocomputer wäre diese Anzahl jedoch zu groß -> also mit mod-Operator rechnen.
Ein einfacher Hashing-Algorithmus Schritt 3: Bsp: 100 Adressen (0-99) a = s mod n a = 13883 mod 100 a = 83 s – Summe von Schritt 2 n – Anzahl der Adressen in der Datei a – die Adresse, die erzeugt werden soll
Progressiver Overflow Kollisionsauflösung Beim 4. Versuch hat der DS eine freie Adresse gefunden. Bei einem Key mit der Adresse 99 geht die Suche bei 0 weiter.
Progressiver Overflow
Buckets Adresse mit mehr als einem Datensatz Überlauf von Datensätzen viel seltener
Aufbau eines Buckets
Löschen von Datensätzen Wichtig: Die Lücke, die nach dem Löschen bleibt, darf spätere Suchvorgänge nicht behindern und muss für neue DS zur Verfügung stehen. In Form von # werden sogenannte Tombstones eingefügt, damit die Suche nach einem Schlüssel nicht bei der Lücke endet.
Löschen von Datensätzen Irgendwann sehr viele Tombstones Idee: Algorithmus überprüft, ob die DS, die nach einem Tombstone kommen, nicht doch in ihre Home-Addresse passen. Auch die Suchlänge verkürzt sich
Andere Techniken zur Vermeidung von Kollisionen Double Hashing Suche wird deutlich schneller bei Kollision: eine 2. Hashfunktion, die eine Zahl erzeugt, die teilerfremd zu der home-Adresse ist und das solange, bis eine freie Adresse gefunden wird.
Noch Fragen?!
Vielen Dank für die Aufmerksamkeit!
Bsp: einfacher Hash-Algorithmus int Hash (char key[12], int maxAddress) { int sum = 0; for (int j = 0; j < 12; j += 2) sum = (sum * 100 * key[j] * key[j+1]) % 19937; return sum % maxAddress; } Die Funktion hash verwendet die folding and prime number division, um eine hash Adresse für einen 12 char string.