IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

57.2. Extensibilité

L'interface GIN a un haut niveau d'abstraction. De ce fait, la personne qui code la méthode d'accès n'a besoin d'implanter que les sémantiques du type de données accédé. La couche GIN prend en charge la gestion de la concurrence, des traces et des recherches dans la structure de l'arbre.

Pour obtenir une méthode d'accès GIN fonctionnelle, il suffit d'implanter quatre (ou cinq) méthodes utilisateur. Celles-ci définissent le comportement des clés dans l'arbre et les relations entre clés, valeurs indexées et requêtes indexables. En résumé, GIN combine extensibilité, généralisation, ré-utilisation du code à une interface claire.

Les quatre méthodes qu'une classe d'opérateur GIN doit fournir sont :

int compare(Datum a, Datum b)

Compare deux clés (et non deux valeurs indexées !) et renvoie un entier négatif, zéro ou un entier positif, qui indique si la première clé est inférieure, égale à ou supérieure à la seconde. Null keys are never passed to this function.

Datum *extractValue(Datum inputValue, int32 *nkeys, bool **nullFlags)

Retourne un tableau de clés alloué par palloc en fonction d'un item à indexer. Le nombre de clés retournées doit être stocké dans *nkeys. Si une des clés peut être nulle, allouez aussi par palloc un tableau de *nkeys champs de type bool, stockez son adresse dans *nullFlags, et positionnez les drapeaux null où ils doivent l'être. *nullFlags peut être laissé à NULL (sa valeur initiale) si toutes les clés sont non-nulles. La valeur retournée peut être NULL si l'élément ne contient aucune clé.

Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data, bool **nullFlags, int32 *searchMode)

Renvoie un tableau de clés en fonction de la valeur à requêter ; c'est-à-dire que query est la valeur du côté droit d'un opérateur indexable dont le côté gauche est la colonne indexée. n est le numéro de stratégie de l'opérateur dans la classe d'opérateur (voir Section 35.14.2, « Stratégies des méthode d'indexation »). Souvent, extractQuery doit consulter n pour déterminer le type de données de query et la méthode à utiliser pour extraire les valeurs des clés. Le nombre de clés renvoyées doit être stocké dans *nkeys. Si une des clés peut être nulle, allouez aussi par palloc un tableau de *nkeys champs de type bool, stockez son address à *nullFlags, et positionnez les drapeaux NULL où_ils doivent l'être. *nullFlags peut être laissé à NULL (sa valeur initiale) si toutes les clés sont non-nulles. La valeur de retour peut être NULL si query ne contient aucune clé.

searchMode est un argument de sortie qui permet à extractQuery de spécifier des détails sur comment la recherche sera effectuée. Si *searchMode est positionné à GIN_SEARCH_MODE_DEFAULT (qui est la valeur à laquelle il est initialisé avant l'appel), seuls les items qui correspondent à au moins une des clés retournées sont considérées comme des candidats à correspondance. Si *searchMode est positionné à GIN_SEARCH_MODE_INCLUDE_EMPTY, alors en plus des items qui contiennent au moins une clé correspondant, les items qui ne contiennent aucune clé sont aussi considérées comme des candidats à correspondance. (Ce mode est utile pour implémenter un opérateur «est sous-ensemble de», par exemple.) Si *searchMode est positionné à GIN_SEARCH_MODE_ALL, alors tous les items non nuls de l'index sont candidats à correspondance, qu'ils aient une clé qui corresponde à celles retournées ou non. (Ce mode est beaucoup plus lent que les deux autres, mais il peut être nécessaire pour implémenter des cas exceptionnels correctement. Un opérateur qui a besoin de ce mode dans la plupart des cas n'est probablement pas un bon candidat pour une classe d'opérateur GIN.) Les symboles à utiliser pour positionner ce mode sont définis dans access/gin.h.

pmatch est un paramètre de sortie à utiliser quand une correspondance partielle est permise. Pour l'utiliser, extractQuery doit allouer un tableau de booléens *nkeys et stocker son adresse dans *pmatch. Chaque élément du tableau devrait être positionné à TRUE si la clé correspondante a besoin d'une correspondance partielle, FALSE sinon. Si *pmatch est positionné à NULL alors GIN suppose qu'une mise en correspondance partielle n'est pas nécessaire. La variable est initialisée à NULL avant l'appel, et peut donc être simplement ignorée par les classes d'opérateurs qui ne supportent pas les correspondances partielles.

extra_data est un paramètre de sortie qui autorise extractQuery à passer des données supplémentaires aux méthodes consistent et comparePartial. Pour l'utiliser, extractQuery doit allouer un tableau de pointeurs *nkeys et stocker son adresse à *extra_data, puis stocker ce qu'il souhaite dans les pointeurs individuels. La variable est initialisée à NULL avant l'appel, afin que ce paramètre soit simplement ignoré par une classe d'opérateurs qui n'a pas besoin de données supplémentaires. Si *extra_data est positionné, le tableau dans son ensemble est passé à la méthode consistent method, et l'élément approprié à la méthode comparePartial.

bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, Datum queryKeys[], bool nullFlags[])

Retourne TRUE si un item indexé répond à l'opérateur de requête possédant le numéro de stratégie n (ou pourrait le satisfaire, si l'indication recheck est retournée). Cette fonction n'a pas d'accès direct aux valeurs des items indexés. Au lieu de cela, ce qui est disponible, c'est la connaissance de quelles valeurs de clés extraites de la requête apparaissent dans un item indexé donné. Le tableau check a une longueur de nkeys, qui est la même que le nombre de clés retourné précédemment par extractQuery pour ce datum query. Chaque élément du tableau check est TRUE si l'item indexé contient la clé de requête correspondante, c'est à dire, si (check[i] == TRUE) la i-ème clé du tableau résultat de extractQuery est présente dans l'item indexé. Le datum query original est passé au cas où la méthode contains aurait besoin de le consulter, de même que les tableaux queryKeys[] et nullFlags[] retournée précédemment par extractQuery, ou NULL si aucun.

Quand extractQuery retourne une clé nulle dans queryKeys[], l'élément correpondant de check[] est TRUE si l'item indexé contient une clé nulle; c'est à dire que la sémantique de check[] est comme celle de IS NOT DISTINCT FROM. La fonction consistent peut examiner l'élément correspondant de nullFlags[] si elle a besoin de faire la différence entre une correspondance de valeur «normale» et une correspondance nulle.

En cas de réussite, *recheck devrait être positionné à TRUE si les enregistrements de la table doivent être revérifiées par rapport à l'opérateur de la requête, ou FALSE si le test d'index est exact. Autrement dit, une valeur de retour à FALSE garantit que l'enregistrement de la table ne correspond pas; une valeur de retour à TRUE avec *recheck à FALSE garantit que l'enregistrement de la table correspond à la requête; et une valeur de retour à TRUE avec *recheck à TRUE signifie que l'enregistrement de la table pourrait correspondre à la requête, et qu'il doit être récupéré et re-vérifié en évaluant l'opérateur de la requête directement sur l'item initialement indexé.

En option, une classe d'opérateurs pour GIN peut fournir une cinquième méthode :

int comparePartial(Datum partial_key, Datum key, StrategyNumber n, Pointer extra_data)

Compare une requête de correspondance partielle à une clé d'index. Renvoie un entier dont le signe indique le résultat : inférieur à zéro signifie que la clé d'index ne correspond pas à la requête mais que le parcours d'index va continuer ; zéro signifie que la clé d'index ne correspond pas à la requête ; supérieur à zéro indique que le parcours d'index doit s'arrêter car il n'existe pas d'autres correspondances. Le numéro de stratégie n de l'opérateur qui a généré la requête de correspondance partielle est fourni au cas où sa sémantique est nécessaire pour déterminer la fin du parcours. De plus, extra_data est l'élément correspondant du tableau extra-data fait par extractQuery, ou NULL sinon. Null keys are never passed to this function.

Pour supporter des requêtes à « correspondance partielle », une classe d'opérateur doit fournir la méthode comparePartial, et sa méthode extractQuery doit positionner le paramètre pmatch quand une requête à correspondance partielle est rencontrée. Voir Section 57.3.2, « Algorithme de mise en correspondance partielle » pour les détails.

Le type de données réel des différentes valeurs Datum mentionnées ci-dessus varien en fonction de la classe d'opérateurs. Les valeurs d'item passée à extractValue sont toujours du type d'entrée de la classe d'opérateur, et toutes les valeurs clé doivent être du type de STORAGE de la classe. Le type de l'argument query passé à extractQuery et consistent est ce qui est spécifié comme type de droite de l'opérateur du membre de classe identifié par le numéro de stratégie. Ce n'est pas nécessairement le même que le type de l'item, tant que des valeurs de clés d'un type correct peuvent en être extraites.