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

55.2. 확장 성

전통적으로, 새로운 사설 토토 액세스 방법을 구현하면 a 많은 어려운 일. 내부를 이해해야했습니다 Lock Manager 및 Write-Ahead와 같은 데이터베이스의 작업 통나무. 그만큼gist인터페이스는 a 액세스 방법 구현자를 요구하는 높은 추상화 수준 액세스중인 데이터 유형의 의미를 구현하기 위해서만. 그만큼gist레이어 자체는주의를 기울입니다 동시성, 트리 구조 로깅 및 검색.

이 확장 성은 확장 성과 혼동되어서는 안됩니다 데이터 측면에서 다른 표준 검색 트리 중 핸들. 예를 들어,사설 토토확장 가능한 B- 트리 및 해시 사설 토토를 지원합니다. 그것은 당신을 의미합니다 사용할 수 있습니다사설 토토빌드 a 원하는 데이터 유형보다 B- 트리 또는 해시. 그러나 B- 트리 만 지원 범위는 (<, =, ) 및 해시 사설 토토 평등 쿼리 만 지원합니다.

사설 토토 인 경우 A가있는 이미지 컬렉션이 표시됩니다.사설 토토b- 트리, 쿼리 만 발행 할 수 있습니다 와 같은"imagex는 imagey와 같다", "imagex는 imagey보다 작습니다"and"imagex가 이미지보다 큽니다". 당신이 정의하는 방법에 따라"Equals", ""보다 작습니다.and""보다 큰 "이 맥락에서 이것은 될 수 있습니다 유용한. 그러나 A를 사용함으로써gist기반 사설 토토에서 도메인 별 요청 방법을 만들 수 있습니다 질문, 아마도"모든 이미지를 찾으십시오 말 "또는"모든 과도한 노출을 찾으십시오 이미지 ".

A를 얻는 데 필요한 모든gist액세스 메소드 UP 및 실행은 여러 사용자 정의를 구현하는 것입니다. 트리의 키의 동작을 정의하는 방법. 물론 이 방법은 멋진 쿼리를 지원하기 위해서는 꽤 멋져야하지만 모든 표준 쿼리 (B- 트리, R- 트리 등) 비교적 간단합니다. 요컨대gist와 함께 확장 성을 결합합니다 일반성, 코드 재사용 및 깨끗한 인터페이스.

사설 토토 연산자가에 대한 7 가지 방법이 있습니다.gist제공해야합니다 그것은 선택 사항입니다. 사설 토토의 정확성은 적절하게 보장됩니다 구현동일, 일관성Union방법, 효율성 (크기 및 속도) 사설 토토는에 따라 다릅니다.페널티andpicksplit방법. 나머지 두 기본 방법은입니다.압축andDecompress, 사설 토토가 내부를 가질 수있게합니다 IT 색인 데이터와 다른 유형의 트리 데이터. 나뭇잎 사설 토토 된 데이터 유형이지만 다른 트리 노드는 어떤 c 구조물이든 (하지만 여전히 따라야사설 토토데이터 유형 규칙은 여기에 참조Varlena가변 크기의 데이터의 경우). 만약 트리의 내부 데이터 유형은 SQL 레벨에 존재합니다.스토리지옵션생성 운영자 클래스명령을 사용할 수 있습니다. 선택적 8 번째 방법 이다거리운영자 클래스는 순서 스캔을 지원하기를 원합니다 (가장 가까운 곳 검색).

일관성

사설 토토 항목 주어진P및 쿼리 값Q,이 함수는 여부를 결정합니다 사설 토토 항목은입니다."일관성"질문; 즉, 술어가 될 수 있습니다"indexed_column indexable_operator Q"색인 입력? 리프 사설 토토 항목의 경우 이것은 테스트와 같습니다. 사설 토토 가능한 조건, 내부 트리 노드에 대해서는 사설 토토의 하위 트리를 스캔 해야하는지 여부를 결정합니다. 트리 노드로 표시됩니다. 결과가true, a다시 확인플래그 또한 반환됩니다. 이것은 술어가 확실히 있는지를 나타냅니다 사실이거나 아마도 사실입니다. 만약에Recheck=거짓그런 다음 사설 토토가 테스트되었습니다 정확히 조건이 있지만 If다시 확인=true행은입니다 후보 일치 만. 이 경우 시스템이 자동으로됩니다 평가indexable_operator실제 행 값에 대해 실제로 일치하는지 확인하십시오. 이것 컨벤션 허용gistTO 무손실 및 손실 사설 토토 구조를 모두 지원합니다.

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

함수 생성 또는 교체 my_consistent (내부, data_type, smallint, oid, 내부)
Bool을 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는 이것을 따라갈 수 있습니다. 해골:

Datum my_consistent (pg_function_args);
pg_function_info_v1 (my_consistent);

자료
my_consistent (pg_function_args)

    gistentry *entry = (gistentry *) pg_getarg_pointer (0);
    data_type *query = pg_getarg_data_type_p (1);
    StrategyNumber Strategy = (StrategyNumber) pg_getarg_uint16 (2);
    /* OID 하위 유형 = PG_GETARG_OID (3); */
    bool *recheck = (bool *) pg_getarg_pointer (4);
    data_type *key = datumgetDatatype (enther- key);
    부리 retval;

    /*
     * 전략, 키 및 쿼리의 함수로 반환 값을 결정하십시오.
     *
     * gist_leaf (Entry)를 사용하여 인덱스 트리에서 호출되는 위치를 알 수 있습니다.
     * 예를 들어 = 연산자를 지원할 때 편리합니다 (예 :
     * 비 잎 노드에서 비 빈 연합 ()을 확인하고 잎의 평등을 확인하십시오.
     * 노드).
     */

    *다시 확인 = 참;        / * 또는 확인이 정확한 경우 false */

    pg_return_bool (retval);

여기,는 사설 토토의 요소입니다 그리고쿼리색인. 그만큼StrategyNumber매개 변수 운영자 클래스의 운영자가 적용되는지를 나타냅니다. 의 연산자 번호 중 하나와 일치합니다.운영자 클래스 만들기명령. 무엇에 따라 클래스에 포함시킨 운영자, 데이터 유형Query운영자마다 다를 수 있지만 위의 골격은 그렇지 않다고 가정합니다.

Union

이 방법은 트리의 정보를 통합합니다. 주어진 세트 항목,이 기능은 주어진 모든 항목.

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

함수 생성 또는 교체 my_union (내부, 내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는 이것을 따라갈 수 있습니다. 해골:

Datum my_union (pg_function_args);
pg_function_info_v1 (my_union);

자료
my_union (pg_function_args)

    gistentRyvector *entryVec = (gistentRyvector *) pg_getarg_pointer (0);
    gistentry *ent = EntryVec- 벡터;
    data_type *out,
               *TMP,
               *오래된;
    int numranges,
                i = 0;

    numranges = actorvevec- n;
    tmp = DatumgetDatatype (ENT [0] .key);
    out = tmp;

    if (numranges == 1)

        out = data_type_deep_copy (tmp);

        pg_return_data_type_p (out);

    for (i = 1; i <numranges; i ++)

        old = out;
        tmp = DatumgetDatatype (ent [i] .key);
        out = my_union_implementation (out, tmp);

    pg_return_data_type_p (out);

보시다시피,이 골격에서 우리는 데이터 유형을 다루고 있습니다. 어디Union (X, Y, Z) = Union (Union (X, Y), 지). 그렇지 않은 경우 데이터 유형을 지원하기에 쉽습니다. 이 사례는 this에서 적절한 노조 알고리즘을 구현함으로써gist지원 방법.

theUnion구현 함수 새로 포인터를 반환해야palloc ()ed 메모리. 당신은 단지 무엇이든 반환 할 수 없습니다 입력은.

압축

데이터 항목을 실제에 적합한 형식으로 변환합니다. 사설 토토 페이지의 저장소.

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

함수 생성 또는 교체 my_compress (내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는 이것을 따라갈 수 있습니다. 해골:

Datum my_compress (pg_function_args);
pg_function_info_v1 (my_compress);

자료
my_compress (pg_function_args)

    gistentry *entry = (gistentry *) pg_getarg_pointer (0);
    gistentry *retval;

    if (Entry- Leafkey)

        / * 입력- 키를 압축 버전으로 교체하십시오 */
        compressed_data_type *compressed_data = palloc (sizeof (compressed_data_type));

        / *채우기 *Entry- 키 ... */

        retval = palloc (sizeof (gistentry));
        gistentryinit (*retval, pointergetDatum (compressed_data),
                      Entry- Rel, Entry- Page, Entry- 오프셋, False);

    또 다른

        / * 일반적으로 우리는 잎이 아닌 항목으로 아무것도 할 필요가 없습니다 */
        retval = 진입;

    pg_return_pointer (retval);

당신은 적응해야합니다compressed_data_type특정 유형으로 잎 노드를 압축하기 위해 변환하고 있습니다. 강의.

귀하의 요구에 따라, 당신은 또한 관심이 필요할 수 있습니다. 압축null거기에있는 값, 저장 예를 들어(Datum) 0LikeGIST_CIRCLE_COMPRESdoes.

Decompress

반대압축메소드. 데이터 항목의 사설 토토 표현을 데이터베이스에서 조작 할 수있는 형식.

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

함수 생성 또는 교체 my_decompress (내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는 이것을 따라갈 수 있습니다. 해골:

Datum my_decompress (pg_function_args);
pg_function_info_v1 (my_decompress);

자료
my_decompress (pg_function_args)

    pg_return_pointer (pg_getarg_pointer (0));

위의 골격은없는 경우에 적합합니다. 감압이 필요합니다.

페널티

값을 나타내는 값을 반환합니다"비용"나무의 특정 분기에 새 입구를 삽입하는 것. 항목은 최소 경로에 삽입됩니다페널티나무에서. 값페널티는 음이 없어야합니다. 경우 a 음수 값이 반환되고 0으로 취급됩니다.

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

함수 생성 또는 교체 my_penalty (내부, 내부, 내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;  - 경우에 따라 페널티 기능이 엄격 할 필요는 없습니다

그리고 C 모듈의 일치하는 코드는 이것을 따라갈 수 있습니다. 해골:

Datum my_penalty (pg_function_args);
pg_function_info_v1 (my_penalty);

자료
my_penalty (pg_function_args)

    gistentry *origentry = (gistentry *) pg_getarg_pointer (0);
    gistentry *newentry = (gistentry *) pg_getarg_pointer (1);
    float *penalty = (float *) pg_getarg_pointer (2);
    data_type *orig = datumgetDatatype (Origentry- 키);
    data_type *new = DatumgetDatatype (newentry- 키);

    *penalty = my_penalty_implementation (Orig, New);
    pg_return_pointer (페널티);

the페널티함수는 중요합니다 색인의 우수한 성능. 삽입 시간에 사용됩니다 새를 추가 할 위치를 선택할 때 따라야 할 지점을 결정하십시오. 나무의 입구. 쿼리 시점에서 인덱스의 균형이 높아집니다 더 빨리 조회.

picksplit

사설 토토 페이지 분할이 필요한 경우이 기능이 결정됩니다. 페이지의 항목은 이전 페이지에 유지해야하며 새 페이지로 이동해야합니다.

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

함수 생성 또는 교체 my_picksplit (내부, 내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는 이것을 따라갈 수 있습니다. 해골:

Datum my_picksplit (pg_function_args);
pg_function_info_v1 (my_picksplit);

자료
my_picksplit (pg_function_args)

    gistentRyvector *entryVec = (gistentRyvector *) pg_getarg_pointer (0);
    OffsetNumber maxoff = EntryVec- n -1;
    gistentry *ent = EntryVec- 벡터;
    gist_splitvec *v = (gist_splitvec *) pg_getarg_pointer (1);
    INT I,
                nbytes;
    오프셋 너버 *왼쪽,
               *오른쪽;
    data_type *tmp_union;
    data_type *Unionl;
    data_type *Unionr;
    gistentry ** raw_entryvec;

    maxoff = EntryVec- n -1;
    nbytes = (maxoff + 1) * sizeof (offsetNumber);

    v- spl_left = (OffsetNumber *) palloc (nbytes);
    왼쪽 = v- spl_left;
    v- spl_nleft = 0;

    v- spl_right = (OffsetNumber *) palloc (nbytes);
    오른쪽 = v- spl_right;
    v- spl_nright = 0;

    Unionl = null;
    Unionr = null;

    /* 원시 입력 벡터를 초기화합니다. */
    raw_entryvec = (gistentry **) malloc (EntryVec- n *sizeof (void *));
    for (i = firstOffSetNumber; i <= maxOff; i = OffSetNumberNext (i))
        raw_entryvec [i] = & (EntryVec- 벡터 [i]);

    for (i = firstOffSetNumber; i <= maxOff; i = OffSetNumberNext (i))

        int real_index = raw_entryvec [i] - EntryVec- 벡터;

        TMP_UNION = DATUMGETDATATYPE (EntryVec- 벡터 [real_index] .key);
        assert (tmp_union! = null);

        /*
         * 인덱스 항목을 넣을 위치를 선택하고 Unionl 및 UnionR 업데이트
         * 따라서. V_SPL_LEFT 또는에 대한 항목을 추가하십시오
         * v_spl_right와 카운터에 관심이 있습니다.
         */

        if (my_choice_is_left (Unionl, Curl, Unionr, Curr))

            if (UnionL == null)
                Unionl = tmp_union;
            또 다른
                Unionl = my_union_implementation (Unionl, Tmp_union);

            *왼쪽 = real_index;
            ++ 왼쪽;
            ++ (v- spl_nleft);

        또 다른

            /*
             * 오른쪽에 동일합니다
             */

    v- spl_ldatum = DataTypeGetDatum (Unionl);
    v- spl_rdatum = DataTypeGetDatum (UnionR);
    pg_return_pointer (V);

좋아요페널티, Thepicksplit기능은 좋은 성능에 중요합니다 색인의. 적절한 디자인페널티picksplit구현은 도전입니다 잘 실적이 좋은 구현gist인덱스 거짓말.

동일

두 인덱스 항목이 동일하면 false 인 경우 true를 반환합니다 그렇지 않으면.

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

함수 생성 또는 교체 my_same (내부, 내부, 내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는 이것을 따라갈 수 있습니다. 해골:

Datum my_same (pg_function_args);
pg_function_info_v1 (my_same);

자료
my_same (pg_function_args)

    prefix_ra사설 토토e *v1 = pg_getarg_prefix_ra사설 토토e_p (0);
    prefix_ra사설 토토e *v2 = pg_getarg_prefix_ra사설 토토e_p (1);
    bool *result = (bool *) pg_getarg_pointer (2);

    *결과 = my_eq (v1, v2);
    pg_return_pointer (결과);

역사적 이유로동일함수는 부울 결과를 반환하지 않습니다. 대신해야합니다 세 번째 인수로 표시된 위치에 플래그를 저장합니다.

거리

사설 토토 항목 주어진P및 쿼리 값Q,이 함수는 다음을 결정합니다 사설 토토 항목"거리"쿼리에서 값. 운영자 클래스 인 경우이 기능을 제공해야합니다 주문 연산자가 포함되어 있습니다. 주문을 사용하는 쿼리 연산자는 인덱스 항목을 가장 작은"거리"값 먼저, 결과는 운영자의 의미와 일치해야합니다. a 리프 인덱스 항목 결과는 단지의 거리를 나타냅니다. 색인 입력; 내부 트리 노드의 경우 결과는 어린이 입국이 가질 수있는 가장 작은 거리.

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

함수 생성 또는 교체 my_distance (내부, data_type, smallint, oid)
float8을 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는 이것을 따라갈 수 있습니다. 해골:

Datum my_distance (pg_function_args);
pg_function_info_v1 (my_distance);

자료
my_distance (pg_function_args)

    gistentry *entry = (gistentry *) pg_getarg_pointer (0);
    data_type *query = pg_getarg_data_type_p (1);
    StrategyNumber Strategy = (StrategyNumber) pg_getarg_uint16 (2);
    /* OID 하위 유형 = PG_GETARG_OID (3); */
    data_type *key = datumgetDatatype (enther- key);
    이중 retval;

    /*
     * 전략, 키 및 쿼리의 함수로 반환 값을 결정하십시오.
     */

    pg_return_float8 (retval);

에 대한 인수거리함수는의 인수와 동일합니다.일관성플래그를 다시 확인하지 않는 한 기능 사용됩니다. 잎 지수 항목까지의 거리는 항상 튜플을 다시 주문할 방법이 없기 때문에 정확하게 결정 그들이 반환되면. 언제든지 근사치가 허용됩니다 내부 트리 노드까지의 거리를 결정하는 한 결과는 어린이의 실제 거리보다 크지 않습니다. 따라서 예를 들어, 경계 상자까지의 거리는 일반적으로 충분합니다. 기하학적 애플리케이션. 결과 값은 유한 할 수 있습니다float8값. (무한대 및 마이너스 무한대 NULLS와 같은 케이스를 처리하는 데 내부적으로 사용되므로 추천거리기능 이 값을 반환하십시오.)

모든 GIST 지원 방법은 일반적으로 단기간에 호출됩니다. 메모리 컨텍스트; 즉,CurrentMemoryContext각 튜플 후에 재설정됩니다 처리됩니다. 따라서 걱정하는 것은 그리 중요하지 않습니다 당신이 palloc 모든 것을 pfree'ing. 그러나 경우에 따라 유용합니다 반복 된 호출에서 데이터를 캐시하는 지원 방법. 할 일 그것은 더 긴 수명 데이터를 할당fcinfo- flinfo- fn_mcxt그리고 포인터를 유지하십시오fcinfo- flinfo- fn_extra. 그런 데이터는 인덱스 작업의 수명을 위해 살아남을 것입니다 (예 : 단일 GIST 인덱스 스캔, 인덱스 빌드 또는 인덱스 튜플 삽입). BE a를 대체 할 때 이전 값을 pfree에 조심하십시오.fn_extra값 또는 누출이 축적됩니다 작동 기간.