天天看點

GIN索引-擴充性

GIN索引的接口實作了一個高層次的抽象,要求通路使用者僅需要實作被通路資料類型的語義。GIN層自身可以處理并發操作、記錄日志、搜尋樹結構的任務。

定義GIN索引的通路方式所要做的事情就是實作多個使用者定義的方法,這些方法定義了鍵在樹中的行為、鍵與鍵之間的關系、需要索引的item、能夠使用索引的查詢。簡而言之,GIN索引将擴充性與普遍性、代碼重用、清晰的接口結合在了一起。

實作GIN索引的操作符類有如下四個方法:

int compare(Datum a, Datum b)

比較兩個key(不是索引的item)然後傳回一個小于零、零或大于零的值,分别表示第一個key小于、等于或大于第二個key。NULL不會被傳入這個函數。

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

給定一個要被索引的item,傳回一個對應key的數組。傳回key的數目必須存儲在nkeys中。如果任何key都可能為NULL,還要配置設定包含nkeys個布爾元素的數組,将位址存儲到nullFlags,并且根據需要設定NULL值。 如果所有key都是非NULL,可以讓nullFlags保持為NULL(他的初始值)。如果item不包含任何key,傳回值可以為NULL。

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

給定一個被查詢的值,傳回一個對應的key的數組。也就是說,query是可索引操作符右側的值,而該操作符左側是被索引的字段。 n是操作符類中操作符的政策号。通常,extractQuery需要參考n來決定query的資料類型以及抽取鍵值的方法。傳回key的個數必須存放在nkeys中。如果任何key都可能為NULL,還要配置設定包含nkeys個布爾元素的數組,将位址存儲到nullFlags,并且根據需要設定NULL值。 如果所有key都是非NULL的,可以讓nullFlags保持為NULL(他的初始值)。如果query不包含任何key,傳回值可以為NULL。

searchMode是一個輸出參數,他允許extractQuery指定一些關于如何執行搜尋的細節。如果設定searchMode為GIN_SEARCH_MODE_DEFAULT(這也是調用函數前此參數的初始化值),隻有那些至少傳回一個key的item才能被考慮作為候選比對項。如果設定searchMode為GIN_SEARCH_MODE_INCLUDE_EMPTY,除了包含至少一個比對key的item之外,根本不包含任何key的item也被考慮作為候選比對項。(這個模式對于實作像“是否是子集”這樣的操作是有用的)如果設定*searchMode為GIN_SEARCH_MODE_ALL,索引中所有非NULL的item都被考慮作為候選比對項,不管他們是否比對傳回key中的任何一個。

pmatch是一個允許支援部分比對的輸出參數。如果使用此參數,extractQuery必須配置設定有nkeys個布爾元素的數組,并把數組位址儲存到pmatch。如果需要部分比對相應的key,則數組的每個元素應該設定為TRUE;如果不需要比對,則設定為FALSE。如果設定*pmatch為NULL,則假設GIN不需要部分比對。在函數調用前這個值被初始化為NULL,是以,對于不支援部分比對的操作符類,可以忽略這個參數。

extra_data是一個允許extractQuery以consistent和comparePartial的方式傳遞額外資料的輸出參數。如果使用他,extractQuery必須配置設定一個包含nkeys個Pointer元素的數組,并把數組位址儲存到extra_data,然後把他想附加的東西存儲到各個獨立的指針中。在函數調用前這個值初始化為NULL,是以,對于不需要附加資料的操作符類,可以忽略這個參數。如果設定了*extra_data,那麼以consistent方式傳遞整個數組,使用comparePartial方式傳遞适當的元素。

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

如果被索引項滿足StrategyNumber為n的查詢操作符則傳回TRUE。這個函數并不直接通路被索引項的值,因為GIN并沒有精确的把項目儲存下來,但是需要知道從查詢中提取的哪些鍵值出現在給定的被索引項中。 check數組的長度是nkeys,這個與query調用extractQuery函數傳回的鍵值的數目相同。如果索引項包含了相應的查詢鍵,check數組中對應的元素值就是TRUE。比如,如果(check[i] == TRUE),那麼意味着extractQuery的結果數組的第i個鍵出現在索引項中。考慮可能會用到consistent方式,原始的query也被作為參數傳入進來。與此相同的還有extractQuery函數傳回的queryKeys[]和nullFlags[]。 extra_data是extractQuery函數傳回的額外資料數組,如果沒有的話就是NULL。

當extractQuery在queryKeys[]中傳回一個NULL的鍵值,如果被

手機靓号購買平台

索引項包含NULL鍵值,相應的check[]中的元素是TRUE。也就是說,check[]的語義很像IS NOT DISTINCT FROM。如果需要知道是通常值比對還是NULL比對,consistent函數可以檢查相應的nullFlags[]元素。

成功執行後,如果堆元組需要針對查詢運算符進行重新檢查,recheck需要設定為TRUE,如果索引測試已經是精确的了,則設為FALSE。也就是說,FALSE的傳回值確定堆元組不比對這個查詢;設定recheck為FALSE的TRUE的傳回值確定堆元組比對這個查詢;設定*recheck為TRUE的TRUE的傳回值意味着堆元組可能比對這個查詢,是以需要通過直接對照原始索引項對查詢運算符進行擷取和重新檢查。

GIN操作符類可以可選地提供第五個函數。

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

比較一個部分比對查詢鍵和一個索引鍵。傳回一個整型值,他個符号代表了不同的含義:小于0意味着索引鍵不比對查詢,但是索引掃描應該繼續; 0意味着索引鍵比對查詢;大于0訓示應該終止索引掃描,因為不可能再有更多的比對。在需要确定何時結束掃描的語義的情況下,這裡提供了生成部分一緻查詢的操作符的政策号n。同樣的,extra_data是extractQuery生成的額外資料數組中的相應元素,如果沒有對應的元素,則為NULL。 NULL的鍵永遠不會被傳入這個函數。

為了支援"部分比對"查詢,一個操作符類必須提供comparePartial方法,并且當遇到部分比對查詢時,他的extractQuery方法必須設定pmatch參數。詳細資訊請參考部分比對算法。

上面的各種Datum值的實際資料類型根據操作符類的不同而不同。傳入到extractValue中的項目值總是操作符類的輸入類型,所有的鍵值類型必須是這個類的STORAGE類型。傳入到extractQuery和consistent的query參數的類型是由政策号識别的類成員操作符的右操作數的輸入類型。他不需要和項目類型相同,隻要可以從中抽取出正确類型的鍵值。

繼續閱讀