On souhaite écrire une table de hachage d'un genre un peu particulier.
Premièrement, il sera possible uniquement d'ajouter des élements
dans la table de hachage, pas d'en supprimer (au moins au début).
De plus, à chaque fois qu'un élement sera ajouté, on incrémentera un compteur
appelé compteur de génération, l'élement sera stocké avec sa valeur de génération.
De plus, une opération appeler
snapshot permet à partir de la table
HashGen d'obtenir une
Map contenant toutes les valeurs
insérées avant l'appel à
snapshot et qui ne contiendra pas les
valeurs ajoutées après l'appel à
snapshot.
Bien sûr, il est facile d'implanter
snapshot en copiant toutes
les valeurs dans une nouvelle
Map et de renvoyer celle-ci
mais ce n'est pas très efficace. L'idée en plutôt que la
Map
renvoyé stocke juste le numéro de version au moment où on appel
snapshot
et que celle-ci montre parmis les valeurs
HashGen uniquement
celles ayant une génération de valeur inférieur. Comme cela, les valeurs
ne sont pas stockées dans plusieurs endroits mais uniquement dans
HashGen.
Enfin, pour simplifier le problème même si c'est mal, la table de hachage
ne se redimensionnera pas.
public class HashGen {
private final HashEntry[] entries = new HashEntry[32];
static class HashEntry {
final Object key;
Object value;
final Entry next;
HashEntry(Object key, Object value, Entry next) {
this.key = key;
this.value = value;
this.next = next;
}
}
public Object get(Object key) {
Objects.requireNonNull(key);
int index = key.hashCode() & 0b11111;
HashEntry head = entries[index];
for(Entry e = head; e != null; e = e.next) {
if (e.key.equals(key)) {
return e.value;
}
}
return null;
}
public void put(Object key, Object value) {
Objects.requireNonNull(key);
Objects.requireNonNull(value);
int index = key.hashCode() & 0b11111;
HashEntry head = entries[index];
for(Entry e = head; e != null; e = e.next) {
if (e.key.equals(key)) {
e.value = value;
return;
}
}
entries[index] = new HashEntry(key, value, head);
}
}