이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은에 대해 같은 페이지를 보려고 할 수 있습니다현재버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

56.2. 확장 성

SP-Gist인터페이스를 제공합니다 높은 수준의 추상화로 액세스 방법이 필요합니다. 개발자는 주어진 데이터 유형에 특정한 메소드 만 구현합니다. 그만큼SP-Gist코어는 책임이 있습니다 효율적인 디스크 매핑 및 트리 구조 검색. 그것 또한 동시성 및 로깅 고려 사항을 처리합니다.

leaf tuples ofSP-Gist트리에는 인덱스 열과 동일한 데이터 유형의 값이 포함되어 있습니다. 루트 레벨의 잎 사설 토토에는 항상 원본이 포함됩니다. 인덱싱 된 데이터 값이지만 낮은 레벨의 잎 사설 토토에는 접미사와 같은 압축 된 표현 만. 이 경우 운영자 클래스 지원 기능은 재구성 할 수 있어야합니다. 내부에서 축적 된 정보를 사용한 원래 값 잎 수준에 도달하기 위해 통과 된 사설 토토.

내부 사설 토토은 분기점이기 때문에 더 복잡합니다. 검색 트리에서. 각 내부 사설 토토에는 하나 이상의 세트가 포함됩니다노드, 유사한 그룹을 나타냅니다 잎 값. 노드에는 다운 링크가 포함되어 있습니다 또 다른 낮은 수준의 내부 튜플 또는 짧은 잎 튜플 목록 모두 같은 색인 페이지에 있습니다. 각 노드에는에레이블예를 들어, radix에서 트리 노드 레이블은 문자열의 다음 문자 일 수 있습니다. 값. 선택적으로, 내부 튜플은 a를 가질 수 있습니다.prefix모든 회원을 설명하는 값. a radix tree 이것은 대표의 일반적인 접두사 일 수 있습니다. 문자열. 접두사 값은 반드시 접두사 일 필요는 없지만 운영자 클래스가 필요한 데이터 일 수 있습니다. 예를 들어, a 쿼드 트리 4 사분면이있는 중심점을 저장할 수 있습니다. 관련하여 측정됩니다. 그런 다음 쿼드 트리 내부 튜플이 될 것입니다 또한이 주위의 사분면에 해당하는 4 개의 노드도 포함 중심점.

일부 트리 알고리즘은 레벨 (또는 깊이)에 대한 지식이 필요합니다. 현재 튜플, 그래서SP-Gist코어는 가능성을 제공합니다 내림차순으로 레벨 카운팅을 관리하는 운영자 클래스 나무. 또한 점진적으로 재구성을 지원합니다 필요할 때 대표 값.

참고 :thesp-gist코어 코드는 NULL 항목을 처리합니다. 하지만SP-Gist색인은 Nulls의 저장 항목을 수행합니다 인덱스 된 열, 이것은 인덱스 연산자 클래스 코드에서 숨겨져 있습니다. NULL 인덱스 항목이나 검색 조건이 전달되지 않습니다. 운영자 클래스 방법. (SP-Gist운영자는 엄격하고 할 수 없습니다 널 값에 대해 성공하십시오.) 널 값은 논의되지 않습니다. 추가 여기.

인덱스 운영자 클래스가 5 가지 사용자 정의 방법이 있습니다. 을 위한SP-Gist제공해야합니다. 모두 5는 2를 수락하는 협약을 따릅니다내부인수, 첫 번째는 포인터입니다 지원 방법에 대한 입력 값을 포함하는 C 구조, 두 번째 인수는 출력 값이있는 C 구조에 대한 포인터입니다. 배치해야합니다. 4 가지 방법은 방금 retlyvoid, 모든 결과가 출력에 나타나기 때문에 구조물; 하지만Leaf_consistent추가로 반환부울결과. 그만큼 메소드는 입력 스트러크의 필드를 수정해서는 안됩니다. 대체로 케이스, 출력 구조는 호출하기 전에 0으로 초기화됩니다. 사용자 정의 방법.

5 가지 사용자 정의 방법은 다음과 같습니다.

config

인덱스 구현에 대한 정적 정보를 반환합니다. 접두사 및 노드 레이블 데이터의 데이터 유형 OID 포함 유형.

theSQL기능은 다음과 같이 보인다 :

함수 만들기 my_config (내부, 내부) 반환 void ...

첫 번째 인수는 a에 대한 포인터입니다.SPGCONFIGINC 구조물, 입력 데이터를 포함합니다 기능. 두 번째 인수는 A에 대한 포인터입니다.SPGCONFIGOUTC struct 결과 데이터로 채우십시오.

typedef struct spgconfigin

    Oid Atttype;        / * 색인화 할 데이터 유형 */
 spgconfigin;

typedef struct spgconfigout

    OID PREFIXTYPE;     / * 내부 튜플 접두사의 데이터 유형 */
    OID LABELTYPE;      / * 내부 튜플 노드 레이블의 데이터 유형 */
    BOOL CANRETURNDATA;  / * opclass는 원본 데이터를 재구성 할 수 있습니다 */
    BOOL LONGVALUESOK;   / * opclass는 값에 대처할 수 있습니다 1 페이지 */
 spgconfigout;

atttype가 전달됩니다 다형성 인덱스 연산자 클래스 지원; 평범한 고정 데이터 유형 운영자 클래스는 항상 동일합니다 가치와 무시할 수 있습니다.

접두사를 사용하지 않는 운영자 클래스의 경우PrefixType로 설정할 수 있습니다voidoid. 마찬가지로, 그렇지 않은 운영자 클래스 노드 레이블 사용labelType설정할 수 있습니다 에게voidoid. CanreturnData연산자 인 경우 True를 설정해야합니다 클래스는 원래 공급 된 인덱스를 재구성 할 수 있습니다 값.LongValuesoktrue를 설정해야합니다 만atttype변수입니다 길이와 연산자 클래스는 긴 값을 분할 할 수 있습니다. 반복 된 접미사로 (참조섹션 56.3.1).

선택

내부에 새 값을 삽입하는 메소드를 선택합니다. 튜플.

theSQL기능은 다음과 같이 보인다 :

함수 생성 my_choose (내부, 내부) 반환 void ...

첫 번째 인수는 A에 대한 포인터입니다.SpgchooseinC 구조물, 입력 데이터를 포함합니다 기능. 두 번째 인수는 A에 대한 포인터입니다.spgchooseoutc 구조물 결과 데이터로 채우십시오.

typedef struct spgchoosein

    데이텀 데이텀;          / * 색인화 될 원본 데이텀 */
    데이텀 리프 듀다;      / * 잎에 저장 될 전류 데이텀 */
    int 레벨;          / * 현재 레벨 (0에서 계산) */

    / * 현재 내부 튜플의 데이터 */
    BOOL ALLTHESAME;     /* 튜플은 모든 것이 표시되어 있습니까? */
    BOOL HASPREFIX;      /* 튜플에는 접두사가 있습니까? */
    Datum Prefixdatum;    / * 그렇다면 접두사 값 */
    int nnodes;         / * 내부 튜플의 노드 수 */
    Datum *Nodelabels;     / * 노드 레이블 값 (null이 없음) */
 spgchoosein;

typedef enum spgchooseresulttype

    spgmatchnode = 1, / * 기존 노드로 내려갑니다 * /
    spgaddnode, / * 내부 튜플에 노드를 추가하십시오 * /
    spgsplittuple / * 분할 내부 튜플 (접두사 변경) * /
 spgchooseresulttype;

typedef struct spgchooseout

    spgchooseresulttype resulttype;     / * 액션 코드, 위 참조 */
    노동 조합

        spgmatchnode * /struct / * 결과 * /

            int noden;      / *이 노드로 내려갑니다 (0에서 index) */
            int levelAdd;   / *이 정도의 증분 레벨 */
            데이텀리스트 덤;  / * 새로운 잎 기준 */
         matchNode;
        spgaddnode * /struct / * 결과 * /

            데이텀 노 델라벨;  / * 새 노드 레이블 */
            int noden;      / * 삽입 할 위치 (0에서 색인) */
         addnode;
        spgsplittuple에 대한 struct / * 결과 * /

            / * 하나의 노드로 새로운 내부 튜플을 형성하는 정보 */
            부울 접두사 hasprefix;    /* 튜플은 접두사가 있어야합니까? */
            Datum PrefixprefixDatum;  / * 그렇다면 그 가치 */
            데이텀 노 델라벨;          / * 노드 레이블 */

            / * 모든 오래된 노드와 함께 새로운 하위 수준 내부 튜플을 형성하는 정보 */
            bool postfixhasprefix;   /* 튜플은 접두사가 있어야합니까? */
            Datum postfixprefixdatum; / * 그렇다면 그 가치 */
         splittuple;
               결과;
 spgchooseout;

Datum는 원래 데이텀입니다 색인에 삽입되어야했습니다.Leafdatum처음에는와 동일합니다.Datum이지만 더 낮은 수준에서 변경 될 수 있습니다 트리 인 경우선택또는picksplit메소드를 변경합니다. 삽입시 검색은 잎 페이지에 도달하고 현재 값Leafdatum새로 저장 될 것입니다 생성 된 잎 사설 토토.레벨입니다 루트 레벨의 경우 0에서 시작하는 현재 내부 튜플 레벨.Allthesame전류 인 경우 사실입니다 내부 튜플은 여러 동등한 노드를 포함하는 것으로 표시됩니다 (참조섹션 56.3.3).hasprefix전류 내부 튜플은 접두사를 함유하고; 그렇다면,PrefixDatum값입니다.nnodes에 포함 된 자식 노드의 수입니다 내부 튜플 및Nodelabelsis 레이블이없는 경우 레이블 값 또는 NULL 배열.

the선택함수는 결정할 수 있습니다 새로운 값이 기존 하위 노드 중 하나와 일치하는 것입니다. 또는 새 하위 노드를 추가해야하거나 새 값이 튜플 접두사와 일치하지 않으므로 내부 튜플은 덜 제한적인 접두사 생성을 위해 분할.

새 값이 기존 자식 노드 중 하나와 일치하는 경우resultTypetoSPGMATCHNODE. 세트Noden노드 어레이의 해당 노드의 인덱스 (0에서)까지. 세트levelAdd증분으로레벨내림차순으로 인한 해당 노드 또는 연산자 클래스가 사용하지 않는 경우 0으로 남겨 둡니다. 레벨. 세트Restdatum동등한Datum운영자 클래스가없는 경우 데이 텀을 한 레벨에서 다음 레벨로 수정하거나 그렇지 않으면 로 사용할 수정 된 값Leafdatum다음 단계에서.

새 하위 노드를 추가 해야하는 경우resultTypetoSpgaddnode. 세트Nodelabel신규에 사용되는 레이블에 노드 및 setNoden인덱스에 대한 ( 0) 노드 어레이에 노드를 삽입 할 수 있습니다. 노드 후 추가되었습니다,선택함수 수정 된 내부 튜플로 다시 호출됩니다. 그 전화 를 초래해야합니다.SPGMATCHNODE결과.

새 값이 사설 토토 접두사와 일치하지 않는 경우resulttypetoSPGSPLITTUPLE. 이 조치는 기존의 모든 것을 움직입니다 노드는 새로운 하위 수준 내부 튜플로, 기존을 대체합니다. 새와 연결되는 단일 노드를 갖는 튜플이있는 내부 튜플 하위 레벨 내부 튜플. 세트prefixhasprefix새로운지 여부를 나타냅니다 상부 사설 토토은 접두사가 있어야하며, 그렇다면 설정하면prefixprefixDatum접두사 값으로. 이 새로운 접두사 값은 그것보다 충분히 덜 제한적이어야합니다 인덱싱 할 새 값을 수락하려면 원본이되며 원래 접두사보다 길다. 세트Nodelabel노드에 사용할 레이블에 그것은 새로운 하위 수준의 내부 튜플을 가리킬 것입니다. 세트postfixhasprefix새로운지 여부를 나타냅니다 낮은 수준의 내부 튜플은 접두사가 있어야하며, 그렇다면 설정하면postfixprefixDatum접두사에 값. 이 두 접두사의 조합과 추가 레이블은 원래 접두사와 동일한 의미를 가져야합니다. 이동중인 노드 레이블을 변경할 기회가 없습니다. 새로운 하위 수준의 튜플, 어린이 지수 항목을 변경합니다. 노드가 분할 된 후선택함수는 다시 호출됩니다 교체 내부 튜플. 그 전화는 일반적으로를 초래할 것입니다.SPGADDNODE결과, 아마도 분할 단계에 추가 된 노드 레이블은 새 값과 일치하지 않습니다. 그래서 그 후, 마지막으로 돌아 오는 세 번째 전화가있을 것입니다SPGMATCHNODE삽입을 허용합니다 잎 수준으로 내려갑니다.

picksplit

잎 세트 위에 새 내부 튜플을 만드는 방법 결정 튜플.

theSQL선언 기능은 다음과 같이 보인다 :

함수 만들기 my_picksplit (내부, 내부) 반환 void ...

첫 번째 인수는 A에 대한 포인터입니다.SPGPICKSPLITINC 입력 데이터를 포함하는 구조 기능을 위해. 두 번째 인수는 A에 대한 포인터입니다.SPGPICKSPLITOUTC 구조물 결과 데이터로 채우십시오.

typedef struct spgpicksplitin

    int ntuples;        / * 잎 튜플 수 */
    데이텀 *데이텀;         / * 그들의 데이텀 (길이의 배열 ntuples) */
    int 레벨;          / * 현재 레벨 (0에서 계산) */
 spgpicksplitin;

typedef struct spgpicksplitout

    BOOL HASPREFIX;      /* 새로운 내부 튜플이 접두사가 있어야합니까? */
    Datum Prefixdatum;    / * 그렇다면 그 가치 */

    int nnodes;         / * 새 내부 튜플에 대한 노드 수 */
    Datum *Nodelabels;     / * 레이블 (또는 레이블 없음) */

    int *maptuplestonodes;   / * 각 잎에 대한 노드 인덱스 */
    데이텀 *리프트 수스 룸;    / * 각각의 새로운 잎 튜플에 보관할 데이 텀 */
 spgpicksplitout;

ntuples는 잎의 수입니다 제공된 사설 토토.Datums는 배열입니다 그들의 데이텀 값.레벨is 모든 잎 튜플이 공유하는 현재 레벨, 새로운 내부 튜플 레벨.

SEThasprefix새로운 내부 튜플에는 접두사가 있어야하며 설정하면PrefixDatum접두사 값으로. 세트nnodes새로운 내부 튜플이 포함되고 설정됩니다Nodelabels레이블 값의 배열로. (노드에 레이블이 필요하지 않은 경우Nodelabels보다섹션 56.3.2자세한 내용.) SETMaptuplestonodesto 노드의 인덱스 (제로)를 각각에 제공하는 배열 잎 튜플을 할당해야합니다. 세트Leaftupledatums값의 배열로 새로운 잎 사설 토토에 저장되었습니다 (이들은 입력과 동일합니다Datums운영자 클래스가없는 경우 한 레벨에서 다음 레벨로 데이텀을 수정하십시오).picksplit함수는 palloc'ing theNodelabels, MaptuplestonodesandLeaftupledatums배열.

둘 이상의 잎 사설 토토이 제공되면picksplit함수는 그것들을 분류합니다 둘 이상의 노드로; 그렇지 않으면 분할 할 수 없습니다 여러 페이지에 걸친 잎 튜플, 이것은 궁극적 인 목적입니다. 이 작업. 따라서이면picksplit함수는 모든 잎을 배치하게됩니다 동일한 노드의 튜플, Core SP-Gist 코드는 잎 튜플이있는 내부 튜플을 결정하고 생성합니다. 무작위로 여러 동일하게 표지 된 노드에 할당됩니다. 그런 것 튜플이 표시되어Allthesame이것은 일어났다. 그만큼선택andInner_consistent함수는 가져와야합니다 그러한 내부 튜플에 적합한 관리. 보다섹션 56.3.3자세한 내용은

picksplita에 적용 할 수 있습니다 단일 리프 사설 토토은의 경우에만config함수 세트LongValuesok진실과 더 큰 페이지 입력 값이 제공되었습니다. 이 경우 작동은 접두사를 벗기고 새롭고 짧은 잎을 생성하는 것입니다. 데이텀 값. 호출은 잎 기준이 짧아 질 때까지 반복됩니다. 페이지에 맞게 충분히 생성되었습니다. 보다섹션 56.3.1더 많은 정보.

Inner_consistent

트리 중에 따라야 할 노드 세트 (분기) 세트를 반환합니다 찾다.

theSQL기능은 다음과 같이 보인다 :

함수 만들기 my_inner_consistent (내부, 내부) 반환 void ...

첫 번째 인수는 a에 대한 포인터입니다.SpginnerConsistentinC 구조물, 입력을 포함합니다 기능에 대한 데이터. 두 번째 인수는 A에 대한 포인터입니다.SpginnerConsistentOutC 구조 함수는 결과 데이터로 채워야합니다.

typedef struct spginnerconsistentin

    스캔 키 스캔 키;       / * 운영자 배열 및 비교 값 */
    int nkeys;          / * 배열 길이 */

    Datum ReconstructedValue;     / * 부모에게 재구성 된 값 */
    int 레벨;          / * 현재 레벨 (0에서 계산) */
    bool returndata;     /* 원본 데이터를 반환해야합니까? */

    / * 현재 내부 튜플의 데이터 */
    BOOL ALLTHESAME;     /* 튜플은 모든 것이 표시되어 있습니까? */
    BOOL HASPREFIX;      /* 튜플에는 접두사가 있습니까? */
    Datum Prefixdatum;    / * 그렇다면 접두사 값 */
    int nnodes;         / * 내부 튜플의 노드 수 */
    Datum *Nodelabels;     / * 노드 레이블 값 (null이 없음) */
 SpginnerConsistentin;

typedef struct spginnerconsistentout

    int nnodes;         / * 방문 할 어린이 노드 수 */
    int *nodenumbers;    / * 노드 어레이의 인덱스 */
    int *levelAdds;      / * 각 */에 대한 이거 화수율
    Datum *재구성 Values;    / * 관련 재구성 값 */
 spginnerConsistEntOut;

배열Scankeys, 길이nkeys, 인덱스 검색을 설명합니다 정황). 이러한 조건은 색인과 결합됩니다 그들 모두를 만족시키는 항목은 흥미 롭습니다. (nkeys= 0은 모든 색인을 의미합니다 항목은 쿼리를 만족합니다.) 일반적으로 일관된 함수 만sk_strategysk_argument각 배열의 필드 인덱스 가능한 운영자에게 각각 제공되는 입력 비교 값. 특히 확인할 필요가 없습니다sk_flags비교가 있는지 확인하십시오 SP-Gist 핵심 코드가 그러한 것을 걸러 내기 때문에 값은 null입니다. 정황.재구성 valueis 부모 사설 토토에 대해 재구성 된 값; 그것은(Datum) 0루트 레벨에서 또는Inner_consistent함수는 값을 제공하지 않았습니다 부모 수준에서.레벨is 루트 레벨의 경우 0에서 시작하는 현재 내부 튜플 레벨.returnDataistrue이를 위해 재구성 된 데이터가 필요한 경우 질문; 이것은만큼 그렇게 될 것입니다config함수 주장CanreturnData. Allthesame현재 내부 튜플이 있으면 사실입니다 두드러진"All-the-Same"; 이 경우 모두 노드는 동일한 레이블 (있는 경우)을 가지므로 전부 또는 전혀 쿼리와 일치합니다 (참조섹션 56.3.3).hasprefix전류 내부 튜플은 접두사를 함유하고; 그렇다면,PrefixDatum값입니다.nnodes포함 된 자식 노드 수입니다 내부 튜플 및Nodelabelsis 레이블 값 배열 또는 노드에 노드에 없으면 NULL 라벨.

nnodes수로 설정해야합니다 검색으로 방문 해야하는 자식 노드 및Nodenumbers배열로 설정해야합니다 인덱스. 운영자 클래스가 레벨을 추적하는 경우levelAdds레벨의 배열로 방문 할 각 노드로 내림차순이 필요합니다. (종종 이러한 증분은 모든 노드에서 동일하지만 반드시 그렇지는 않기 때문에 배열이 사용됩니다.) value 인 경우 재구성이 필요합니다, 설정재구성값의 배열로 각 어린이 노드를 방문 할 때 재구성; 그렇지 않으면 떠나재구성null로. 주목하십시오 그만큼Inner_consistent함수는입니다 Palloc'ing the에 대한 책임Nodenumbers, levelAddsand재구성배열.

Leaf_consistent

리프 튜플이 쿼리를 만족시키는 경우 true를 반환합니다.

theSQL기능은 다음과 같이 보인다 :

함수 만들기 my_leaf_consistent (내부, 내부) 반환 bool ...

첫 번째 인수는 A에 대한 포인터입니다spleafconsistentinC 구조물, 입력을 포함합니다 기능에 대한 데이터. 두 번째 인수는 A에 대한 포인터입니다.SPLEAMCONSESTENTOUTc 구조 함수는 결과 데이터로 채워야합니다.

typedef struct spleafconsistentin

    스캔 키 스캔 키;       / * 운영자 배열 및 비교 값 */
    int nkeys;          / * 배열 길이 */

    Datum ReconstructedValue;     / * 부모에게 재구성 된 값 */
    int 레벨;          / * 현재 레벨 (0에서 계산) */
    bool returndata;     /* 원본 데이터를 반환해야합니까? */

    데이텀 리프 듀다;      / * 잎 튜플의 데이텀 */
 spgleafconsistentin;

typedef struct spgleafconsistentout

    데이텀 리프 값;      / * 재구성 된 원본 데이터 */
    부울 재건;        / * 운영자를 다시 확인 해야하는 경우 true 설정 */
 spleafconsistentout;

배열Scankeys, 길이nkeys, 인덱스 검색을 설명합니다 정황). 이러한 조건은 색인과 결합됩니다 그들 모두를 만족시키는 항목은 쿼리를 만족시킵니다. (nkeys= 0은 모든 색인을 의미합니다 항목은 쿼리를 만족합니다.) 일반적으로 일관된 함수 만sk_strategyandsk_argument각 배열의 필드 인덱스 가능한 운영자에게 각각 제공되는 입력 비교 값. 특히 확인할 필요가 없습니다sk_flags비교가 있는지 확인하십시오 SP-Gist 핵심 코드가 그러한 것을 걸러 내기 때문에 값은 null입니다. 정황.재구성 valueis 부모 사설 토토에 대해 재구성 된 값; 그것은(Datum) 0루트 레벨에서 또는Inner_consistent함수는 값을 제공하지 않았습니다 부모 수준에서.레벨입니다 루트 레벨의 경우 0에서 시작하는 현재 잎 튜플 레벨.returnDataistrue이를 위해 재구성 된 데이터가 필요한 경우 질문; 이것은만큼 그렇게 될 것입니다config기능 주장CanreturnData. Leafdatum는 현재에 저장된 핵심 값입니다 잎 튜플.

함수가 반환해야합니다trueLeaf Tuple은 쿼리와 일치합니다.거짓if 아니다. 에서truecase, ifreturnDataistruetheLeafValue값으로 설정해야합니다 이 잎 사설 토토에 대해 원래 색인으로 공급되었습니다. 또한,다시 확인로 설정 될 수 있습니다true경기가 불확실한 경우 연산자는 실제 힙 사설 토토에 다시 적용되어 확인해야합니다. 경기.

모든 SP-Gist 지원 방법은 일반적으로 단기간 메모리 컨텍스트; 즉,CurrentMemoryContext처리 후 재설정됩니다 각 사설 토토의. 따라서 걱정하는 것은 그리 중요하지 않습니다 당신이 palloc 모든 것을 pfree'ing. (그만큼config메소드는 예외입니다 메모리가 새는 것을 피하십시오. 그러나 보통config메소드는 할당하는 것 외에는 아무것도하지 않아야합니다 전달 된 매개 변수 구조물로의 상수.)

인덱스 된 열이 Collatable Data Type 인 경우 인덱스 Collation은 다음을 사용하여 모든 지원 방법으로 전달됩니다. 기준pg_get_collation ()메커니즘.