Le but de ce examen est d'implanter une base de données (enfin une liste d’éléments) en mémoire ayant des index (listes d'indices) permettant d'accélérer la recherche.
Un
Repository est un objet qui contient une liste d'éléments indexés (numérotés) non nuls.
La classe
Repository est typée par le type des éléments que les instances de la classe contiennent.
La méthode
add permet d'ajouter des éléments dans le
Repository.
Il n'est pas possible de supprimer des éléments (sauf en reconstruisant un nouveau
Repository).
Un
Selector est une liste d'entiers triés (des indices) construite à partir d'une fonction indiquant
si un élément est présent ou non dans le
Selector.
La méthode
addSelector permet d'ajouter au
Repository un
Selector créé à partir
d'une fonction de test qui renvoie un booléen pour un élément passé en paramètre.
Si cette fonction de test renvoie vrai pour un élément, alors la position de cet élément
(dans la liste des éléments du
Repository) est stockée dans la liste des entiers de ce
Selector
Par exemple avec le code suivant,
var repository = new Repository<String>();
repository.add("foo");
repository.add("baz");
repository.add("booz");
var selector = repository.addSelector(s -> s.contains("oo"));
System.out.println(selector);
le
Selector affiche [0, 2] car les éléments à l'indice 0 ("foo") et à l'indice 2 ("booz") contiennent "oo".
L'indice 1 ne fait pas partie du
Selector car "baz" (l'élément à l'indice 1) ne contient pas "oo".
Enfin, la méthode
createQuery permet de créer un objet
Query associé au repository et sur lequel on peut demander
d'appliquer plusieurs
Selector (avec la méthode
select) puis de ressortir le
Stream
des éléments vérifiant les différents
Selector grâce à la méthode
toStream.
Par exemple, avec le code suivant,
var repository = new Repository<String>();
repository.add("foo");
repository.add("baz");
repository.add("booz");
var selector1 = repository.addSelector(s -> s.contains("oo"));
var selector2 = repository.addSelector(s -> charAt(0) == 'f');
var query = repository.createQuery();
var list = query.select(selector1).select(selector2).toStream().collect(toList());
la liste
list contient uniquement l'élément "foo", car c'est le seul élément qui vérifie les deux
Selector
(contenir "oo" et avoir 'f' comme première lettre).
En terme d'implantation, on pré-suppose que l'on ajoute rarement des éléments au
Repository mais que par contre,
on effectue fréquemment des requêtes de sélection. C'est pour cela que chaque
Selector maintient un index
en mémoire plutôt que de ré-appliquer les fonctions de test de chaque
Selector pour chaque requête.
Certains tests unitaires correspondant à l'implantation sont ici:
RepositoryTest.java.