토토 결과 연산자가에 대한 7 가지 방법이 있습니다gist제공해야합니다. 단정
인덱스의 적절한 토토 결과으로 인덱스가 보장됩니다.동일
, 일관성
andUnion
방법, 효율성 (크기 및
토토 결과의 속도)는에 따라 다릅니다.페널티
andpicksplit
방법. 나머지 두 가지 방법
이다압축
andDecompress
색인이 토토 결과되는 데이터와 다른 유형의 내부 트리 데이터.
잎은 토토 결과 된 데이터 유형이어야하며 다른 잎은
트리 노드는 모든 C 구조물 일 수 있습니다 (그러나 여전히 따라야합니다토토 결과데이터 유형 규칙은 여기에 있습니다.
참조Varlena가변 크기의 경우
데이터). 트리의 내부 데이터 유형이 SQL 레벨에 존재하는 경우
그만큼스토리지옵션운영자 클래스 만들기명령을 사용할 수 있습니다.
일관성
토토 결과 항목 주어진P및 a 쿼리 값Q,이 기능 토토 결과 항목이 |10392_10406쿼리와 함께; 즉, 할 수 있습니다 술어"indexed_column indexable_operator Q"인덱스 항목? 리프 인덱스 항목의 경우 이것은 동일합니다 내부의 경우 인덱스 가능한 조건을 테스트합니다 트리 노드 이것은 스캔 해야하는지 여부를 결정합니다. 트리 노드로 표시되는 인덱스의 하위 트리. 언제 결과는입니다.true, aRecheck플래그도 반환해야합니다. 이것 술어가 확실히 사실인지를 나타냅니다 아마도 사실입니다. 만약에Recheck=거짓그러면 토토 결과가 테스트되었습니다 술어 조건은 정확히 반면Recheck=true행은 후보 일일뿐입니다. 이 경우 시스템이됩니다 자동으로 평가indexable_operator실제에 대한 실제로 일치하는지 확인하기 위해 값. 이 컨벤션 허용gist지원 무손실 및 손실 인덱스 구조.
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매개 변수를 나타냅니다 운영자 클래스의 운영자가 적용되고 있습니다. 의 연산자 번호 중 하나와 일치합니다.운영자 클래스 만들기명령. 에 따라 클래스에 포함시킨 운영자, 데이터 유형쿼리연산자이지만 위의 골격은 그렇지 않다고 가정합니다.
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), Z). 지원하기에 쉽습니다 이 경우가 아닌 경우 데이터 유형은 이것의 적절한 노조 알고리즘gist지원 방법.
theUnion
토토 결과
함수는 새로 포인터를 반환해야합니다palloc ()
ed 메모리. 당신은 단지 돌아올 수 없습니다
입력이 무엇이든.
compress
데이터 항목을 적합한 형식으로 변환합니다 토토 결과 페이지의 물리적 저장.
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
반대compress
메소드. 토토 결과를 변환합니다
데이터 항목을 할 수있는 형식으로 표현
데이터베이스에 의해 조작.
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에 삽입하는 것
나무의 특정 가지. 항목이 아래로 삽입됩니다
최소한의 경로18899_18908
in
나무. 값페널티
는 음성이 없어야합니다. 경우 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_range *v1 = pg_getarg_prefix_range_p (0); prefix_range *v2 = pg_getarg_prefix_range_p (1); bool *result = (bool *) pg_getarg_pointer (2); *결과 = my_eq (v1, v2); pg_return_pointer (결과);
역사적 이유로동일
함수는 a를 반환하지 않습니다
부울 결과; 대신 깃발을 보관해야합니다
세 번째 인수로 표시된 위치