PostgreSQL Source Code: src/backend/utils/adt/tsgistidx.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
24#include "utils/fmgrprotos.h"
26
27
28
29typedef struct
30{
34
35#define SIGLEN_DEFAULT (31 * 4)
36#define SIGLEN_MAX GISTMaxIndexKeySize
37#define GET_SIGLEN() (PG_HAS_OPCLASS_OPTIONS() ? \
38 ((GistTsVectorOptions *) PG_GET_OPCLASS_OPTIONS())->siglen : \
39 SIGLEN_DEFAULT)
40
41#define SIGLENBIT(siglen) ((siglen) * BITS_PER_BYTE)
42
44
45#define LOOPBYTE(siglen) \
46 for (i = 0; i < siglen; i++)
47
48#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
49#define GETBITBYTE(x,i) ( ((char)(x)) >> (i) & 0x01 )
50#define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )
51#define SETBIT(x,i) GETBYTE(x,i) |= ( 0x01 << ( (i) % BITS_PER_BYTE ) )
52#define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )
53
54#define HASHVAL(val, siglen) (((unsigned int)(val)) % SIGLENBIT(siglen))
55#define HASH(sign, val, siglen) SETBIT((sign), HASHVAL(val, siglen))
56
57#define GETENTRY(vec,pos) ((SignTSVector *) DatumGetPointer((vec)->vector[(pos)].key))
58
59
60
61
62
63typedef struct
64{
69
70#define ARRKEY 0x01
71#define SIGNKEY 0x02
72#define ALLISTRUE 0x04
73
74#define ISARRKEY(x) ( ((SignTSVector*)(x))->flag & ARRKEY )
75#define ISSIGNKEY(x) ( ((SignTSVector*)(x))->flag & SIGNKEY )
76#define ISALLTRUE(x) ( ((SignTSVector*)(x))->flag & ALLISTRUE )
77
78#define GTHDRSIZE ( VARHDRSZ + sizeof(int32) )
79#define CALCGTSIZE(flag, len) ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int32)) : (((flag) & ALLISTRUE) ? 0 : (len)) ) )
80
81#define GETSIGN(x) ( (BITVECP)( (char*)(x)+GTHDRSIZE ) )
82#define GETSIGLEN(x)( VARSIZE(x) - GTHDRSIZE )
83#define GETARR(x) ( (int32*)( (char*)(x)+GTHDRSIZE ) )
84#define ARRNELEM(x) ( ( VARSIZE(x) - GTHDRSIZE )/sizeof(int32) )
85
87
90{
91
93 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
94 errmsg("cannot accept a value of type %s", "gtsvector")));
95
97}
98
101{
103 char *outbuf;
104
107 else
108 {
110 outbuf = pstrdup("all true bits");
111 else
112 {
115
116 outbuf = psprintf("%d true bits, %d false bits",
117 cnttrue, (int) SIGLENBIT(siglen) - cnttrue);
118 }
119 }
120
123}
124
125static int
127{
130
132}
133
134static void
136{
140
142 for (k = 0; k < len; k++)
144}
145
148{
151
154
157
158 return res;
159}
160
161
164{
168
170 {
177
180 while (len--)
181 {
183
187
189 arr++;
190 ptr++;
191 }
192
196 {
197
198
199
200
204 }
205
206
208 {
210
212 res = ressign;
213 }
214
218 entry->offset, false);
219 }
222 {
226
228 {
229 if ((sign[i] & 0xff) != 0xff)
231 }
232
237 entry->offset, false);
238 }
240}
241
244{
245
246
247
248
251
253 {
255
258 entry->offset, false);
259
261 }
262
264}
265
266typedef struct
267{
271
272
273
274
277{
278 int32 *StopLow = ((CHKVAL *) checkval)->arrb;
279 int32 *StopHigh = ((CHKVAL *) checkval)->arre;
280 int32 *StopMiddle;
281
282
283
284
285
286
287 if (val->prefix)
289
290 while (StopLow < StopHigh)
291 {
292 StopMiddle = StopLow + (StopHigh - StopLow) / 2;
293 if (*StopMiddle == val->valcrc)
295 else if (*StopMiddle < val->valcrc)
296 StopLow = StopMiddle + 1;
297 else
298 StopHigh = StopMiddle;
299 }
300
302}
303
304
305
306
309{
311
312
313
314
315 if (val->prefix)
317
320 else
322}
323
326{
329
330
331
334
335
336 *recheck = true;
337
338 if (!query->size)
340
342 {
345
350 }
351 else
352 {
354
358 &chkval,
361 }
362}
363
366{
368
370 {
372
374 return 1;
375
377
380 }
381 else
382 {
384
386 HASH(sbase, ptr[i], siglen);
387 }
388 return 0;
389}
390
391
394{
401
402 memset(base, 0, siglen);
403
404 for (i = 0; i < entryvec->n; i++)
405 {
407 {
410 break;
411 }
412 }
413
415
417}
418
421{
426
428 {
430 *result = true;
432 *result = false;
434 *result = false;
435 else
436 {
440
442
443 *result = true;
445 {
447 {
448 *result = false;
449 break;
450 }
451 }
452 }
453 }
454 else
455 {
458
459 if (lena != lenb)
460 *result = false;
461 else
462 {
466
467 *result = true;
468 for (i = 0; i < lena; i++)
470 {
471 *result = false;
472 break;
473 }
474 }
475 }
476
478}
479
482{
484}
485
486static int
488{
489 int i,
490 diff,
491 dist = 0;
492
494 {
495 diff = (unsigned char) (a[i] ^ b[i]);
496
498 }
499 return dist;
500}
501
502static int
504{
507
509 {
511 return 0;
512 else
514 }
517
518 Assert(siglena == siglenb);
519
521}
522
525{
533
534 *penalty = 0.0;
535
537 {
539
541
543 {
544 int siglenbit = SIGLENBIT(siglen);
545
546 *penalty =
548 (float) (siglenbit + 1);
549 }
550 else
552
554 }
555 else
558}
559
560typedef struct
561{
562 bool allistrue;
565
566static void
568{
574 else
576}
577
578#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
579typedef struct
580{
584
585static int
587{
590
592}
593
594
595static int
597{
598 if (a->allistrue)
599 {
600 if (b->allistrue)
601 return 0;
602 else
604 }
605 else if (b->allistrue)
607
609}
610
613{
618 j;
620 *datum_r;
622 union_r;
623 int32 size_alpha,
624 size_beta;
625 int32 size_waste,
626 waste = -1;
629 seed_2 = 0;
631 *right;
634 int i;
636 char *cache_sign;
638
639 maxoff = entryvec->n - 2;
640 nbytes = (maxoff + 2) * sizeof(OffsetNumber);
643
645 cache_sign = palloc(siglen * (maxoff + 2));
646
647 for (j = 0; j < maxoff + 2; j++)
648 cache[j].sign = &cache_sign[siglen * j];
649
651 siglen);
652
654 {
656 {
659
660 size_waste = hemdistcache(&(cache[j]), &(cache[k]), siglen);
661 if (size_waste > waste)
662 {
663 waste = size_waste;
664 seed_1 = k;
665 seed_2 = j;
666 }
667 }
668 }
669
674
675 if (seed_1 == 0 || seed_2 == 0)
676 {
677 seed_1 = 1;
678 seed_2 = 2;
679 }
680
681
683 siglen, cache[seed_1].sign);
685 siglen, cache[seed_2].sign);
686 union_l = GETSIGN(datum_l);
687 union_r = GETSIGN(datum_r);
690
693 {
694 costvector[j - 1].pos = j;
695 size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]), siglen);
696 size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
697 costvector[j - 1].cost = abs(size_alpha - size_beta);
698 }
700
701 for (k = 0; k < maxoff; k++)
702 {
704 if (j == seed_1)
705 {
706 *left++ = j;
708 continue;
709 }
710 else if (j == seed_2)
711 {
712 *right++ = j;
714 continue;
715 }
716
717 if (ISALLTRUE(datum_l) || cache[j].allistrue)
718 {
719 if (ISALLTRUE(datum_l) && cache[j].allistrue)
720 size_alpha = 0;
721 else
726 siglen);
727 }
728 else
730
731 if (ISALLTRUE(datum_r) || cache[j].allistrue)
732 {
733 if (ISALLTRUE(datum_r) && cache[j].allistrue)
734 size_beta = 0;
735 else
740 siglen);
741 }
742 else
744
746 {
747 if (ISALLTRUE(datum_l) || cache[j].allistrue)
748 {
750 memset(GETSIGN(datum_l), 0xff, siglen);
751 }
752 else
753 {
757 }
758 *left++ = j;
760 }
761 else
762 {
763 if (ISALLTRUE(datum_r) || cache[j].allistrue)
764 {
766 memset(GETSIGN(datum_r), 0xff, siglen);
767 }
768 else
769 {
773 }
774 *right++ = j;
776 }
777 }
778
782
784}
785
786
787
788
789
790
791
792
795{
797}
798
801{
803
808
810}
#define FLEXIBLE_ARRAY_MEMBER
#define MemSet(start, val, len)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_FREE_IF_COPY(ptr, n)
#define PG_GETARG_POINTER(n)
#define PG_GETARG_DATUM(n)
#define PG_DETOAST_DATUM(datum)
#define PG_RETURN_POINTER(x)
#define PG_RETURN_BOOL(x)
#define gistentryinit(e, k, r, pg, o, l)
Assert(PointerIsAligned(start, uint64))
#define TOAST_INDEX_TARGET
static int pg_cmp_s32(int32 a, int32 b)
char * pstrdup(const char *in)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
PGDLLIMPORT const uint8 pg_number_of_ones[256]
static uint64 pg_popcount(const char *buf, int bytes)
#define INIT_LEGACY_CRC32(crc)
#define COMP_LEGACY_CRC32(crc, data, len)
#define FIN_LEGACY_CRC32(crc)
#define qsort(a, b, c, d)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
char * psprintf(const char *fmt,...)
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
void init_local_reloptions(local_relopts *relopts, Size relopt_struct_size)
void add_local_int_reloption(local_relopts *relopts, const char *name, const char *desc, int default_val, int min_val, int max_val, int offset)
static TSVector DatumGetTSVector(Datum X)
#define PG_GETARG_TSQUERY(n)
#define TS_EXEC_PHRASE_NO_POS
static int32 unionkey(BITVECP sbase, SignTSVector *add, int siglen)
#define HASHVAL(val, siglen)
static int hemdistcache(CACHESIGN *a, CACHESIGN *b, int siglen)
Datum gtsvector_penalty(PG_FUNCTION_ARGS)
static int hemdist(SignTSVector *a, SignTSVector *b)
static TSTernaryValue checkcondition_arr(void *checkval, QueryOperand *val, ExecPhraseData *data)
static SignTSVector * gtsvector_alloc(int flag, int len, BITVECP sign)
static int32 sizebitvec(BITVECP sign, int siglen)
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Datum gtsvector_same(PG_FUNCTION_ARGS)
#define GETENTRY(vec, pos)
Datum gtsvector_picksplit(PG_FUNCTION_ARGS)
static void fillcache(CACHESIGN *item, SignTSVector *key, int siglen)
static int comparecost(const void *va, const void *vb)
Datum gtsvectorin(PG_FUNCTION_ARGS)
Datum gtsvector_compress(PG_FUNCTION_ARGS)
#define CALCGTSIZE(flag, len)
Datum gtsvector_decompress(PG_FUNCTION_ARGS)
Datum gtsvector_consistent(PG_FUNCTION_ARGS)
static void makesign(BITVECP sign, SignTSVector *a, int siglen)
Datum gtsvector_options(PG_FUNCTION_ARGS)
Datum gtsvector_union(PG_FUNCTION_ARGS)
Datum gtsvectorout(PG_FUNCTION_ARGS)
#define SIGLENBIT(siglen)
static int compareint(const void *va, const void *vb)
static TSTernaryValue checkcondition_bit(void *checkval, QueryOperand *val, ExecPhraseData *data)
#define HASH(sign, val, siglen)
Datum gtsvector_consistent_oldsig(PG_FUNCTION_ARGS)
bool TS_execute(QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond)
#define SET_VARSIZE(PTR, len)