• Aucun résultat trouvé

L’exécution de requêtes est résumée dans l’algorithme 5 ; on considère qu’il s’agit de la toute première exécution, qui comporte son initialisation. Un exemple complet est également présenté, étape par étape, en Fig. 28.

C’est à cette étape que la validité de la requête est vérifiée (qu’elle est bien applicable sur le flux), et que l’on effectue la matérialisation (si be- soin) ; toutes les modifications effectuées à ce moment sont enregistrées pour être appliquées lors de l’exécution de la requête sur les échantillons suivants. Ainsi, si la requête est valide, son application future prendra moins de temps (les vérifications initiales ne seront plus nécessaires). Pour que l’algorithme fonctionne, il faut naturellement fournir la compression PatBin de la requête, mais également un échantillon PatBin provenant du flux de données. C’est le pattern qui est le plus important ; le binding peut éventuellement être factice, et géré plus tard (on peut séparer la gestion de la première exécution de la requête des exécutions suivantes). Les flux (séries de bindings) sont stockés en mémoire principale afin d’optimiser le traitement des requêtes ; il est pos- sible de faire persister les flux par sérialisation si un traitement ultérieur est nécessaire.

Il faut dans un premier temps initialiser une structure de résultat, qui permettra de renvoyer les variables attendues, mais aussi d’enregistrer l’évo- lution des agrégats, qui doivent se faire sur plusieurs échantillons. Ensuite vient l’étape mentionnée en section 6.2, pour comparer les patterns respec- tifs de la requête et du flux. En effectuant l’intersection des encodages, on obtient Pi, soit le pattern commun au flux et à la requête (Fig. 28 a). Puis,

en soustrayant Pi au pattern de la requête, on obtient Pm : ce qui reste à

triplets) sont présents dans la requête, mais pas dans le flux, il y a un be- soin de matérialisation. On peut résoudre cette étape en requêtant une base de connaissance statique liée au projet, qui contiendra les informations man- quantes (Fig. 28 c), et les ajouter au pattern, et à chaque binding qui arrivera du flux (le pattern donnera la position des objets issus de la base statique dans le binding). Ensuite vient le traitement du cas inverse : si la taille du pattern de flux est supérieure à celle du pattern de requête, c’est qu’il y a certains éléments du flux qui ne sont pas nécessaire à la requête ; on peut donc les retirer, et normaliser les deux patterns pour qu’ils soient identiques (Fig. 28 d). Notons qu’à chaque étape, le retrait (respectivement l’ajout) d’un élément d’un pattern entraîne le retrait d’un élément du binding à la position correspondante (les séparateurs du pattern sont des :, ceux du binding des ;). Lors de la comparaison entre les éléments des patterns, il est possible d’utiliser les bénéfices de l’encodage de LiteMat afin de réécrire la requête. Cette étape se déroule lors du calcul de l’intersection : pour chaque élément encodé du flux étant strictement supérieur à la valeur à la position correspon- dante dans la requête, il est possible que l’élément en question corresponde à une sous-propriété de l’élément de la requête. Cette vérification peut s’ef- fectuer en se basant sur les spécificités de LiteMat (nombre de bits pour l’encodage) : si une sous-propriété de l’identifiant de la requête correspond à l’identifiant du flux, cet identifiant est adopté en remplacement dans la requête. La réécriture ne s’effectue qu’une fois pour toute, à l’initialisation, et elle n’est valide que pour l’application de la requête sur ce flux spécifique (elle devra potentiellement être réécrite d’une autre manière pour d’autres flux).

A cette étape, pour que la requête puisse être exécutée, les patterns de la requête et du flux doivent être identiques ; les étapes précédentes ne sont pas toujours nécessaires, mais elles s’assurent que les encodages correspondent au maximum. Il faut également s’assurer que le binding de la requête est inclus dans celui du flux, c’est-à-dire que les littéraux spécifiés dans la requête sont présents dans le binding du flux, et qu’ils correspondent. Si ces deux conditions ne sont pas remplies, alors soit le graphe du flux est différent de celui de la requête (il n’est donc pas possible de l’appliquer), soit les littéraux spécifiés ne sont pas identiques, et dans ce cas les éléments fournis ne correspondent pas. L’exécution renvoie alors null, pour préciser le problème. Si ces conditions sont vérifiées, le binding du flux est comparé à celui de la requête, d’où on extrait les filtres (sur les variables et sur les agrégats). Si ces filtres sont valides, enfin, on peut extraire les variables du flux : il suffit

Algorithm 5 Exécution complète de requête

1: procedure QueryExecution(Pq, Bq, Ps, Bs)

2: result = initialize(Bq)

3: Pi = Pq∩ Ps

4: Pm = Pq− Pi

5: if Pm is not empty then

6: Ps, Bs = materialize(Ps, Bs, Pm) 7: end if 8: if Ps > Pq then 9: normalize(Ps, Pq) 10: end if 11: if Ps == Pq and Bq⊂ Bs then 12: if verifyFilters(Bq, Bs) then 13: update(result) 14: return result 15: end if 16: end if 17: return null 18: end procedure

Extrait de flux compressé

31:(5:8):40:(44:(49:53):66:(12:74):67:(12:74))

;"Postal Bank";"Bank#041"; ; ;450;"US$"; ;"Dupond";"CCP XXX"; ;"Durand";"CCP YYY"

Requête compressée (nécessitant matérialisation)

31:(8:23):40:(44:(49:53))

;"Bank#041";"Paris"; ; ;?var1;"US$"

(a) Calcul de Ps∩ Pq = Pi 31:(8):40:(44:(49:53))

(b) Calcul de Pq− Pi = Pm (forme statique à matérialiser dans le flux) 31:(23)

;"Paris"

(c) Nouveau Ps, Bs

31:(5:8:23):40:(44:(49:53):66:(12:74):67:(12:74))

;"Postal Bank";"Bank#041";"Paris"; ; ;450;"US$"; ;"Dupond";"CCP XXX"; ;"Durand";"CCP YYY"

(d) Normalisation (Ps = Pq, Bq ⊂ Bs?) 31:(8:23):40:(44:(49:53))

;"Bank#041";"Paris"; ; ;450;"US$"

Figure 28 – Vérification de validité de requête

de récupérer les bindings correspondants à la position des variables (puisqu’à cette étape, les bindings ont la même longueur). Les valeurs correspondant aux agrégats sont récupérées de la même manière, mais stockées différemment et non retournées, car il faudra plusieurs échantillons avant de les calculer. Ce résultat est ensuite renvoyé à l’utilisateur.

Lorsque la première exécution de requête est remplie avec succès, cer- taines vérifications ne sont plus nécessaires : les trois premières conditions de l’algorithme (lignes 5, 8, 11) seront toujours valides tant que le pattern du flux ne varie pas, et on peut traiter le PatBin du flux toujours de la même manière après la première étape (matérialisation/normalisation). Le stockage des modifications à effectuer pour la requête exécutée permet donc de gagner du temps. En revanche, il est toujours nécessaire de vérifier les filtres appli- qués au binding (ligne 12), car les littéraux vont varier d’un échantillon à l’autre. Le résultat renvoyé par la procédure d’exécution sera mis à jour à

chaque fois, avec des variables retournées différentes, et des agrégats dont les valeurs vont s’accumuler. L’utilisateur peut choisir de calculer le résultat des agrégats lorsque le nombre de valeurs rassemblées sera satisfaisant.

Dans le cas d’un besoin de groupement (GROUP BY de SPARQL, va- riables et agrégats à retourner en même temps), la structure qui stocke les valeurs des agrégats au fur et à mesure va, en plus de l’opération finale à exé- cuter (SUM, AVG, MAX, ...), enregistrer les variables de groupement liées à l’agrégat. Il y aura donc une liste de structures pour chaque série de valeurs de variables différentes ; lorsque l’utilisateur demande le résultat, l’intégra- lité des variables enregistrées sont renvoyées, et les groupements qui leur sont associées sont calculés.