PostgreSQL Source Code  git master
tsgistidx.c File Reference
#include "postgres.h"
#include "access/gist.h"
#include "access/heaptoast.h"
#include "access/reloptions.h"
#include "common/int.h"
#include "lib/qunique.h"
#include "port/pg_bitutils.h"
#include "tsearch/ts_utils.h"
#include "utils/fmgrprotos.h"
#include "utils/pg_crc.h"
Include dependency graph for tsgistidx.c:

Go to the source code of this file.

Data Structures

struct  GistTsVectorOptions
 
struct  SignTSVector
 
struct  CHKVAL
 
struct  CACHESIGN
 
struct  SPLITCOST
 

Macros

#define SIGLEN_DEFAULT   (31 * 4)
 
#define SIGLEN_MAX   GISTMaxIndexKeySize
 
#define GET_SIGLEN()
 
#define SIGLENBIT(siglen)   ((siglen) * BITS_PER_BYTE)
 
#define LOOPBYTE(siglen)    for (i = 0; i < siglen; i++)
 
#define GETBYTE(x, i)   ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
 
#define GETBITBYTE(x, i)   ( ((char)(x)) >> (i) & 0x01 )
 
#define CLRBIT(x, i)   GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )
 
#define SETBIT(x, i)   GETBYTE(x,i) |= ( 0x01 << ( (i) % BITS_PER_BYTE ) )
 
#define GETBIT(x, i)   ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )
 
#define HASHVAL(val, siglen)   (((unsigned int)(val)) % SIGLENBIT(siglen))
 
#define HASH(sign, val, siglen)   SETBIT((sign), HASHVAL(val, siglen))
 
#define GETENTRY(vec, pos)   ((SignTSVector *) DatumGetPointer((vec)->vector[(pos)].key))
 
#define ARRKEY   0x01
 
#define SIGNKEY   0x02
 
#define ALLISTRUE   0x04
 
#define ISARRKEY(x)   ( ((SignTSVector*)(x))->flag & ARRKEY )
 
#define ISSIGNKEY(x)   ( ((SignTSVector*)(x))->flag & SIGNKEY )
 
#define ISALLTRUE(x)   ( ((SignTSVector*)(x))->flag & ALLISTRUE )
 
#define GTHDRSIZE   ( VARHDRSZ + sizeof(int32) )
 
#define CALCGTSIZE(flag, len)   ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int32)) : (((flag) & ALLISTRUE) ? 0 : (len)) ) )
 
#define GETSIGN(x)   ( (BITVECP)( (char*)(x)+GTHDRSIZE ) )
 
#define GETSIGLEN(x)   ( VARSIZE(x) - GTHDRSIZE )
 
#define GETARR(x)   ( (int32*)( (char*)(x)+GTHDRSIZE ) )
 
#define ARRNELEM(x)   ( ( VARSIZE(x) - GTHDRSIZE )/sizeof(int32) )
 
#define SINGOUTSTR   "%d true bits, %d false bits"
 
#define ARROUTSTR   "%d unique words"
 
#define EXTRALEN   ( 2*13 )
 
#define WISH_F(a, b, c)   (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
 

Typedefs

typedef char * BITVECP
 

Functions

static int32 sizebitvec (BITVECP sign, int siglen)
 
Datum gtsvectorin (PG_FUNCTION_ARGS)
 
Datum gtsvectorout (PG_FUNCTION_ARGS)
 
static int compareint (const void *va, const void *vb)
 
static void makesign (BITVECP sign, SignTSVector *a, int siglen)
 
static SignTSVectorgtsvector_alloc (int flag, int len, BITVECP sign)
 
Datum gtsvector_compress (PG_FUNCTION_ARGS)
 
Datum gtsvector_decompress (PG_FUNCTION_ARGS)
 
static TSTernaryValue checkcondition_arr (void *checkval, QueryOperand *val, ExecPhraseData *data)
 
static TSTernaryValue checkcondition_bit (void *checkval, QueryOperand *val, ExecPhraseData *data)
 
Datum gtsvector_consistent (PG_FUNCTION_ARGS)
 
static int32 unionkey (BITVECP sbase, SignTSVector *add, int siglen)
 
Datum gtsvector_union (PG_FUNCTION_ARGS)
 
Datum gtsvector_same (PG_FUNCTION_ARGS)
 
static int hemdistsign (BITVECP a, BITVECP b, int siglen)
 
static int hemdist (SignTSVector *a, SignTSVector *b)
 
Datum gtsvector_penalty (PG_FUNCTION_ARGS)
 
static void fillcache (CACHESIGN *item, SignTSVector *key, int siglen)
 
static int comparecost (const void *va, const void *vb)
 
static int hemdistcache (CACHESIGN *a, CACHESIGN *b, int siglen)
 
Datum gtsvector_picksplit (PG_FUNCTION_ARGS)
 
Datum gtsvector_consistent_oldsig (PG_FUNCTION_ARGS)
 
Datum gtsvector_options (PG_FUNCTION_ARGS)
 

Variables

static int outbuf_maxlen = 0
 

Macro Definition Documentation

◆ ALLISTRUE

#define ALLISTRUE   0x04

Definition at line 72 of file tsgistidx.c.

◆ ARRKEY

#define ARRKEY   0x01

Definition at line 70 of file tsgistidx.c.

◆ ARRNELEM

#define ARRNELEM (   x)    ( ( VARSIZE(x) - GTHDRSIZE )/sizeof(int32) )

Definition at line 84 of file tsgistidx.c.

◆ ARROUTSTR

#define ARROUTSTR   "%d unique words"

Definition at line 100 of file tsgistidx.c.

◆ CALCGTSIZE

#define CALCGTSIZE (   flag,
  len 
)    ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int32)) : (((flag) & ALLISTRUE) ? 0 : (len)) ) )

Definition at line 79 of file tsgistidx.c.

◆ CLRBIT

#define CLRBIT (   x,
  i 
)    GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )

Definition at line 50 of file tsgistidx.c.

◆ EXTRALEN

#define EXTRALEN   ( 2*13 )

Definition at line 101 of file tsgistidx.c.

◆ GET_SIGLEN

#define GET_SIGLEN ( )
Value:
#define PG_GET_OPCLASS_OPTIONS()
Definition: fmgr.h:342
#define PG_HAS_OPCLASS_OPTIONS()
Definition: fmgr.h:341
#define SIGLEN_DEFAULT
Definition: tsgistidx.c:35

Definition at line 37 of file tsgistidx.c.

◆ GETARR

#define GETARR (   x)    ( (int32*)( (char*)(x)+GTHDRSIZE ) )

Definition at line 83 of file tsgistidx.c.

◆ GETBIT

#define GETBIT (   x,
  i 
)    ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )

Definition at line 52 of file tsgistidx.c.

◆ GETBITBYTE

#define GETBITBYTE (   x,
  i 
)    ( ((char)(x)) >> (i) & 0x01 )

Definition at line 49 of file tsgistidx.c.

◆ GETBYTE

#define GETBYTE (   x,
  i 
)    ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )

Definition at line 48 of file tsgistidx.c.

◆ GETENTRY

#define GETENTRY (   vec,
  pos 
)    ((SignTSVector *) DatumGetPointer((vec)->vector[(pos)].key))

Definition at line 57 of file tsgistidx.c.

◆ GETSIGLEN

#define GETSIGLEN (   x)    ( VARSIZE(x) - GTHDRSIZE )

Definition at line 82 of file tsgistidx.c.

◆ GETSIGN

#define GETSIGN (   x)    ( (BITVECP)( (char*)(x)+GTHDRSIZE ) )

Definition at line 81 of file tsgistidx.c.

◆ GTHDRSIZE

#define GTHDRSIZE   ( VARHDRSZ + sizeof(int32) )

Definition at line 78 of file tsgistidx.c.

◆ HASH

#define HASH (   sign,
  val,
  siglen 
)    SETBIT((sign), HASHVAL(val, siglen))

Definition at line 55 of file tsgistidx.c.

◆ HASHVAL

#define HASHVAL (   val,
  siglen 
)    (((unsigned int)(val)) % SIGLENBIT(siglen))

Definition at line 54 of file tsgistidx.c.

◆ ISALLTRUE

#define ISALLTRUE (   x)    ( ((SignTSVector*)(x))->flag & ALLISTRUE )

Definition at line 76 of file tsgistidx.c.

◆ ISARRKEY

#define ISARRKEY (   x)    ( ((SignTSVector*)(x))->flag & ARRKEY )

Definition at line 74 of file tsgistidx.c.

◆ ISSIGNKEY

#define ISSIGNKEY (   x)    ( ((SignTSVector*)(x))->flag & SIGNKEY )

Definition at line 75 of file tsgistidx.c.

◆ LOOPBYTE

#define LOOPBYTE (   siglen)     for (i = 0; i < siglen; i++)

Definition at line 45 of file tsgistidx.c.

◆ SETBIT

#define SETBIT (   x,
  i 
)    GETBYTE(x,i) |= ( 0x01 << ( (i) % BITS_PER_BYTE ) )

Definition at line 51 of file tsgistidx.c.

◆ SIGLEN_DEFAULT

#define SIGLEN_DEFAULT   (31 * 4)

Definition at line 35 of file tsgistidx.c.

◆ SIGLEN_MAX

#define SIGLEN_MAX   GISTMaxIndexKeySize

Definition at line 36 of file tsgistidx.c.

◆ SIGLENBIT

#define SIGLENBIT (   siglen)    ((siglen) * BITS_PER_BYTE)

Definition at line 41 of file tsgistidx.c.

◆ SIGNKEY

#define SIGNKEY   0x02

Definition at line 71 of file tsgistidx.c.

◆ SINGOUTSTR

#define SINGOUTSTR   "%d true bits, %d false bits"

Definition at line 99 of file tsgistidx.c.

◆ WISH_F

#define WISH_F (   a,
  b,
  c 
)    (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )

Definition at line 587 of file tsgistidx.c.

Typedef Documentation

◆ BITVECP

typedef char* BITVECP

Definition at line 43 of file tsgistidx.c.

Function Documentation

◆ checkcondition_arr()

static TSTernaryValue checkcondition_arr ( void *  checkval,
QueryOperand val,
ExecPhraseData data 
)
static

Definition at line 285 of file tsgistidx.c.

286 {
287  int32 *StopLow = ((CHKVAL *) checkval)->arrb;
288  int32 *StopHigh = ((CHKVAL *) checkval)->arre;
289  int32 *StopMiddle;
290 
291  /* Loop invariant: StopLow <= val < StopHigh */
292 
293  /*
294  * we are not able to find a prefix by hash value
295  */
296  if (val->prefix)
297  return TS_MAYBE;
298 
299  while (StopLow < StopHigh)
300  {
301  StopMiddle = StopLow + (StopHigh - StopLow) / 2;
302  if (*StopMiddle == val->valcrc)
303  return TS_MAYBE;
304  else if (*StopMiddle < val->valcrc)
305  StopLow = StopMiddle + 1;
306  else
307  StopHigh = StopMiddle;
308  }
309 
310  return TS_NO;
311 }
signed int int32
Definition: c.h:494
long val
Definition: informix.c:670
@ TS_MAYBE
Definition: ts_utils.h:136
@ TS_NO
Definition: ts_utils.h:134

References TS_MAYBE, TS_NO, and val.

Referenced by gtsvector_consistent().

◆ checkcondition_bit()

static TSTernaryValue checkcondition_bit ( void *  checkval,
QueryOperand val,
ExecPhraseData data 
)
static

Definition at line 317 of file tsgistidx.c.

318 {
319  void *key = (SignTSVector *) checkval;
320 
321  /*
322  * we are not able to find a prefix in signature tree
323  */
324  if (val->prefix)
325  return TS_MAYBE;
326 
327  if (GETBIT(GETSIGN(key), HASHVAL(val->valcrc, GETSIGLEN(key))))
328  return TS_MAYBE;
329  else
330  return TS_NO;
331 }
#define HASHVAL(val, siglen)
Definition: tsgistidx.c:54
#define GETBIT(x, i)
Definition: tsgistidx.c:52
#define GETSIGLEN(x)
Definition: tsgistidx.c:82
#define GETSIGN(x)
Definition: tsgistidx.c:81

References GETBIT, GETSIGLEN, GETSIGN, HASHVAL, sort-test::key, TS_MAYBE, TS_NO, and val.

Referenced by gtsvector_consistent().

◆ comparecost()

static int comparecost ( const void *  va,
const void *  vb 
)
static

Definition at line 595 of file tsgistidx.c.

596 {
597  const SPLITCOST *a = (const SPLITCOST *) va;
598  const SPLITCOST *b = (const SPLITCOST *) vb;
599 
600  return pg_cmp_s32(a->cost, b->cost);
601 }
static int pg_cmp_s32(int32 a, int32 b)
Definition: int.h:483
int b
Definition: isn.c:70
int a
Definition: isn.c:69

References a, b, and pg_cmp_s32().

Referenced by gtsvector_picksplit().

◆ compareint()

static int compareint ( const void *  va,
const void *  vb 
)
static

Definition at line 135 of file tsgistidx.c.

136 {
137  int32 a = *((const int32 *) va);
138  int32 b = *((const int32 *) vb);
139 
140  return pg_cmp_s32(a, b);
141 }

References a, b, and pg_cmp_s32().

Referenced by gtsvector_compress().

◆ fillcache()

static void fillcache ( CACHESIGN item,
SignTSVector key,
int  siglen 
)
static

Definition at line 576 of file tsgistidx.c.

577 {
578  item->allistrue = false;
579  if (ISARRKEY(key))
580  makesign(item->sign, key, siglen);
581  else if (ISALLTRUE(key))
582  item->allistrue = true;
583  else
584  memcpy(item->sign, GETSIGN(key), siglen);
585 }
BITVECP sign
Definition: trgm_gist.c:745
bool allistrue
Definition: trgm_gist.c:744
#define ISARRKEY(x)
Definition: tsgistidx.c:74
#define ISALLTRUE(x)
Definition: tsgistidx.c:76
static void makesign(BITVECP sign, SignTSVector *a, int siglen)
Definition: tsgistidx.c:144

References CACHESIGN::allistrue, GETSIGN, ISALLTRUE, ISARRKEY, sort-test::key, makesign(), and CACHESIGN::sign.

Referenced by gtsvector_picksplit().

◆ gtsvector_alloc()

static SignTSVector* gtsvector_alloc ( int  flag,
int  len,
BITVECP  sign 
)
static

Definition at line 156 of file tsgistidx.c.

157 {
158  int size = CALCGTSIZE(flag, len);
160 
161  SET_VARSIZE(res, size);
162  res->flag = flag;
163 
164  if ((flag & (SIGNKEY | ALLISTRUE)) == SIGNKEY && sign)
165  memcpy(GETSIGN(res), sign, len);
166 
167  return res;
168 }
char sign
Definition: informix.c:674
void * palloc(Size size)
Definition: mcxt.c:1316
const void size_t len
static pg_noinline void Size size
Definition: slab.c:607
char * flag(int b)
Definition: test-ctype.c:33
#define ALLISTRUE
Definition: tsgistidx.c:72
#define CALCGTSIZE(flag, len)
Definition: tsgistidx.c:79
#define SIGNKEY
Definition: tsgistidx.c:71
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References ALLISTRUE, CALCGTSIZE, flag(), GETSIGN, len, palloc(), res, SET_VARSIZE, sign, SIGNKEY, and size.

Referenced by gtsvector_compress(), gtsvector_picksplit(), and gtsvector_union().

◆ gtsvector_compress()

Datum gtsvector_compress ( PG_FUNCTION_ARGS  )

Definition at line 172 of file tsgistidx.c.

173 {
174  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
175  int siglen = GET_SIGLEN();
176  GISTENTRY *retval = entry;
177 
178  if (entry->leafkey)
179  { /* tsvector */
180  TSVector val = DatumGetTSVector(entry->key);
181  SignTSVector *res = gtsvector_alloc(ARRKEY, val->size, NULL);
182  int32 len;
183  int32 *arr;
184  WordEntry *ptr = ARRPTR(val);
185  char *words = STRPTR(val);
186 
187  arr = GETARR(res);
188  len = val->size;
189  while (len--)
190  {
191  pg_crc32 c;
192 
194  COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len);
196 
197  *arr = *(int32 *) &c;
198  arr++;
199  ptr++;
200  }
201 
202  qsort(GETARR(res), val->size, sizeof(int), compareint);
203  len = qunique(GETARR(res), val->size, sizeof(int), compareint);
204  if (len != val->size)
205  {
206  /*
207  * there is a collision of hash-function; len is always less than
208  * val->size
209  */
210  len = CALCGTSIZE(ARRKEY, len);
211  res = (SignTSVector *) repalloc(res, len);
212  SET_VARSIZE(res, len);
213  }
214 
215  /* make signature, if array is too long */
217  {
218  SignTSVector *ressign = gtsvector_alloc(SIGNKEY, siglen, NULL);
219 
220  makesign(GETSIGN(ressign), res, siglen);
221  res = ressign;
222  }
223 
224  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
226  entry->rel, entry->page,
227  entry->offset, false);
228  }
229  else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
230  !ISALLTRUE(DatumGetPointer(entry->key)))
231  {
232  int32 i;
233  SignTSVector *res;
235 
236  LOOPBYTE(siglen)
237  {
238  if ((sign[i] & 0xff) != 0xff)
239  PG_RETURN_POINTER(retval);
240  }
241 
242  res = gtsvector_alloc(SIGNKEY | ALLISTRUE, siglen, sign);
243  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
245  entry->rel, entry->page,
246  entry->offset, false);
247  }
248  PG_RETURN_POINTER(retval);
249 }
#define ARRPTR(x)
Definition: cube.c:25
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:244
#define TOAST_INDEX_TARGET
Definition: heaptoast.h:68
#define STRPTR(x)
Definition: hstore.h:76
char * BITVECP
Definition: hstore_gist.c:31
int i
Definition: isn.c:73
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1540
uint32 pg_crc32
Definition: pg_crc.h:37
#define INIT_LEGACY_CRC32(crc)
Definition: pg_crc.h:79
#define COMP_LEGACY_CRC32(crc, data, len)
Definition: pg_crc.h:81
#define FIN_LEGACY_CRC32(crc)
Definition: pg_crc.h:80
#define qsort(a, b, c, d)
Definition: port.h:449
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
char * c
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21
OffsetNumber offset
Definition: gist.h:163
Datum key
Definition: gist.h:160
Page page
Definition: gist.h:162
Relation rel
Definition: gist.h:161
bool leafkey
Definition: gist.h:164
uint32 pos
Definition: ts_type.h:46
uint32 len
Definition: ts_type.h:45
static TSVector DatumGetTSVector(Datum X)
Definition: ts_type.h:118
#define LOOPBYTE(siglen)
Definition: tsgistidx.c:45
static SignTSVector * gtsvector_alloc(int flag, int len, BITVECP sign)
Definition: tsgistidx.c:156
#define GET_SIGLEN()
Definition: tsgistidx.c:37
#define ISSIGNKEY(x)
Definition: tsgistidx.c:75
#define GETARR(x)
Definition: tsgistidx.c:83
static int compareint(const void *va, const void *vb)
Definition: tsgistidx.c:135
#define ARRKEY
Definition: tsgistidx.c:70
#define VARSIZE(PTR)
Definition: varatt.h:279

References ALLISTRUE, ARRKEY, ARRPTR, CALCGTSIZE, COMP_LEGACY_CRC32, compareint(), DatumGetPointer(), DatumGetTSVector(), FIN_LEGACY_CRC32, GET_SIGLEN, GETARR, GETSIGN, gistentryinit, gtsvector_alloc(), i, INIT_LEGACY_CRC32, ISALLTRUE, ISSIGNKEY, GISTENTRY::key, GISTENTRY::leafkey, WordEntry::len, len, LOOPBYTE, makesign(), GISTENTRY::offset, GISTENTRY::page, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), WordEntry::pos, qsort, qunique(), GISTENTRY::rel, repalloc(), res, SET_VARSIZE, sign, SIGNKEY, STRPTR, TOAST_INDEX_TARGET, val, and VARSIZE.

◆ gtsvector_consistent()

Datum gtsvector_consistent ( PG_FUNCTION_ARGS  )

Definition at line 334 of file tsgistidx.c.

335 {
336  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
337  TSQuery query = PG_GETARG_TSQUERY(1);
338 
339  /* StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); */
340  /* Oid subtype = PG_GETARG_OID(3); */
341  bool *recheck = (bool *) PG_GETARG_POINTER(4);
343 
344  /* All cases served by this function are inexact */
345  *recheck = true;
346 
347  if (!query->size)
348  PG_RETURN_BOOL(false);
349 
350  if (ISSIGNKEY(key))
351  {
352  if (ISALLTRUE(key))
353  PG_RETURN_BOOL(true);
354 
356  key,
359  }
360  else
361  { /* only leaf pages */
362  CHKVAL chkval;
363 
364  chkval.arrb = GETARR(key);
365  chkval.arre = chkval.arrb + ARRNELEM(key);
367  (void *) &chkval,
370  }
371 }
#define GETQUERY(x)
Definition: _int.h:157
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
int32 * arrb
Definition: _int_bool.c:226
int32 * arre
Definition: _int_bool.c:227
int32 size
Definition: ts_type.h:221
#define PG_GETARG_TSQUERY(n)
Definition: ts_type.h:266
#define TS_EXEC_PHRASE_NO_POS
Definition: ts_utils.h:202
static TSTernaryValue checkcondition_arr(void *checkval, QueryOperand *val, ExecPhraseData *data)
Definition: tsgistidx.c:285
#define ARRNELEM(x)
Definition: tsgistidx.c:84
static TSTernaryValue checkcondition_bit(void *checkval, QueryOperand *val, ExecPhraseData *data)
Definition: tsgistidx.c:317
bool TS_execute(QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond)
Definition: tsvector_op.c:1854

References CHKVAL::arrb, CHKVAL::arre, ARRNELEM, checkcondition_arr(), checkcondition_bit(), DatumGetPointer(), GETARR, GETQUERY, ISALLTRUE, ISSIGNKEY, GISTENTRY::key, sort-test::key, PG_GETARG_POINTER, PG_GETARG_TSQUERY, PG_RETURN_BOOL, TSQueryData::size, TS_EXEC_PHRASE_NO_POS, and TS_execute().

Referenced by gtsvector_consistent_oldsig().

◆ gtsvector_consistent_oldsig()

Datum gtsvector_consistent_oldsig ( PG_FUNCTION_ARGS  )

Definition at line 803 of file tsgistidx.c.

804 {
805  return gtsvector_consistent(fcinfo);
806 }
Datum gtsvector_consistent(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:334

References gtsvector_consistent().

◆ gtsvector_decompress()

Datum gtsvector_decompress ( PG_FUNCTION_ARGS  )

Definition at line 252 of file tsgistidx.c.

253 {
254  /*
255  * We need to detoast the stored value, because the other gtsvector
256  * support functions don't cope with toasted values.
257  */
258  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
260 
261  if (key != (SignTSVector *) DatumGetPointer(entry->key))
262  {
263  GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
264 
266  entry->rel, entry->page,
267  entry->offset, false);
268 
269  PG_RETURN_POINTER(retval);
270  }
271 
272  PG_RETURN_POINTER(entry);
273 }
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240

References DatumGetPointer(), gistentryinit, GISTENTRY::key, sort-test::key, GISTENTRY::offset, GISTENTRY::page, palloc(), PG_DETOAST_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), and GISTENTRY::rel.

◆ gtsvector_options()

Datum gtsvector_options ( PG_FUNCTION_ARGS  )

Definition at line 809 of file tsgistidx.c.

810 {
812 
813  init_local_reloptions(relopts, sizeof(GistTsVectorOptions));
814  add_local_int_reloption(relopts, "siglen", "signature length",
816  offsetof(GistTsVectorOptions, siglen));
817 
818  PG_RETURN_VOID();
819 }
#define PG_RETURN_VOID()
Definition: fmgr.h:349
void init_local_reloptions(local_relopts *relopts, Size relopt_struct_size)
Definition: reloptions.c:734
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)
Definition: reloptions.c:918
#define SIGLEN_MAX
Definition: tsgistidx.c:36

References add_local_int_reloption(), init_local_reloptions(), PG_GETARG_POINTER, PG_RETURN_VOID, SIGLEN_DEFAULT, and SIGLEN_MAX.

◆ gtsvector_penalty()

Datum gtsvector_penalty ( PG_FUNCTION_ARGS  )

Definition at line 533 of file tsgistidx.c.

534 {
535  GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
536  GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
537  float *penalty = (float *) PG_GETARG_POINTER(2);
538  int siglen = GET_SIGLEN();
539  SignTSVector *origval = (SignTSVector *) DatumGetPointer(origentry->key);
541  BITVECP orig = GETSIGN(origval);
542 
543  *penalty = 0.0;
544 
545  if (ISARRKEY(newval))
546  {
547  BITVECP sign = palloc(siglen);
548 
549  makesign(sign, newval, siglen);
550 
551  if (ISALLTRUE(origval))
552  {
553  int siglenbit = SIGLENBIT(siglen);
554 
555  *penalty =
556  (float) (siglenbit - sizebitvec(sign, siglen)) /
557  (float) (siglenbit + 1);
558  }
559  else
560  *penalty = hemdistsign(sign, orig, siglen);
561 
562  pfree(sign);
563  }
564  else
565  *penalty = hemdist(origval, newval);
566  PG_RETURN_POINTER(penalty);
567 }
#define newval
void pfree(void *pointer)
Definition: mcxt.c:1520
static int hemdist(SignTSVector *a, SignTSVector *b)
Definition: tsgistidx.c:512
static int32 sizebitvec(BITVECP sign, int siglen)
Definition: tsgistidx.c:490
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Definition: tsgistidx.c:496
#define SIGLENBIT(siglen)
Definition: tsgistidx.c:41

References DatumGetPointer(), GET_SIGLEN, GETSIGN, hemdist(), hemdistsign(), ISALLTRUE, ISARRKEY, GISTENTRY::key, makesign(), newval, palloc(), pfree(), PG_GETARG_POINTER, PG_RETURN_POINTER, SIGLENBIT, sign, and sizebitvec().

◆ gtsvector_picksplit()

Datum gtsvector_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 621 of file tsgistidx.c.

622 {
625  int siglen = GET_SIGLEN();
626  OffsetNumber k,
627  j;
628  SignTSVector *datum_l,
629  *datum_r;
630  BITVECP union_l,
631  union_r;
632  int32 size_alpha,
633  size_beta;
634  int32 size_waste,
635  waste = -1;
636  int32 nbytes;
637  OffsetNumber seed_1 = 0,
638  seed_2 = 0;
639  OffsetNumber *left,
640  *right;
641  OffsetNumber maxoff;
642  BITVECP ptr;
643  int i;
644  CACHESIGN *cache;
645  char *cache_sign;
646  SPLITCOST *costvector;
647 
648  maxoff = entryvec->n - 2;
649  nbytes = (maxoff + 2) * sizeof(OffsetNumber);
650  v->spl_left = (OffsetNumber *) palloc(nbytes);
651  v->spl_right = (OffsetNumber *) palloc(nbytes);
652 
653  cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2));
654  cache_sign = palloc(siglen * (maxoff + 2));
655 
656  for (j = 0; j < maxoff + 2; j++)
657  cache[j].sign = &cache_sign[siglen * j];
658 
660  siglen);
661 
662  for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
663  {
664  for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
665  {
666  if (k == FirstOffsetNumber)
667  fillcache(&cache[j], GETENTRY(entryvec, j), siglen);
668 
669  size_waste = hemdistcache(&(cache[j]), &(cache[k]), siglen);
670  if (size_waste > waste)
671  {
672  waste = size_waste;
673  seed_1 = k;
674  seed_2 = j;
675  }
676  }
677  }
678 
679  left = v->spl_left;
680  v->spl_nleft = 0;
681  right = v->spl_right;
682  v->spl_nright = 0;
683 
684  if (seed_1 == 0 || seed_2 == 0)
685  {
686  seed_1 = 1;
687  seed_2 = 2;
688  }
689 
690  /* form initial .. */
691  datum_l = gtsvector_alloc(SIGNKEY | (cache[seed_1].allistrue ? ALLISTRUE : 0),
692  siglen, cache[seed_1].sign);
693  datum_r = gtsvector_alloc(SIGNKEY | (cache[seed_2].allistrue ? ALLISTRUE : 0),
694  siglen, cache[seed_2].sign);
695  union_l = GETSIGN(datum_l);
696  union_r = GETSIGN(datum_r);
697  maxoff = OffsetNumberNext(maxoff);
698  fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff), siglen);
699  /* sort before ... */
700  costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
701  for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
702  {
703  costvector[j - 1].pos = j;
704  size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]), siglen);
705  size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
706  costvector[j - 1].cost = abs(size_alpha - size_beta);
707  }
708  qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
709 
710  for (k = 0; k < maxoff; k++)
711  {
712  j = costvector[k].pos;
713  if (j == seed_1)
714  {
715  *left++ = j;
716  v->spl_nleft++;
717  continue;
718  }
719  else if (j == seed_2)
720  {
721  *right++ = j;
722  v->spl_nright++;
723  continue;
724  }
725 
726  if (ISALLTRUE(datum_l) || cache[j].allistrue)
727  {
728  if (ISALLTRUE(datum_l) && cache[j].allistrue)
729  size_alpha = 0;
730  else
731  size_alpha = SIGLENBIT(siglen) -
732  sizebitvec((cache[j].allistrue) ?
733  GETSIGN(datum_l) :
734  cache[j].sign,
735  siglen);
736  }
737  else
738  size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l), siglen);
739 
740  if (ISALLTRUE(datum_r) || cache[j].allistrue)
741  {
742  if (ISALLTRUE(datum_r) && cache[j].allistrue)
743  size_beta = 0;
744  else
745  size_beta = SIGLENBIT(siglen) -
746  sizebitvec((cache[j].allistrue) ?
747  GETSIGN(datum_r) :
748  cache[j].sign,
749  siglen);
750  }
751  else
752  size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r), siglen);
753 
754  if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
755  {
756  if (ISALLTRUE(datum_l) || cache[j].allistrue)
757  {
758  if (!ISALLTRUE(datum_l))
759  memset(GETSIGN(datum_l), 0xff, siglen);
760  }
761  else
762  {
763  ptr = cache[j].sign;
764  LOOPBYTE(siglen)
765  union_l[i] |= ptr[i];
766  }
767  *left++ = j;
768  v->spl_nleft++;
769  }
770  else
771  {
772  if (ISALLTRUE(datum_r) || cache[j].allistrue)
773  {
774  if (!ISALLTRUE(datum_r))
775  memset(GETSIGN(datum_r), 0xff, siglen);
776  }
777  else
778  {
779  ptr = cache[j].sign;
780  LOOPBYTE(siglen)
781  union_r[i] |= ptr[i];
782  }
783  *right++ = j;
784  v->spl_nright++;
785  }
786  }
787 
788  *right = *left = FirstOffsetNumber;
789  v->spl_ldatum = PointerGetDatum(datum_l);
790  v->spl_rdatum = PointerGetDatum(datum_r);
791 
793 }
int j
Definition: isn.c:74
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
int spl_nleft
Definition: gist.h:143
OffsetNumber * spl_right
Definition: gist.h:147
Datum spl_ldatum
Definition: gist.h:144
Datum spl_rdatum
Definition: gist.h:149
int spl_nright
Definition: gist.h:148
OffsetNumber * spl_left
Definition: gist.h:142
int32 n
Definition: gist.h:235
int32 cost
Definition: hstore_gist.c:354
OffsetNumber pos
Definition: hstore_gist.c:353
static int hemdistcache(CACHESIGN *a, CACHESIGN *b, int siglen)
Definition: tsgistidx.c:605
#define WISH_F(a, b, c)
Definition: tsgistidx.c:587
#define GETENTRY(vec, pos)
Definition: tsgistidx.c:57
static void fillcache(CACHESIGN *item, SignTSVector *key, int siglen)
Definition: tsgistidx.c:576
static int comparecost(const void *va, const void *vb)
Definition: tsgistidx.c:595

References ALLISTRUE, comparecost(), SPLITCOST::cost, fillcache(), FirstOffsetNumber, GET_SIGLEN, GETENTRY, GETSIGN, gtsvector_alloc(), hemdistcache(), hemdistsign(), i, ISALLTRUE, j, LOOPBYTE, GistEntryVector::n, OffsetNumberNext, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), SPLITCOST::pos, qsort, SIGLENBIT, CACHESIGN::sign, sign, SIGNKEY, sizebitvec(), GIST_SPLITVEC::spl_ldatum, GIST_SPLITVEC::spl_left, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_rdatum, GIST_SPLITVEC::spl_right, and WISH_F.

◆ gtsvector_same()

Datum gtsvector_same ( PG_FUNCTION_ARGS  )

Definition at line 429 of file tsgistidx.c.

430 {
433  bool *result = (bool *) PG_GETARG_POINTER(2);
434  int siglen = GET_SIGLEN();
435 
436  if (ISSIGNKEY(a))
437  { /* then b also ISSIGNKEY */
438  if (ISALLTRUE(a) && ISALLTRUE(b))
439  *result = true;
440  else if (ISALLTRUE(a))
441  *result = false;
442  else if (ISALLTRUE(b))
443  *result = false;
444  else
445  {
446  int32 i;
447  BITVECP sa = GETSIGN(a),
448  sb = GETSIGN(b);
449 
450  Assert(GETSIGLEN(a) == siglen && GETSIGLEN(b) == siglen);
451 
452  *result = true;
453  LOOPBYTE(siglen)
454  {
455  if (sa[i] != sb[i])
456  {
457  *result = false;
458  break;
459  }
460  }
461  }
462  }
463  else
464  { /* a and b ISARRKEY */
465  int32 lena = ARRNELEM(a),
466  lenb = ARRNELEM(b);
467 
468  if (lena != lenb)
469  *result = false;
470  else
471  {
472  int32 *ptra = GETARR(a),
473  *ptrb = GETARR(b);
474  int32 i;
475 
476  *result = true;
477  for (i = 0; i < lena; i++)
478  if (ptra[i] != ptrb[i])
479  {
480  *result = false;
481  break;
482  }
483  }
484  }
485 
486  PG_RETURN_POINTER(result);
487 }
#define Assert(condition)
Definition: c.h:858

References a, ARRNELEM, Assert, b, GET_SIGLEN, GETARR, GETSIGLEN, GETSIGN, i, ISALLTRUE, ISSIGNKEY, LOOPBYTE, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ gtsvector_union()

Datum gtsvector_union ( PG_FUNCTION_ARGS  )

Definition at line 402 of file tsgistidx.c.

403 {
405  int *size = (int *) PG_GETARG_POINTER(1);
406  int siglen = GET_SIGLEN();
407  SignTSVector *result = gtsvector_alloc(SIGNKEY, siglen, NULL);
408  BITVECP base = GETSIGN(result);
409  int32 i;
410 
411  memset(base, 0, siglen);
412 
413  for (i = 0; i < entryvec->n; i++)
414  {
415  if (unionkey(base, GETENTRY(entryvec, i), siglen))
416  {
417  result->flag |= ALLISTRUE;
418  SET_VARSIZE(result, CALCGTSIZE(result->flag, siglen));
419  break;
420  }
421  }
422 
423  *size = VARSIZE(result);
424 
425  PG_RETURN_POINTER(result);
426 }
int32 flag
Definition: tsgistidx.c:66
static int32 unionkey(BITVECP sbase, SignTSVector *add, int siglen)
Definition: tsgistidx.c:374

References ALLISTRUE, CALCGTSIZE, SignTSVector::flag, GET_SIGLEN, GETENTRY, GETSIGN, gtsvector_alloc(), i, GistEntryVector::n, PG_GETARG_POINTER, PG_RETURN_POINTER, SET_VARSIZE, SIGNKEY, size, unionkey(), and VARSIZE.

◆ gtsvectorin()

Datum gtsvectorin ( PG_FUNCTION_ARGS  )

Definition at line 89 of file tsgistidx.c.

90 {
91  /* There's no need to support input of gtsvectors */
92  ereport(ERROR,
93  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
94  errmsg("cannot accept a value of type %s", "gtsvector")));
95 
96  PG_RETURN_VOID(); /* keep compiler quiet */
97 }
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149

References ereport, errcode(), errmsg(), ERROR, and PG_RETURN_VOID.

◆ gtsvectorout()

Datum gtsvectorout ( PG_FUNCTION_ARGS  )

Definition at line 106 of file tsgistidx.c.

107 {
109  char *outbuf;
110 
111  if (outbuf_maxlen == 0)
112  outbuf_maxlen = 2 * EXTRALEN + Max(strlen(SINGOUTSTR), strlen(ARROUTSTR)) + 1;
113  outbuf = palloc(outbuf_maxlen);
114 
115  if (ISARRKEY(key))
116  sprintf(outbuf, ARROUTSTR, (int) ARRNELEM(key));
117  else
118  {
119  if (ISALLTRUE(key))
120  sprintf(outbuf, "all true bits");
121  else
122  {
123  int siglen = GETSIGLEN(key);
124  int cnttrue = sizebitvec(GETSIGN(key), siglen);
125 
126  sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT(siglen) - cnttrue);
127  }
128  }
129 
130  PG_FREE_IF_COPY(key, 0);
131  PG_RETURN_POINTER(outbuf);
132 }
#define Max(x, y)
Definition: c.h:998
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define sprintf
Definition: port.h:240
#define ARROUTSTR
Definition: tsgistidx.c:100
#define EXTRALEN
Definition: tsgistidx.c:101
static int outbuf_maxlen
Definition: tsgistidx.c:103
#define SINGOUTSTR
Definition: tsgistidx.c:99

References ARRNELEM, ARROUTSTR, EXTRALEN, GETSIGLEN, GETSIGN, ISALLTRUE, ISARRKEY, sort-test::key, Max, outbuf_maxlen, palloc(), PG_DETOAST_DATUM, PG_FREE_IF_COPY, PG_GETARG_DATUM, PG_RETURN_POINTER, SIGLENBIT, SINGOUTSTR, sizebitvec(), and sprintf.

◆ hemdist()

static int hemdist ( SignTSVector a,
SignTSVector b 
)
static

Definition at line 512 of file tsgistidx.c.

513 {
514  int siglena = GETSIGLEN(a);
515  int siglenb = GETSIGLEN(b);
516 
517  if (ISALLTRUE(a))
518  {
519  if (ISALLTRUE(b))
520  return 0;
521  else
522  return SIGLENBIT(siglenb) - sizebitvec(GETSIGN(b), siglenb);
523  }
524  else if (ISALLTRUE(b))
525  return SIGLENBIT(siglena) - sizebitvec(GETSIGN(a), siglena);
526 
527  Assert(siglena == siglenb);
528 
529  return hemdistsign(GETSIGN(a), GETSIGN(b), siglena);
530 }

References a, Assert, b, GETSIGLEN, GETSIGN, hemdistsign(), ISALLTRUE, SIGLENBIT, and sizebitvec().

Referenced by gtsvector_penalty().

◆ hemdistcache()

static int hemdistcache ( CACHESIGN a,
CACHESIGN b,
int  siglen 
)
static

Definition at line 605 of file tsgistidx.c.

606 {
607  if (a->allistrue)
608  {
609  if (b->allistrue)
610  return 0;
611  else
612  return SIGLENBIT(siglen) - sizebitvec(b->sign, siglen);
613  }
614  else if (b->allistrue)
615  return SIGLENBIT(siglen) - sizebitvec(a->sign, siglen);
616 
617  return hemdistsign(a->sign, b->sign, siglen);
618 }

References a, b, hemdistsign(), SIGLENBIT, and sizebitvec().

Referenced by gtsvector_picksplit().

◆ hemdistsign()

static int hemdistsign ( BITVECP  a,
BITVECP  b,
int  siglen 
)
static

Definition at line 496 of file tsgistidx.c.

497 {
498  int i,
499  diff,
500  dist = 0;
501 
502  LOOPBYTE(siglen)
503  {
504  diff = (unsigned char) (a[i] ^ b[i]);
505  /* Using the popcount functions here isn't likely to win */
506  dist += pg_number_of_ones[diff];
507  }
508  return dist;
509 }
PGDLLIMPORT const uint8 pg_number_of_ones[256]
Definition: pg_bitutils.c:87

References a, b, i, LOOPBYTE, and pg_number_of_ones.

Referenced by gtsvector_penalty(), gtsvector_picksplit(), hemdist(), and hemdistcache().

◆ makesign()

static void makesign ( BITVECP  sign,
SignTSVector a,
int  siglen 
)
static

Definition at line 144 of file tsgistidx.c.

145 {
146  int32 k,
147  len = ARRNELEM(a);
148  int32 *ptr = GETARR(a);
149 
150  MemSet(sign, 0, siglen);
151  for (k = 0; k < len; k++)
152  HASH(sign, ptr[k], siglen);
153 }
#define MemSet(start, val, len)
Definition: c.h:1020
#define HASH(sign, val, siglen)
Definition: tsgistidx.c:55

References a, ARRNELEM, GETARR, HASH, len, MemSet, and sign.

Referenced by fillcache(), gtsvector_compress(), and gtsvector_penalty().

◆ sizebitvec()

static int32 sizebitvec ( BITVECP  sign,
int  siglen 
)
static

Definition at line 490 of file tsgistidx.c.

491 {
492  return pg_popcount(sign, siglen);
493 }
static uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.h:339

References pg_popcount(), and sign.

Referenced by gtsvector_penalty(), gtsvector_picksplit(), gtsvectorout(), hemdist(), and hemdistcache().

◆ unionkey()

static int32 unionkey ( BITVECP  sbase,
SignTSVector add,
int  siglen 
)
static

Definition at line 374 of file tsgistidx.c.

375 {
376  int32 i;
377 
378  if (ISSIGNKEY(add))
379  {
380  BITVECP sadd = GETSIGN(add);
381 
382  if (ISALLTRUE(add))
383  return 1;
384 
385  Assert(GETSIGLEN(add) == siglen);
386 
387  LOOPBYTE(siglen)
388  sbase[i] |= sadd[i];
389  }
390  else
391  {
392  int32 *ptr = GETARR(add);
393 
394  for (i = 0; i < ARRNELEM(add); i++)
395  HASH(sbase, ptr[i], siglen);
396  }
397  return 0;
398 }

References ARRNELEM, Assert, GETARR, GETSIGLEN, GETSIGN, HASH, i, ISALLTRUE, ISSIGNKEY, and LOOPBYTE.

Referenced by gtsvector_union().

Variable Documentation

◆ outbuf_maxlen

int outbuf_maxlen = 0
static

Definition at line 103 of file tsgistidx.c.

Referenced by gtsvectorout().