L'ETS (Erlang Term Storage) est une structure de données en mémoire dans Erlang, similaire à une base de données dans d'autres langages. Il permet de stocker et de récupérer des données dans un programme Erlang. **gen\_server** est un modèle d'Erlang utilisé pour créer des serveurs capables de gérer des requêtes clientes concurrentes.
Voici cinq exemples d'utilisation d'ETS dans un **gen\_server** :
Stockage de données
Nous pouvons utilisre ETS pour stocker des données dans la fonction **init** du **gen\_server**:
init([]) ->
TableId = ets:new(etat, [named_table]),
{ok, TableId}.
Ici, nous créons une nouvelle table ETS nommée "etat".
Insertion de données
Pour insérer des données, nous utilisons la fonction **handle\_info** du **gen\_server**:
handle_info({requete, IdRequete, Donnees}, TableId) ->
ets:insert(TableId, {IdRequete, Donnees}),
{noreply, TableId}.
Nous utilisons ici la fonction **ets:insert** pour ajouter des données à notre table ETS.
Requête de données
Afin de récupérer des données, nous pouvons utiliser le code suivant:
handle_info({requete, IdRequete, _}, TableId) ->
case ets:lookup(TableId, IdRequete) of
[] -> {noreply, TableId};
[{IdRequete, Donnees}] ->
{reply, Donnees, TableId}
end.
Ce code utilise la fonction **ets:lookup** pour rechercher des données dans la table ETS.
Mise à jour de données
La mise à jour des données se fait grâce au code suivant:
handle_info({mise_a_jour, IdRequete, NouvellesDonnees}, TableId) ->
ets:insert(TableId, {IdRequete, NouvellesDonnees}),
{noreply, TableId}.
Nous utilisons ici la fonction **ets:insert** pour mettre à jour les données existantes dans la table ETS.
Suppression de données
Pour supprimer des données, nous utilisons le code suivant:
handle_info({suppression, IdRequete}, TableId) ->
ets:delete(TableId, IdRequete),
{noreply, TableId}.
Ce code utilise la fonction **ets:delete** pour retirer des données de la table ETS.
Parcours de la table ETS
Le parcours de tous les enregistrements de la table ETS peut être réalisé avec **ets:foldl**:
handle_info(parcurir, _From, TableId) ->
Resultat = ets:foldl(fun(Enregistrement, Accumulateur) -> [Enregistrement | Accumulateur] end, [], TableId),
{reply, lists:reverse(Resultat), TableId}.
Code exemple
Lors de l'utilisation du module **gen\_server** d'Erlang, il est possible d'utiliser une table ETS pour stocker les données d'état du serveur. Voici un exemple simple illustrant comment utiliser une table ETS dans un **gen\_server**:
-module(demo).
-export([demarrer/0, arreter/0, handle_call/3, handle_cast/2, handle_info/2]).
demarrer() ->
register(demo, spawn(fun boucle/0)).
arreter() ->
demo ! arret.
handle_call(Requete, _From, Etat) ->
ets:insert(Etat#etat.table, {Requete, []}),
{reply, Requete, Etat}.
handle_cast(arret, Etat) ->
{stop, normal, Etat}.
handle_info(_, Etat) ->
{noreply, Etat}.
boucle() ->
boucle(ets:new(stockage, [named_table])).
boucle(Table) ->
receive
arret ->
ok;
Message ->
NouvelleTable = ets:insert(Table, {Message, []}),
boucle(NouvelleTable)
end.
Dans ce code, nous définissons un module nommé demo qui comprend les fonctions **demarrer/0** et **arreter/0** pour démarrer et arrêter le serveur, ainsi que les fonctions **handle\_call/3**, **handle\_cast/2** et **handle\_info/2** pour traiter différents types de messages. La fonction **demarrer** enregistre le processus serveur sous le nom **demo**. Dans **handle\_call**, nous insérons une paire clé-valeur dans la table ETS et répondons avec la clé. La fonction **handle\_cast** traite les messages d'arrêt, tandis que **handle\_info** ignore les autres messages. Enfin, la fonction **boucle** reçoit les messages et agit en conséquence, soit en terminent le processus si le message est d'arrêt, soit en insérant le message dans la table ETS et en continuant à écouter.