64.3. Extensibility

GIN 接口具有很高的抽象度,要求访问方法实现者仅实现被访问数据类型的语义。 GIN 层本身负责并发,日志记录和搜索树结构。

要使 GIN 访问方法正常工作,要做的就是实现一些用户定义的方法,这些方法定义树中键的行为以及键,索引项和可索引查询之间的关系。简而言之,GIN 将可扩展性与通用性,代码重用和干净的接口结合在一起。

GIN 的运算符类必须提供两种方法:

searchMode是一个输出参数,允许extractQuery指定有关搜索方式的详细信息。如果*searchMode设置为GIN_SEARCH_MODE_DEFAULT(这是它在调用前初始化的值),则只有与至少一个返回的键匹配的项才被视为候选匹配项。如果*searchMode设置为GIN_SEARCH_MODE_INCLUDE_EMPTY,则除了包含至少一个匹配键的项之外,根本不包含键的项也被视为候选匹配项。 (例如,此模式对于实现 is-subset-of 运算符很有用.)如果*searchMode设置为GIN_SEARCH_MODE_ALL,则索引中的所有非空项目都被视为候选匹配项,无论它们是否与返回的任何键匹配。 (此模式比其他两种选择慢得多,因为它本质上需要扫描整个索引,但是可能需要正确实现极端情况。在大多数情况下需要此模式的操作员可能不是 GIN 的理想选择access/gin.h中定义了用于设置此模式的符号。

pmatch是支持部分匹配的输出参数。要使用它,extractQuery必须分配一个*nkeys布尔数组并将其地址存储在*pmatch。如果相应的键要求部分匹配,则数组的每个元素应设置为 TRUE,否则设置为 FALSE。如果*pmatch设置为NULL,则 GIN 假定不需要部分匹配。变量在调用前被初始化为NULL,因此不支持部分匹配的运算符类可以忽略此参数。

extra_data是一个输出参数,它允许extractQuery将其他数据传递给consistentcomparePartial方法。要使用它,extractQuery必须分配一个*nkeys指针数组并将其地址存储在*extra_data,然后将要存储的内容存储到各个指针中。变量在调用之前被初始化为NULL,因此该参数可以简单地被不需要额外数据的运算符类忽略。如果设置了*extra_data,则将整个数组传递给consistent方法,并将适当的元素传递给comparePartial方法。

运算符类还必须提供一个函数来检查索引项是否与查询匹配。它有两种形式,布尔consistent函数和三元triConsistent函数。 triConsistent涵盖了两者的功能,因此仅提供triConsistent就足够了。但是,如果布尔变量的计算成本显着降低,则同时提供这两种变量可能是有利的。如果仅提供布尔变量,则会禁用某些依赖于在获取所有键之前反驳索引项的优化。

extractQueryqueryKeys[]中返回空键时,如果索引的项目包含空键,则对应的check[]元素为 TRUE;也就是说,check[]的语义类似于IS NOT DISTINCT FROMconsistent函数可以检查相应的nullFlags[]元素是否需要确定常规值匹配和空匹配之间的区别。

成功后,如果需要根据查询运算符重新检查堆 Tuples,则*recheck应设置为 TRUE;如果索引测试正确,则应设置为 FALSE。也就是说,返回 FALSE 可以确保堆 Tuples 与查询不匹配。将*recheck设置为 FALSE 的 TRUE 返回值可确保堆 Tuples 确实与查询匹配; *recheck设置为 TRUE 的 TRUE 返回值意味着堆 Tuples 可能与查询匹配,因此需要通过直接针对原始索引项评估查询运算符来获取并重新检查它。

check向量中没有GIN_MAYBE值时,GIN_MAYBE返回值等效于在布尔consistent函数中设置recheck标志。

另外,GIN 必须有一种方法可以对存储在索引中的键值进行排序。操作员类可以通过指定比较方法来定义排序 Sequences:

或者,如果运算符类未提供compare方法,则 GIN 将为索引键数据类型查找默认的 btree 运算符类,并使用其比较功能。建议在仅用于一种数据类型的 GIN 运算符类中指定比较函数,因为查找 btree 运算符类需要花费几个周期。但是,多态 GIN 运算符类(例如array_ops)通常不能指定单个比较函数。

(可选)GIN 的运算符类可以提供以下方法:

为了支持“部分匹配”查询,操作员类必须提供comparePartial方法,并且在遇到部分匹配查询时,其extractQuery方法必须设置pmatch参数。有关详情,请参见Section 64.4.2

上面提到的各种Datum值的实际数据类型取决于操作符类别。传递给extractValue的项目值始终是操作员类别的 Importing 类型,并且所有键值都必须属于该类别的STORAGE类型。传递给extractQueryconsistenttriConsistentquery参数的类型是由策略编号标识的类成员运算符的右侧 Importing 类型。只要可以从中提取正确类型的键值,就不必与索引类型相同。但是,建议这三个支持函数的 SQL 声明对query参数使用 opclass 的索引数据类型,即使实际的类型可能取决于操作符。

上一章 首页 下一章