Act-21 : un nouveau type de SGBD parallèle
W.K. Hidouci,
Institut National d'Informatique,
Alger, Octobre 2000.
Sommaire
Les Acteurs de bases de données (DB-Act)
Les Acteurs Collection (C-Act)
Le modèle de données relationnel a eu un grand succès dans le domaine des bases de données orientées gestion. Les données manipulées dans ce type d'application se prêtaient bien à la simplicité du modèle relationnel. De plus le formalisme mathématique de ce dernier facilite la mise en œuvre efficace de langages de requête déclaratifs de haut niveau.
D'autres types d'application manipulant des données plus complexes, s'intègrent moins bien avec les SGBD relationnels. Par contre le modèle de données objet, ayant une sémantique beaucoup plus riche que le relationnel semble être la bonne voie.
Notre idée, dans le projet de recherche Act-21, consiste à intégrer les techniques de la programmation par acteurs, les structures de données distribuées (SDDS) et les SGBD objets. Le résultat serait alors un nouveau type de SGBD parallèle pour multi-ordinateur (exemple : réseau de PC sous Linux) où le modèle de données combine les objets usuels (approche par classes) et les acteurs. Son système de stockage utilisera des structures de données distribuées et scalables ce qui facilitera son extension par adjonction de nouveau nœuds au réseau.
Le processus de modélisation devra alors être enrichi par des connaissances concernant les éventuelles interactions entre les différents types. Cette information sera cruciale pour la résolution des requêtes par un groupe d'acteurs coopérant et autonomes.
Dans le modèle de programmation par acteur, une application est un ensemble d'entités autonomes (les acteurs) qui communiquent entre elles de manière asynchrone afin d'atteindre un but commun.
Appliquer cette vision à la modélisation de données (conception de schémas de BD) paraît assez naturelle pour prendre en compte la dynamique des objets modélisés et tirer avantage des nouvelles architectures de machines parallèles.
Dans cette optique, une base de données serait alors composée d'un ensemble d'acteurs (objets actifs) détenant chacun une partie de la connaissance et coopérant à travers des échanges de messages pour répondre aux requêtes utilisateurs ou aux programmes d'applications.
Les Acteurs de base de données (DB-Act) :
Pour nous un "acteur de base de données" (DB-Act) est un objet actif défini par un comportement (behavior), ce dernier est formé par un état (des variables locales : les accointances) et un script (un ensemble de méthodes). L'identité de chaque acteur est unique (oid), de plus un nom symbolique peut être attribué à chaque acteur. La communication entre acteurs est généralement asynchrone et les messages sont traités suivant l'ordre d'arrivée, un par un.
Au niveau externe, on peut distinguer trois types de DB-Act:
Pour créer un Acteur on utilise la primitive ‘New-Act ( comp , type , nom )’ qui retourne l’oid du nouvel acteur créé.
Les paramètres de la primitive représentent le comportement du nouvel acteur (comp), son type (T-Act, C-Act ou R-Act) et éventuellement un nom unique stocké dans le catalogue des acteurs. On peut obtenir l’oid d’un acteur si on connaît son nom par la primitive ‘Get-Oid( nom )’.
Le type permet d’utiliser des comportements prédéfinis en plus de ceux spécifiés dans ‘comp’. L’acteur qui a exécuté cette primitive devient le père du nouvel acteur créé et est donc sa délégation.
Quand un acteur reçoit un message, il vérifie si ce dernier fait partie de son script, auquel cas il l’exécute, sinon il l’envoie vers sa délégation (par défaut l’acteur père). La relation de délégation définie un arbre d’héritage entre acteurs où la racine est acteur prédéfini décrivant le comportement commun de tous les autres acteurs.
Un acteur peut changer sa délégation à l’aide de la primitive ‘Ch-Deleg( A )’, de même qu’il peut se détacher de l’arbre d’héritage en exécutant ‘Ch-Deleg( NULL )’.
Messages:
Il existe deux types de messages asynchrones:
Dans tous cas, le message peut être soit le nom d'une méthode avec ses paramètres soit une suite d'éléments entre parenthèses.
Si le message est de la forme ‘var = send message to a’ il devient alors synchrone, c’est à dire que l’exécution est suspendue jusqu’à ce que le résultat soit retourné vers ‘var’ (qui joue alors le rôle d’une continuation bloquante) .
A l’intérieur de la partie script d’un acteur, on peut enlever l’expression ‘send to’ si le message est destiné à l’acteur lui même.
Les acteurs de typage (T-Act):
Il existe des types primitifs (entiers, réels, chaînes, …) et des types construits qui sont l'équivalent des classes dans le modèle objet standard. A chaque type construit correspond un acteur de typage (T-Act) chargé de gérer son extension (les instances du types) et participer aux résolutions des requêtes.
Un T-Act connaît tous les autres T-Acts de la base. Lorsqu'il reçoit une requête (un message), un T-Act peut l'exécuter ou la déléguer à un autre T-Act (cas de l'héritage) ou entrer en coopération avec d'autres acteurs pour y répondre (cas d'une requête complexe).
Parmi les méthodes prédéfinies des T-Act on a:
- (oid,ch1=val,ch2=val…) Insère une instance dans l’extension du type.
- delete(oid) Supprime une instance.
- set_field(oid,champ,val) Modifie la valeur du champ spécifiée.
- get_field(oid,champ) :c Retourne vers la continuation c la valeur du champ spécifié pour
l’oid spécifié.
- select(condition):c Retourne vers la continuation c un ensemble d'instances vérifiant
la condition spécifiée. L’ensemble transmis à l’acteur c est terminé
par le message ‘end( oid du T-Act )’.
- add_field(champ,type) Permet d'ajouter un champ à la définition du type géré par ce T-Act.
- del_field(champ) Supprimer un champ existant.
- add_grp(nom_gr) Permet au T-Act de devenir membre du groupe spécifié.
- del-grp(nom_gr) Pour quitter le groupe spécifié.
- add_deleg(Act) Ajouter une délégation
- del_deleg(Act) Supprimer une délégation
- add-subtype(nom,comp) :c Permet de créer un nouveau sous-type de nom ‘nom’ et de
comportement initial ‘comp’. Le nouvel oid est retourné vers c.
Le stockage des instances d'un type se fait à l'aide de la représentation verticale. Ceci facilitera énormément la gestion dynamique du schéma de la base, la migration d'objet et les notions d'acquisition/perte de type en général.
Par exemple pour définir le type ‘Employe’, on commence par spécifier le comportement :
Data :
Int nss ;
Float salaire ;
String departement ;
DB-Act chef =NULL;
Script :
NomDuChef( Int oid ) : Continuation A
{
string s ;
if (chef(oid) != NULL) {
s = get_field( ‘nom’ , chef(oid) )
send s to A ;
}
EmpDuDepartement( string dep ) : Continuation C
{
select(‘departement = #dep’) : C // #dep est le contenu du paramètre
}
} ;
Si un T-Act gérant le type ‘Personne’ existe déjà, on pourra alors définir ‘Employe’ comme sous-type de ‘Personne’ :
Pers = Get-Oid( Personne ) ;
Send add-subtype(‘Employe’,TypeEmp) to Pers ;
La méthode ‘add-subtype(…)’ utilise la primitive ‘New-Act’ pour créer un T-Act dont le nom et le comportement sont spécifiés dans les paramètres de la méthodes et fixe ainsi le lien d’héritage entre le T-Act receveur et le nouveau T-Act.
La partie ‘Data’ du comportement d’un acteur est considérée, dans le cas d’un T-Act, comme étant une déclaration de fichiers LH*, un par champ (représentation verticale). Dans l’exemple ci-dessus, le T-Act ‘Emp’ gère 4 fichiers LH* : nss , salaire, departement et chef, chacun ayant une structure (clé,val) où la clé est l’oid des instances stockées et val la valeur du champ considéré pour cet oid.
Les acteurs collection:
Une collection est un acteur conteneur (C-Act) renfermant un ensemble d'éléments. Ces derniers peuvent être actifs (des acteurs) ou passifs (types simples : entier, chaîne…)
Parmi les méthodes prédéfinies d'un C-Act, on a:
- card( ) : c envoie vers c le nombre d’éléments dans la collection.
- (elt) insère la valeur reçue dans la collection.
- end( oid ) ne fait rien sauf si elle est redéfinie par l’acteur père.
- access( i ) : c envoie vers c l’élément qui se trouve à la ième position.
- extract(elt) :c supprime l'élément dans la collection et l’envoie vers c.
- map(message) envoie le message (de manière asynchrone) à chaque
élément de la collection. Si les éléments ne sont pas des
acteurs, le message est ignoré.
- unique( ) supprime tous les doubles de la collection.
Exemple :
soit la définition du comportement suivant
Def_Behavior C1 {
Script :
End( int x ) { Affich( ) ; } // redéfinition de la méthode ‘end’
Affich( )
{
int x ; string n ;
Pers = Get-Oid(‘Personne’) ; // récupérer l’oid du T-Act Personne
i = 1 ;
while (i <= card( ) )
{
x = access( i ) ; // pour chaque elt de la collection :
n = send get-field(x,’nom’) to Pers ; // récupérer son nom (en synchrone)
send n to console ; // et l’afficher.
i = i + 1 ;
}
}
}
pour créer une collection ayant ce comportement, on écrira :
E = New-Act( C1 , C-Act ) ; // le 3e paramètre de New-Act est facultatif
ensuite cette collection E pourra être utilisée comme résultat d’une sélection :
P = Get-Oid( ‘Personne’ ) ;
send select(‘age > 20’) : E to P ;
Les acteurs de requêtes (R-Act):
Une requête est un acteur (R-Act) défini à l'extérieur par l'utilisateur (ou par un programme d'application) ou à l'intérieur par le module d’exécution des requêtes. Son rôle est de communiquer avec les autres acteurs du système pour trouver les informations cherchées dans la BD.
En fait un R-Act est un acteur de programmation utilisant un langage impératif où le parallélisme est implicite.
Architecture du système :
Les premiers modules formant l’ossature du SGBD sont :
C’est le sous-système de stockage qui gère les données de manière distribués. Il offre aux couches supérieurs (notamment le module CAT) les primitives suivantes :
Ce module a pour rôle de cataloguer toutes les informations utiles pour le système. Il offre aux autres modules (EXEC et REQ) les primitives suivantes :
C’est le langage avec lequel les méthodes sont écrites lors de la définition des comportements. Ce langage est de type impératif (contenant les variables, les affectations, les conditionnelles, …). Quand un acteur exécute une de ses méthodes il fait appel à ce module en donnant comme paramètres son oid, la méthode, les paramètres, …
Ce module offre aux utilisateur un langage de requête de haut niveau (type SQL) et prend en charge son exécution en générant les différents R-Acts nécessaires de manière transparente.