PostgreSQL Source Code  git master
trgm_gist.c File Reference
#include "postgres.h"
#include "access/reloptions.h"
#include "access/stratnum.h"
#include "fmgr.h"
#include "port/pg_bitutils.h"
#include "trgm.h"
Include dependency graph for trgm_gist.c:

Go to the source code of this file.

Data Structures

struct  TrgmGistOptions
 
struct  gtrgm_consistent_cache
 
struct  CACHESIGN
 
struct  SPLITCOST
 

Macros

#define GET_SIGLEN()
 
#define GETENTRY(vec, pos)   ((TRGM *) DatumGetPointer((vec)->vector[(pos)].key))
 
#define WISH_F(a, b, c)   (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
 

Functions

 PG_FUNCTION_INFO_V1 (gtrgm_in)
 
 PG_FUNCTION_INFO_V1 (gtrgm_out)
 
 PG_FUNCTION_INFO_V1 (gtrgm_compress)
 
 PG_FUNCTION_INFO_V1 (gtrgm_decompress)
 
 PG_FUNCTION_INFO_V1 (gtrgm_consistent)
 
 PG_FUNCTION_INFO_V1 (gtrgm_distance)
 
 PG_FUNCTION_INFO_V1 (gtrgm_union)
 
 PG_FUNCTION_INFO_V1 (gtrgm_same)
 
 PG_FUNCTION_INFO_V1 (gtrgm_penalty)
 
 PG_FUNCTION_INFO_V1 (gtrgm_picksplit)
 
 PG_FUNCTION_INFO_V1 (gtrgm_options)
 
Datum gtrgm_in (PG_FUNCTION_ARGS)
 
Datum gtrgm_out (PG_FUNCTION_ARGS)
 
static TRGMgtrgm_alloc (bool isalltrue, int siglen, BITVECP sign)
 
static void makesign (BITVECP sign, TRGM *a, int siglen)
 
Datum gtrgm_compress (PG_FUNCTION_ARGS)
 
Datum gtrgm_decompress (PG_FUNCTION_ARGS)
 
static int32 cnt_sml_sign_common (TRGM *qtrg, BITVECP sign, int siglen)
 
Datum gtrgm_consistent (PG_FUNCTION_ARGS)
 
Datum gtrgm_distance (PG_FUNCTION_ARGS)
 
static int32 unionkey (BITVECP sbase, TRGM *add, int siglen)
 
Datum gtrgm_union (PG_FUNCTION_ARGS)
 
Datum gtrgm_same (PG_FUNCTION_ARGS)
 
static int32 sizebitvec (BITVECP sign, int siglen)
 
static int hemdistsign (BITVECP a, BITVECP b, int siglen)
 
static int hemdist (TRGM *a, TRGM *b, int siglen)
 
Datum gtrgm_penalty (PG_FUNCTION_ARGS)
 
static void fillcache (CACHESIGN *item, TRGM *key, BITVECP sign, int siglen)
 
static int comparecost (const void *a, const void *b)
 
static int hemdistcache (CACHESIGN *a, CACHESIGN *b, int siglen)
 
Datum gtrgm_picksplit (PG_FUNCTION_ARGS)
 
Datum gtrgm_options (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ GET_SIGLEN

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

Definition at line 19 of file trgm_gist.c.

Referenced by gtrgm_compress(), gtrgm_consistent(), gtrgm_distance(), gtrgm_penalty(), gtrgm_picksplit(), gtrgm_same(), and gtrgm_union().

◆ GETENTRY

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

Definition at line 39 of file trgm_gist.c.

Referenced by gtrgm_picksplit(), and gtrgm_union().

◆ WISH_F

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

Definition at line 754 of file trgm_gist.c.

Referenced by gtrgm_picksplit().

Function Documentation

◆ cnt_sml_sign_common()

static int32 cnt_sml_sign_common ( TRGM qtrg,
BITVECP  sign,
int  siglen 
)
static

Definition at line 172 of file trgm_gist.c.

References ARRNELEM, CPTRGM, GETARR, GETBIT, and HASHVAL.

Referenced by gtrgm_consistent(), and gtrgm_distance().

173 {
174  int32 count = 0;
175  int32 k,
176  len = ARRNELEM(qtrg);
177  trgm *ptr = GETARR(qtrg);
178  int32 tmp = 0;
179 
180  for (k = 0; k < len; k++)
181  {
182  CPTRGM(((char *) &tmp), ptr + k);
183  count += GETBIT(sign, HASHVAL(tmp, siglen));
184  }
185 
186  return count;
187 }
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:417
#define GETARR(x)
Definition: trgm.h:107
#define GETBIT(x, i)
Definition: blutils.c:33
char sign
Definition: informix.c:668
#define HASHVAL(val, siglen)
Definition: hstore_gist.c:44
char trgm[3]
Definition: trgm.h:42
#define CPTRGM(a, b)
Definition: trgm.h:48

◆ comparecost()

static int comparecost ( const void *  a,
const void *  b 
)
static

Definition at line 762 of file trgm_gist.c.

Referenced by gtrgm_picksplit().

763 {
764  if (((const SPLITCOST *) a)->cost == ((const SPLITCOST *) b)->cost)
765  return 0;
766  else
767  return (((const SPLITCOST *) a)->cost > ((const SPLITCOST *) b)->cost) ? 1 : -1;
768 }

◆ fillcache()

static void fillcache ( CACHESIGN item,
TRGM key,
BITVECP  sign,
int  siglen 
)
static

Definition at line 742 of file trgm_gist.c.

References CACHESIGN::allistrue, GETSIGN, ISALLTRUE, ISARRKEY, makesign(), sign, and CACHESIGN::sign.

Referenced by gtrgm_picksplit().

743 {
744  item->allistrue = false;
745  item->sign = sign;
746  if (ISARRKEY(key))
747  makesign(item->sign, key, siglen);
748  else if (ISALLTRUE(key))
749  item->allistrue = true;
750  else
751  memcpy((void *) item->sign, (void *) GETSIGN(key), siglen);
752 }
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define ISARRKEY(x)
Definition: trgm.h:101
char sign
Definition: informix.c:668
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
bool allistrue
Definition: trgm_gist.c:737
static void makesign(BITVECP sign, TRGM *a, int siglen)
Definition: trgm_gist.c:91
BITVECP sign
Definition: trgm_gist.c:738

◆ gtrgm_alloc()

static TRGM* gtrgm_alloc ( bool  isalltrue,
int  siglen,
BITVECP  sign 
)
static

Definition at line 70 of file trgm_gist.c.

References ALLISTRUE, CALCGTSIZE, flag(), TRGM::flag, GETSIGN, palloc(), SET_VARSIZE, and SIGNKEY.

Referenced by gtrgm_compress(), gtrgm_picksplit(), and gtrgm_union().

71 {
72  int flag = SIGNKEY | (isalltrue ? ALLISTRUE : 0);
73  int size = CALCGTSIZE(flag, siglen);
74  TRGM *res = palloc(size);
75 
76  SET_VARSIZE(res, size);
77  res->flag = flag;
78 
79  if (!isalltrue)
80  {
81  if (sign)
82  memcpy(GETSIGN(res), sign, siglen);
83  else
84  memset(GETSIGN(res), 0, siglen);
85  }
86 
87  return res;
88 }
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define ALLISTRUE
Definition: hstore_gist.c:54
#define CALCGTSIZE(flag, siglen)
Definition: hstore_gist.c:59
Definition: trgm.h:67
char sign
Definition: informix.c:668
char * flag(int b)
Definition: test-ctype.c:33
#define SIGNKEY
Definition: trgm.h:98
uint8 flag
Definition: trgm.h:70
void * palloc(Size size)
Definition: mcxt.c:950
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ gtrgm_compress()

Datum gtrgm_compress ( PG_FUNCTION_ARGS  )

Definition at line 108 of file trgm_gist.c.

References DatumGetPointer, DatumGetTextPP, generate_trgm(), GET_SIGLEN, GETSIGN, gistentryinit, gtrgm_alloc(), i, ISALLTRUE, ISSIGNKEY, GISTENTRY::key, GISTENTRY::leafkey, LOOPBYTE, GISTENTRY::offset, GISTENTRY::page, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, GISTENTRY::rel, sign, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

109 {
110  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
111  int siglen = GET_SIGLEN();
112  GISTENTRY *retval = entry;
113 
114  if (entry->leafkey)
115  { /* trgm */
116  TRGM *res;
117  text *val = DatumGetTextPP(entry->key);
118 
119  res = generate_trgm(VARDATA_ANY(val), VARSIZE_ANY_EXHDR(val));
120  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
121  gistentryinit(*retval, PointerGetDatum(res),
122  entry->rel, entry->page,
123  entry->offset, false);
124  }
125  else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
126  !ISALLTRUE(DatumGetPointer(entry->key)))
127  {
128  int32 i;
129  TRGM *res;
131 
132  LOOPBYTE(siglen)
133  {
134  if ((sign[i] & 0xff) != 0xff)
135  PG_RETURN_POINTER(retval);
136  }
137 
138  res = gtrgm_alloc(true, siglen, sign);
139  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
140  gistentryinit(*retval, PointerGetDatum(res),
141  entry->rel, entry->page,
142  entry->offset, false);
143  }
144  PG_RETURN_POINTER(retval);
145 }
Relation rel
Definition: gist.h:153
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define LOOPBYTE(siglen)
Definition: hstore_gist.c:32
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define ISSIGNKEY(x)
Definition: trgm.h:102
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define PointerGetDatum(X)
Definition: postgres.h:556
#define DatumGetTextPP(X)
Definition: fmgr.h:292
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
signed int int32
Definition: c.h:417
Page page
Definition: gist.h:154
#define GET_SIGLEN()
Definition: trgm_gist.c:19
Definition: trgm.h:67
char sign
Definition: informix.c:668
Datum key
Definition: gist.h:152
bool leafkey
Definition: gist.h:156
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:236
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:356
#define DatumGetPointer(X)
Definition: postgres.h:549
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:950
int i
Definition: c.h:617
char * BITVECP
Definition: hstore_gist.c:30
OffsetNumber offset
Definition: gist.h:155
static TRGM * gtrgm_alloc(bool isalltrue, int siglen, BITVECP sign)
Definition: trgm_gist.c:70
long val
Definition: informix.c:664

◆ gtrgm_consistent()

Datum gtrgm_consistent ( PG_FUNCTION_ARGS  )

Definition at line 190 of file trgm_gist.c.

References ARRNELEM, cnt_sml(), cnt_sml_sign_common(), CPTRGM, createTrgmNFA(), DatumGetPointer, elog, EqualStrategyNumber, ERROR, generate_trgm(), generate_wildcard_trgm(), GET_SIGLEN, GETARR, GETBIT, GETSIGN, GIST_LEAF, gtrgm_consistent_cache::graph, HASHVAL, ILikeStrategyNumber, index_strategy_get_limit(), ISALLTRUE, sort-test::key, GISTENTRY::key, LikeStrategyNumber, MAXALIGN, MemoryContextAlloc(), palloc(), pfree(), PG_GET_COLLATION, PG_GETARG_POINTER, PG_GETARG_TEXT_P, PG_GETARG_UINT16, PG_RETURN_BOOL, gtrgm_consistent_cache::query, RegExpICaseStrategyNumber, RegExpStrategyNumber, sign, SimilarityStrategyNumber, gtrgm_consistent_cache::strategy, StrictWordSimilarityStrategyNumber, trgm_contained_by(), trgm_presence_map(), gtrgm_consistent_cache::trigrams, trigramsMatchGraph(), VARDATA, VARHDRSZ, VARSIZE, and WordSimilarityStrategyNumber.

191 {
192  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
193  text *query = PG_GETARG_TEXT_P(1);
195 
196  /* Oid subtype = PG_GETARG_OID(3); */
197  bool *recheck = (bool *) PG_GETARG_POINTER(4);
198  int siglen = GET_SIGLEN();
199  TRGM *key = (TRGM *) DatumGetPointer(entry->key);
200  TRGM *qtrg;
201  bool res;
202  Size querysize = VARSIZE(query);
203  gtrgm_consistent_cache *cache;
204  double nlimit;
205 
206  /*
207  * We keep the extracted trigrams in cache, because trigram extraction is
208  * relatively CPU-expensive. When trying to reuse a cached value, check
209  * strategy number not just query itself, because trigram extraction
210  * depends on strategy.
211  *
212  * The cached structure is a single palloc chunk containing the
213  * gtrgm_consistent_cache header, then the input query (4-byte length
214  * word, uncompressed, starting at a MAXALIGN boundary), then the TRGM
215  * value (also starting at a MAXALIGN boundary). However we don't try to
216  * include the regex graph (if any) in that struct. (XXX currently, this
217  * approach can leak regex graphs across index rescans. Not clear if
218  * that's worth fixing.)
219  */
220  cache = (gtrgm_consistent_cache *) fcinfo->flinfo->fn_extra;
221  if (cache == NULL ||
222  cache->strategy != strategy ||
223  VARSIZE(cache->query) != querysize ||
224  memcmp((char *) cache->query, (char *) query, querysize) != 0)
225  {
226  gtrgm_consistent_cache *newcache;
227  TrgmPackedGraph *graph = NULL;
228  Size qtrgsize;
229 
230  switch (strategy)
231  {
235  case EqualStrategyNumber:
236  qtrg = generate_trgm(VARDATA(query),
237  querysize - VARHDRSZ);
238  break;
239  case ILikeStrategyNumber:
240 #ifndef IGNORECASE
241  elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
242 #endif
243  /* FALL THRU */
244  case LikeStrategyNumber:
245  qtrg = generate_wildcard_trgm(VARDATA(query),
246  querysize - VARHDRSZ);
247  break;
249 #ifndef IGNORECASE
250  elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
251 #endif
252  /* FALL THRU */
254  qtrg = createTrgmNFA(query, PG_GET_COLLATION(),
255  &graph, fcinfo->flinfo->fn_mcxt);
256  /* just in case an empty array is returned ... */
257  if (qtrg && ARRNELEM(qtrg) <= 0)
258  {
259  pfree(qtrg);
260  qtrg = NULL;
261  }
262  break;
263  default:
264  elog(ERROR, "unrecognized strategy number: %d", strategy);
265  qtrg = NULL; /* keep compiler quiet */
266  break;
267  }
268 
269  qtrgsize = qtrg ? VARSIZE(qtrg) : 0;
270 
271  newcache = (gtrgm_consistent_cache *)
272  MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
274  MAXALIGN(querysize) +
275  qtrgsize);
276 
277  newcache->strategy = strategy;
278  newcache->query = (text *)
279  ((char *) newcache + MAXALIGN(sizeof(gtrgm_consistent_cache)));
280  memcpy((char *) newcache->query, (char *) query, querysize);
281  if (qtrg)
282  {
283  newcache->trigrams = (TRGM *)
284  ((char *) newcache->query + MAXALIGN(querysize));
285  memcpy((char *) newcache->trigrams, (char *) qtrg, qtrgsize);
286  /* release qtrg in case it was made in fn_mcxt */
287  pfree(qtrg);
288  }
289  else
290  newcache->trigrams = NULL;
291  newcache->graph = graph;
292 
293  if (cache)
294  pfree(cache);
295  fcinfo->flinfo->fn_extra = (void *) newcache;
296  cache = newcache;
297  }
298 
299  qtrg = cache->trigrams;
300 
301  switch (strategy)
302  {
306 
307  /*
308  * Similarity search is exact. (Strict) word similarity search is
309  * inexact
310  */
311  *recheck = (strategy != SimilarityStrategyNumber);
312 
313  nlimit = index_strategy_get_limit(strategy);
314 
315  if (GIST_LEAF(entry))
316  { /* all leafs contains orig trgm */
317  double tmpsml = cnt_sml(qtrg, key, *recheck);
318 
319  res = (tmpsml >= nlimit);
320  }
321  else if (ISALLTRUE(key))
322  { /* non-leaf contains signature */
323  res = true;
324  }
325  else
326  { /* non-leaf contains signature */
327  int32 count = cnt_sml_sign_common(qtrg, GETSIGN(key), siglen);
328  int32 len = ARRNELEM(qtrg);
329 
330  if (len == 0)
331  res = false;
332  else
333  res = (((((float8) count) / ((float8) len))) >= nlimit);
334  }
335  break;
336  case ILikeStrategyNumber:
337 #ifndef IGNORECASE
338  elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
339 #endif
340  /* FALL THRU */
341  case LikeStrategyNumber:
342  case EqualStrategyNumber:
343  /* Wildcard and equal search are inexact */
344  *recheck = true;
345 
346  /*
347  * Check if all the extracted trigrams can be present in child
348  * nodes.
349  */
350  if (GIST_LEAF(entry))
351  { /* all leafs contains orig trgm */
352  res = trgm_contained_by(qtrg, key);
353  }
354  else if (ISALLTRUE(key))
355  { /* non-leaf contains signature */
356  res = true;
357  }
358  else
359  { /* non-leaf contains signature */
360  int32 k,
361  tmp = 0,
362  len = ARRNELEM(qtrg);
363  trgm *ptr = GETARR(qtrg);
364  BITVECP sign = GETSIGN(key);
365 
366  res = true;
367  for (k = 0; k < len; k++)
368  {
369  CPTRGM(((char *) &tmp), ptr + k);
370  if (!GETBIT(sign, HASHVAL(tmp, siglen)))
371  {
372  res = false;
373  break;
374  }
375  }
376  }
377  break;
379 #ifndef IGNORECASE
380  elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
381 #endif
382  /* FALL THRU */
384  /* Regexp search is inexact */
385  *recheck = true;
386 
387  /* Check regex match as much as we can with available info */
388  if (qtrg)
389  {
390  if (GIST_LEAF(entry))
391  { /* all leafs contains orig trgm */
392  bool *check;
393 
394  check = trgm_presence_map(qtrg, key);
395  res = trigramsMatchGraph(cache->graph, check);
396  pfree(check);
397  }
398  else if (ISALLTRUE(key))
399  { /* non-leaf contains signature */
400  res = true;
401  }
402  else
403  { /* non-leaf contains signature */
404  int32 k,
405  tmp = 0,
406  len = ARRNELEM(qtrg);
407  trgm *ptr = GETARR(qtrg);
408  BITVECP sign = GETSIGN(key);
409  bool *check;
410 
411  /*
412  * GETBIT() tests may give false positives, due to limited
413  * size of the sign array. But since trigramsMatchGraph()
414  * implements a monotone boolean function, false positives
415  * in the check array can't lead to false negative answer.
416  * So we can apply trigramsMatchGraph despite uncertainty,
417  * and that usefully improves the quality of the search.
418  */
419  check = (bool *) palloc(len * sizeof(bool));
420  for (k = 0; k < len; k++)
421  {
422  CPTRGM(((char *) &tmp), ptr + k);
423  check[k] = GETBIT(sign, HASHVAL(tmp, siglen));
424  }
425  res = trigramsMatchGraph(cache->graph, check);
426  pfree(check);
427  }
428  }
429  else
430  {
431  /* trigram-free query must be rechecked everywhere */
432  res = true;
433  }
434  break;
435  default:
436  elog(ERROR, "unrecognized strategy number: %d", strategy);
437  res = false; /* keep compiler quiet */
438  break;
439  }
440 
441  PG_RETURN_BOOL(res);
442 }
#define GIST_LEAF(entry)
Definition: gist.h:162
bool trigramsMatchGraph(TrgmPackedGraph *graph, bool *check)
Definition: trgm_regexp.c:636
#define VARDATA(PTR)
Definition: postgres.h:302
#define RegExpStrategyNumber
Definition: trgm.h:34
TRGM * generate_wildcard_trgm(const char *str, int slen)
Definition: trgm_op.c:866
#define SimilarityStrategyNumber
Definition: trgm.h:30
#define VARSIZE(PTR)
Definition: postgres.h:303
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define VARHDRSZ
Definition: c.h:623
TRGM * createTrgmNFA(text *text_re, Oid collation, TrgmPackedGraph **graph, MemoryContext rcontext)
Definition: trgm_regexp.c:521
#define StrictWordSimilarityStrategyNumber
Definition: trgm.h:38
#define RegExpICaseStrategyNumber
Definition: trgm.h:35
uint16 StrategyNumber
Definition: stratnum.h:22
float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
Definition: trgm_op.c:996
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define ARRNELEM(x)
Definition: trgm.h:108
bool * trgm_presence_map(TRGM *query, TRGM *key)
Definition: trgm_op.c:1083
#define PG_GET_COLLATION()
Definition: fmgr.h:198
signed int int32
Definition: c.h:417
#define GETARR(x)
Definition: trgm.h:107
#define GET_SIGLEN()
Definition: trgm_gist.c:19
void pfree(void *pointer)
Definition: mcxt.c:1057
#define GETBIT(x, i)
Definition: blutils.c:33
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:553
TrgmPackedGraph * graph
Definition: trgm_gist.c:31
Definition: trgm.h:67
#define EqualStrategyNumber
Definition: trgm.h:40
char sign
Definition: informix.c:668
StrategyNumber strategy
Definition: trgm_gist.c:26
Datum key
Definition: gist.h:152
#define LikeStrategyNumber
Definition: trgm.h:32
double index_strategy_get_limit(StrategyNumber strategy)
Definition: trgm_op.c:132
bool trgm_contained_by(TRGM *trg1, TRGM *trg2)
Definition: trgm_op.c:1044
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
#define WordSimilarityStrategyNumber
Definition: trgm.h:36
#define HASHVAL(val, siglen)
Definition: hstore_gist.c:44
char trgm[3]
Definition: trgm.h:42
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:356
size_t Size
Definition: c.h:528
#define MAXALIGN(LEN)
Definition: c.h:753
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define DatumGetPointer(X)
Definition: postgres.h:549
void * palloc(Size size)
Definition: mcxt.c:950
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:336
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:797
#define elog(elevel,...)
Definition: elog.h:228
static int32 cnt_sml_sign_common(TRGM *qtrg, BITVECP sign, int siglen)
Definition: trgm_gist.c:172
Definition: c.h:617
char * BITVECP
Definition: hstore_gist.c:30
#define ILikeStrategyNumber
Definition: trgm.h:33
#define CPTRGM(a, b)
Definition: trgm.h:48

◆ gtrgm_decompress()

Datum gtrgm_decompress ( PG_FUNCTION_ARGS  )

Definition at line 148 of file trgm_gist.c.

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

149 {
150  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
151  GISTENTRY *retval;
152  text *key;
153 
154  key = DatumGetTextPP(entry->key);
155 
156  if (key != (text *) DatumGetPointer(entry->key))
157  {
158  /* need to pass back the decompressed item */
159  retval = palloc(sizeof(GISTENTRY));
160  gistentryinit(*retval, PointerGetDatum(key),
161  entry->rel, entry->page, entry->offset, entry->leafkey);
162  PG_RETURN_POINTER(retval);
163  }
164  else
165  {
166  /* we can return the entry as-is */
167  PG_RETURN_POINTER(entry);
168  }
169 }
Relation rel
Definition: gist.h:153
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PointerGetDatum(X)
Definition: postgres.h:556
#define DatumGetTextPP(X)
Definition: fmgr.h:292
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
Page page
Definition: gist.h:154
Datum key
Definition: gist.h:152
bool leafkey
Definition: gist.h:156
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:236
#define DatumGetPointer(X)
Definition: postgres.h:549
void * palloc(Size size)
Definition: mcxt.c:950
Definition: c.h:617
OffsetNumber offset
Definition: gist.h:155

◆ gtrgm_distance()

Datum gtrgm_distance ( PG_FUNCTION_ARGS  )

Definition at line 445 of file trgm_gist.c.

References ARRNELEM, cnt_sml(), cnt_sml_sign_common(), DatumGetPointer, DistanceStrategyNumber, elog, ERROR, generate_trgm(), GET_SIGLEN, GETSIGN, GIST_LEAF, ISALLTRUE, sort-test::key, GISTENTRY::key, MAXALIGN, MemoryContextAlloc(), pfree(), PG_GETARG_POINTER, PG_GETARG_TEXT_P, PG_GETARG_UINT16, PG_RETURN_FLOAT8, StrictWordDistanceStrategyNumber, VARDATA, VARHDRSZ, VARSIZE, and WordDistanceStrategyNumber.

446 {
447  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
448  text *query = PG_GETARG_TEXT_P(1);
450 
451  /* Oid subtype = PG_GETARG_OID(3); */
452  bool *recheck = (bool *) PG_GETARG_POINTER(4);
453  int siglen = GET_SIGLEN();
454  TRGM *key = (TRGM *) DatumGetPointer(entry->key);
455  TRGM *qtrg;
456  float8 res;
457  Size querysize = VARSIZE(query);
458  char *cache = (char *) fcinfo->flinfo->fn_extra;
459 
460  /*
461  * Cache the generated trigrams across multiple calls with the same query.
462  */
463  if (cache == NULL ||
464  VARSIZE(cache) != querysize ||
465  memcmp(cache, query, querysize) != 0)
466  {
467  char *newcache;
468 
469  qtrg = generate_trgm(VARDATA(query), querysize - VARHDRSZ);
470 
471  newcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
472  MAXALIGN(querysize) +
473  VARSIZE(qtrg));
474 
475  memcpy(newcache, query, querysize);
476  memcpy(newcache + MAXALIGN(querysize), qtrg, VARSIZE(qtrg));
477 
478  if (cache)
479  pfree(cache);
480  fcinfo->flinfo->fn_extra = newcache;
481  cache = newcache;
482  }
483 
484  qtrg = (TRGM *) (cache + MAXALIGN(querysize));
485 
486  switch (strategy)
487  {
491  /* Only plain trigram distance is exact */
492  *recheck = (strategy != DistanceStrategyNumber);
493  if (GIST_LEAF(entry))
494  { /* all leafs contains orig trgm */
495 
496  /*
497  * Prevent gcc optimizing the sml variable using volatile
498  * keyword. Otherwise res can differ from the
499  * word_similarity_dist_op() function.
500  */
501  float4 volatile sml = cnt_sml(qtrg, key, *recheck);
502 
503  res = 1.0 - sml;
504  }
505  else if (ISALLTRUE(key))
506  { /* all leafs contains orig trgm */
507  res = 0.0;
508  }
509  else
510  { /* non-leaf contains signature */
511  int32 count = cnt_sml_sign_common(qtrg, GETSIGN(key), siglen);
512  int32 len = ARRNELEM(qtrg);
513 
514  res = (len == 0) ? -1.0 : 1.0 - ((float8) count) / ((float8) len);
515  }
516  break;
517  default:
518  elog(ERROR, "unrecognized strategy number: %d", strategy);
519  res = 0; /* keep compiler quiet */
520  break;
521  }
522 
523  PG_RETURN_FLOAT8(res);
524 }
#define GIST_LEAF(entry)
Definition: gist.h:162
#define StrictWordDistanceStrategyNumber
Definition: trgm.h:39
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARSIZE(PTR)
Definition: postgres.h:303
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define DistanceStrategyNumber
Definition: trgm.h:31
#define VARHDRSZ
Definition: c.h:623
#define WordDistanceStrategyNumber
Definition: trgm.h:37
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
uint16 StrategyNumber
Definition: stratnum.h:22
float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
Definition: trgm_op.c:996
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:417
#define GET_SIGLEN()
Definition: trgm_gist.c:19
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:553
Definition: trgm.h:67
Datum key
Definition: gist.h:152
float float4
Definition: c.h:552
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:356
size_t Size
Definition: c.h:528
#define MAXALIGN(LEN)
Definition: c.h:753
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define DatumGetPointer(X)
Definition: postgres.h:549
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:336
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:797
#define elog(elevel,...)
Definition: elog.h:228
static int32 cnt_sml_sign_common(TRGM *qtrg, BITVECP sign, int siglen)
Definition: trgm_gist.c:172
Definition: c.h:617

◆ gtrgm_in()

Datum gtrgm_in ( PG_FUNCTION_ARGS  )

Definition at line 56 of file trgm_gist.c.

References elog, ERROR, and PG_RETURN_DATUM.

57 {
58  elog(ERROR, "not implemented");
59  PG_RETURN_DATUM(0);
60 }
#define ERROR
Definition: elog.h:43
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define elog(elevel,...)
Definition: elog.h:228

◆ gtrgm_options()

Datum gtrgm_options ( PG_FUNCTION_ARGS  )

Definition at line 953 of file trgm_gist.c.

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

954 {
956 
957  init_local_reloptions(relopts, sizeof(TrgmGistOptions));
958  add_local_int_reloption(relopts, "siglen",
959  "signature length in bytes",
961  offsetof(TrgmGistOptions, siglen));
962 
963  PG_RETURN_VOID();
964 }
void init_local_reloptions(local_relopts *opts, Size relopt_struct_size)
Definition: reloptions.c:710
#define SIGLEN_MAX
Definition: hstore_gist.c:23
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
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:894
#define SIGLEN_DEFAULT
Definition: hstore_gist.c:22
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define offsetof(type, field)
Definition: c.h:723

◆ gtrgm_out()

Datum gtrgm_out ( PG_FUNCTION_ARGS  )

Definition at line 63 of file trgm_gist.c.

References elog, ERROR, and PG_RETURN_DATUM.

64 {
65  elog(ERROR, "not implemented");
66  PG_RETURN_DATUM(0);
67 }
#define ERROR
Definition: elog.h:43
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define elog(elevel,...)
Definition: elog.h:228

◆ gtrgm_penalty()

Datum gtrgm_penalty ( PG_FUNCTION_ARGS  )

Definition at line 680 of file trgm_gist.c.

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

681 {
682  GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
683  GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
684  float *penalty = (float *) PG_GETARG_POINTER(2);
685  int siglen = GET_SIGLEN();
686  TRGM *origval = (TRGM *) DatumGetPointer(origentry->key);
687  TRGM *newval = (TRGM *) DatumGetPointer(newentry->key);
688  BITVECP orig = GETSIGN(origval);
689 
690  *penalty = 0.0;
691 
692  if (ISARRKEY(newval))
693  {
694  char *cache = (char *) fcinfo->flinfo->fn_extra;
695  TRGM *cachedVal = (TRGM *) (cache + MAXALIGN(siglen));
696  Size newvalsize = VARSIZE(newval);
697  BITVECP sign;
698 
699  /*
700  * Cache the sign data across multiple calls with the same newval.
701  */
702  if (cache == NULL ||
703  VARSIZE(cachedVal) != newvalsize ||
704  memcmp(cachedVal, newval, newvalsize) != 0)
705  {
706  char *newcache;
707 
708  newcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
709  MAXALIGN(siglen) +
710  newvalsize);
711 
712  makesign((BITVECP) newcache, newval, siglen);
713 
714  cachedVal = (TRGM *) (newcache + MAXALIGN(siglen));
715  memcpy(cachedVal, newval, newvalsize);
716 
717  if (cache)
718  pfree(cache);
719  fcinfo->flinfo->fn_extra = newcache;
720  cache = newcache;
721  }
722 
723  sign = (BITVECP) cache;
724 
725  if (ISALLTRUE(origval))
726  *penalty = ((float) (SIGLENBIT(siglen) - sizebitvec(sign, siglen))) / (float) (SIGLENBIT(siglen) + 1);
727  else
728  *penalty = hemdistsign(sign, orig, siglen);
729  }
730  else
731  *penalty = hemdist(origval, newval, siglen);
732  PG_RETURN_POINTER(penalty);
733 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
static int32 sizebitvec(BITVECP sign, int siglen)
Definition: trgm_gist.c:642
#define VARSIZE(PTR)
Definition: postgres.h:303
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define ISARRKEY(x)
Definition: trgm.h:101
#define GET_SIGLEN()
Definition: trgm_gist.c:19
void pfree(void *pointer)
Definition: mcxt.c:1057
Definition: trgm.h:67
char sign
Definition: informix.c:668
Datum key
Definition: gist.h:152
static int hemdist(TRGM *a, TRGM *b, int siglen)
Definition: trgm_gist.c:664
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Definition: trgm_gist.c:648
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
#define SIGLENBIT(siglen)
Definition: hstore_gist.c:24
size_t Size
Definition: c.h:528
#define newval
#define MAXALIGN(LEN)
Definition: c.h:753
#define DatumGetPointer(X)
Definition: postgres.h:549
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:797
char * BITVECP
Definition: hstore_gist.c:30
static void makesign(BITVECP sign, TRGM *a, int siglen)
Definition: trgm_gist.c:91

◆ gtrgm_picksplit()

Datum gtrgm_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 788 of file trgm_gist.c.

References comparecost(), SPLITCOST::cost, fillcache(), FirstOffsetNumber, GET_SIGLEN, GETENTRY, GETSIGN, gtrgm_alloc(), hemdistcache(), hemdistsign(), i, ISALLTRUE, LOOPBYTE, MemSet, GistEntryVector::n, OffsetNumberNext, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, SPLITCOST::pos, qsort, SIGLENBIT, sign, CACHESIGN::sign, 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.

789 {
791  OffsetNumber maxoff = entryvec->n - 1;
793  int siglen = GET_SIGLEN();
794  OffsetNumber k,
795  j;
796  TRGM *datum_l,
797  *datum_r;
798  BITVECP union_l,
799  union_r;
800  int32 size_alpha,
801  size_beta;
802  int32 size_waste,
803  waste = -1;
804  int32 nbytes;
805  OffsetNumber seed_1 = 0,
806  seed_2 = 0;
807  OffsetNumber *left,
808  *right;
809  BITVECP ptr;
810  int i;
811  CACHESIGN *cache;
812  char *cache_sign;
813  SPLITCOST *costvector;
814 
815  /* cache the sign data for each existing item */
816  cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 1));
817  cache_sign = palloc(siglen * (maxoff + 1));
818 
819  for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k))
820  fillcache(&cache[k], GETENTRY(entryvec, k), &cache_sign[siglen * k],
821  siglen);
822 
823  /* now find the two furthest-apart items */
824  for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
825  {
826  for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
827  {
828  size_waste = hemdistcache(&(cache[j]), &(cache[k]), siglen);
829  if (size_waste > waste)
830  {
831  waste = size_waste;
832  seed_1 = k;
833  seed_2 = j;
834  }
835  }
836  }
837 
838  /* just in case we didn't make a selection ... */
839  if (seed_1 == 0 || seed_2 == 0)
840  {
841  seed_1 = 1;
842  seed_2 = 2;
843  }
844 
845  /* initialize the result vectors */
846  nbytes = maxoff * sizeof(OffsetNumber);
847  v->spl_left = left = (OffsetNumber *) palloc(nbytes);
848  v->spl_right = right = (OffsetNumber *) palloc(nbytes);
849  v->spl_nleft = 0;
850  v->spl_nright = 0;
851 
852  /* form initial .. */
853  datum_l = gtrgm_alloc(cache[seed_1].allistrue, siglen, cache[seed_1].sign);
854  datum_r = gtrgm_alloc(cache[seed_2].allistrue, siglen, cache[seed_2].sign);
855 
856  union_l = GETSIGN(datum_l);
857  union_r = GETSIGN(datum_r);
858 
859  /* sort before ... */
860  costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
861  for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
862  {
863  costvector[j - 1].pos = j;
864  size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]), siglen);
865  size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
866  costvector[j - 1].cost = abs(size_alpha - size_beta);
867  }
868  qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
869 
870  for (k = 0; k < maxoff; k++)
871  {
872  j = costvector[k].pos;
873  if (j == seed_1)
874  {
875  *left++ = j;
876  v->spl_nleft++;
877  continue;
878  }
879  else if (j == seed_2)
880  {
881  *right++ = j;
882  v->spl_nright++;
883  continue;
884  }
885 
886  if (ISALLTRUE(datum_l) || cache[j].allistrue)
887  {
888  if (ISALLTRUE(datum_l) && cache[j].allistrue)
889  size_alpha = 0;
890  else
891  size_alpha = SIGLENBIT(siglen) -
892  sizebitvec((cache[j].allistrue) ? GETSIGN(datum_l) :
893  GETSIGN(cache[j].sign),
894  siglen);
895  }
896  else
897  size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l), siglen);
898 
899  if (ISALLTRUE(datum_r) || cache[j].allistrue)
900  {
901  if (ISALLTRUE(datum_r) && cache[j].allistrue)
902  size_beta = 0;
903  else
904  size_beta = SIGLENBIT(siglen) -
905  sizebitvec((cache[j].allistrue) ? GETSIGN(datum_r) :
906  GETSIGN(cache[j].sign),
907  siglen);
908  }
909  else
910  size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r), siglen);
911 
912  if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
913  {
914  if (ISALLTRUE(datum_l) || cache[j].allistrue)
915  {
916  if (!ISALLTRUE(datum_l))
917  MemSet((void *) GETSIGN(datum_l), 0xff, siglen);
918  }
919  else
920  {
921  ptr = cache[j].sign;
922  LOOPBYTE(siglen)
923  union_l[i] |= ptr[i];
924  }
925  *left++ = j;
926  v->spl_nleft++;
927  }
928  else
929  {
930  if (ISALLTRUE(datum_r) || cache[j].allistrue)
931  {
932  if (!ISALLTRUE(datum_r))
933  MemSet((void *) GETSIGN(datum_r), 0xff, siglen);
934  }
935  else
936  {
937  ptr = cache[j].sign;
938  LOOPBYTE(siglen)
939  union_r[i] |= ptr[i];
940  }
941  *right++ = j;
942  v->spl_nright++;
943  }
944  }
945 
946  v->spl_ldatum = PointerGetDatum(datum_l);
947  v->spl_rdatum = PointerGetDatum(datum_r);
948 
950 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
OffsetNumber pos
Definition: hstore_gist.c:346
static int32 sizebitvec(BITVECP sign, int siglen)
Definition: trgm_gist.c:642
#define LOOPBYTE(siglen)
Definition: hstore_gist.c:32
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define PointerGetDatum(X)
Definition: postgres.h:556
OffsetNumber * spl_left
Definition: gist.h:134
Datum spl_rdatum
Definition: gist.h:141
int32 n
Definition: gist.h:227
static int comparecost(const void *a, const void *b)
Definition: trgm_gist.c:762
#define MemSet(start, val, len)
Definition: c.h:1004
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
int spl_nleft
Definition: gist.h:135
signed int int32
Definition: c.h:417
int32 cost
Definition: hstore_gist.c:347
#define WISH_F(a, b, c)
Definition: trgm_gist.c:754
uint16 OffsetNumber
Definition: off.h:24
#define GET_SIGLEN()
Definition: trgm_gist.c:19
Definition: trgm.h:67
int spl_nright
Definition: gist.h:140
static void fillcache(CACHESIGN *item, TRGM *key, BITVECP sign, int siglen)
Definition: trgm_gist.c:742
char sign
Definition: informix.c:668
#define FirstOffsetNumber
Definition: off.h:27
static int hemdistcache(CACHESIGN *a, CACHESIGN *b, int siglen)
Definition: trgm_gist.c:772
#define GETENTRY(vec, pos)
Definition: trgm_gist.c:39
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Definition: trgm_gist.c:648
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
Datum spl_ldatum
Definition: gist.h:136
#define SIGLENBIT(siglen)
Definition: hstore_gist.c:24
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
OffsetNumber * spl_right
Definition: gist.h:139
void * palloc(Size size)
Definition: mcxt.c:950
int i
char * BITVECP
Definition: hstore_gist.c:30
BITVECP sign
Definition: trgm_gist.c:738
#define qsort(a, b, c, d)
Definition: port.h:497
static TRGM * gtrgm_alloc(bool isalltrue, int siglen, BITVECP sign)
Definition: trgm_gist.c:70

◆ gtrgm_same()

Datum gtrgm_same ( PG_FUNCTION_ARGS  )

Definition at line 583 of file trgm_gist.c.

References ARRNELEM, CMPTRGM, GET_SIGLEN, GETARR, GETSIGN, i, ISALLTRUE, ISSIGNKEY, LOOPBYTE, PG_GETARG_POINTER, and PG_RETURN_POINTER.

584 {
585  TRGM *a = (TRGM *) PG_GETARG_POINTER(0);
586  TRGM *b = (TRGM *) PG_GETARG_POINTER(1);
587  bool *result = (bool *) PG_GETARG_POINTER(2);
588  int siglen = GET_SIGLEN();
589 
590  if (ISSIGNKEY(a))
591  { /* then b also ISSIGNKEY */
592  if (ISALLTRUE(a) && ISALLTRUE(b))
593  *result = true;
594  else if (ISALLTRUE(a))
595  *result = false;
596  else if (ISALLTRUE(b))
597  *result = false;
598  else
599  {
600  int32 i;
601  BITVECP sa = GETSIGN(a),
602  sb = GETSIGN(b);
603 
604  *result = true;
605  LOOPBYTE(siglen)
606  {
607  if (sa[i] != sb[i])
608  {
609  *result = false;
610  break;
611  }
612  }
613  }
614  }
615  else
616  { /* a and b ISARRKEY */
617  int32 lena = ARRNELEM(a),
618  lenb = ARRNELEM(b);
619 
620  if (lena != lenb)
621  *result = false;
622  else
623  {
624  trgm *ptra = GETARR(a),
625  *ptrb = GETARR(b);
626  int32 i;
627 
628  *result = true;
629  for (i = 0; i < lena; i++)
630  if (CMPTRGM(ptra + i, ptrb + i))
631  {
632  *result = false;
633  break;
634  }
635  }
636  }
637 
638  PG_RETURN_POINTER(result);
639 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define CMPTRGM(a, b)
Definition: trgm.h:46
#define LOOPBYTE(siglen)
Definition: hstore_gist.c:32
#define ISSIGNKEY(x)
Definition: trgm.h:102
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:417
#define GETARR(x)
Definition: trgm.h:107
#define GET_SIGLEN()
Definition: trgm_gist.c:19
Definition: trgm.h:67
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
char trgm[3]
Definition: trgm.h:42
int i
char * BITVECP
Definition: hstore_gist.c:30

◆ gtrgm_union()

Datum gtrgm_union ( PG_FUNCTION_ARGS  )

Definition at line 557 of file trgm_gist.c.

References ALLISTRUE, CALCGTSIZE, TRGM::flag, GET_SIGLEN, GETENTRY, GETSIGN, gtrgm_alloc(), i, GistEntryVector::n, PG_GETARG_POINTER, PG_RETURN_POINTER, SET_VARSIZE, unionkey(), and VARSIZE.

558 {
560  int32 len = entryvec->n;
561  int *size = (int *) PG_GETARG_POINTER(1);
562  int siglen = GET_SIGLEN();
563  int32 i;
564  TRGM *result = gtrgm_alloc(false, siglen, NULL);
565  BITVECP base = GETSIGN(result);
566 
567  for (i = 0; i < len; i++)
568  {
569  if (unionkey(base, GETENTRY(entryvec, i), siglen))
570  {
571  result->flag = ALLISTRUE;
572  SET_VARSIZE(result, CALCGTSIZE(ALLISTRUE, siglen));
573  break;
574  }
575  }
576 
577  *size = VARSIZE(result);
578 
579  PG_RETURN_POINTER(result);
580 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define VARSIZE(PTR)
Definition: postgres.h:303
#define GETSIGN(x)
Definition: hstore_gist.c:61
static int32 unionkey(BITVECP sbase, TRGM *add, int siglen)
Definition: trgm_gist.c:527
int32 n
Definition: gist.h:227
#define ALLISTRUE
Definition: hstore_gist.c:54
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
signed int int32
Definition: c.h:417
#define CALCGTSIZE(flag, siglen)
Definition: hstore_gist.c:59
#define GET_SIGLEN()
Definition: trgm_gist.c:19
Definition: trgm.h:67
#define GETENTRY(vec, pos)
Definition: trgm_gist.c:39
uint8 flag
Definition: trgm.h:70
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
char * BITVECP
Definition: hstore_gist.c:30
static TRGM * gtrgm_alloc(bool isalltrue, int siglen, BITVECP sign)
Definition: trgm_gist.c:70

◆ hemdist()

static int hemdist ( TRGM a,
TRGM b,
int  siglen 
)
static

Definition at line 664 of file trgm_gist.c.

References GETSIGN, hemdistsign(), ISALLTRUE, SIGLENBIT, and sizebitvec().

Referenced by gtrgm_penalty().

665 {
666  if (ISALLTRUE(a))
667  {
668  if (ISALLTRUE(b))
669  return 0;
670  else
671  return SIGLENBIT(siglen) - sizebitvec(GETSIGN(b), siglen);
672  }
673  else if (ISALLTRUE(b))
674  return SIGLENBIT(siglen) - sizebitvec(GETSIGN(a), siglen);
675 
676  return hemdistsign(GETSIGN(a), GETSIGN(b), siglen);
677 }
static int32 sizebitvec(BITVECP sign, int siglen)
Definition: trgm_gist.c:642
#define GETSIGN(x)
Definition: hstore_gist.c:61
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Definition: trgm_gist.c:648
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
#define SIGLENBIT(siglen)
Definition: hstore_gist.c:24

◆ hemdistcache()

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

Definition at line 772 of file trgm_gist.c.

References CACHESIGN::allistrue, hemdistsign(), SIGLENBIT, CACHESIGN::sign, and sizebitvec().

Referenced by gtrgm_picksplit().

773 {
774  if (a->allistrue)
775  {
776  if (b->allistrue)
777  return 0;
778  else
779  return SIGLENBIT(siglen) - sizebitvec(b->sign, siglen);
780  }
781  else if (b->allistrue)
782  return SIGLENBIT(siglen) - sizebitvec(a->sign, siglen);
783 
784  return hemdistsign(a->sign, b->sign, siglen);
785 }
static int32 sizebitvec(BITVECP sign, int siglen)
Definition: trgm_gist.c:642
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Definition: trgm_gist.c:648
#define SIGLENBIT(siglen)
Definition: hstore_gist.c:24
bool allistrue
Definition: trgm_gist.c:737
BITVECP sign
Definition: trgm_gist.c:738

◆ hemdistsign()

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

Definition at line 648 of file trgm_gist.c.

References i, LOOPBYTE, and pg_number_of_ones.

Referenced by gtrgm_penalty(), gtrgm_picksplit(), hemdist(), and hemdistcache().

649 {
650  int i,
651  diff,
652  dist = 0;
653 
654  LOOPBYTE(siglen)
655  {
656  diff = (unsigned char) (a[i] ^ b[i]);
657  /* Using the popcount functions here isn't likely to win */
658  dist += pg_number_of_ones[diff];
659  }
660  return dist;
661 }
#define LOOPBYTE(siglen)
Definition: hstore_gist.c:32
PGDLLIMPORT const uint8 pg_number_of_ones[256]
Definition: pg_bitutils.c:87
int i

◆ makesign()

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

Definition at line 91 of file trgm_gist.c.

References ARRNELEM, CPTRGM, GETARR, HASH, MemSet, SETBIT, and SIGLENBIT.

Referenced by fillcache(), and gtrgm_penalty().

92 {
93  int32 k,
94  len = ARRNELEM(a);
95  trgm *ptr = GETARR(a);
96  int32 tmp = 0;
97 
98  MemSet((void *) sign, 0, siglen);
99  SETBIT(sign, SIGLENBIT(siglen)); /* set last unused bit */
100  for (k = 0; k < len; k++)
101  {
102  CPTRGM(((char *) &tmp), ptr + k);
103  HASH(sign, tmp, siglen);
104  }
105 }
#define SETBIT(x, i)
Definition: blutils.c:32
#define MemSet(start, val, len)
Definition: c.h:1004
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:417
#define GETARR(x)
Definition: trgm.h:107
#define HASH(sign, val, siglen)
Definition: hstore_gist.c:45
char sign
Definition: informix.c:668
char trgm[3]
Definition: trgm.h:42
#define SIGLENBIT(siglen)
Definition: hstore_gist.c:24
#define CPTRGM(a, b)
Definition: trgm.h:48

◆ PG_FUNCTION_INFO_V1() [1/11]

PG_FUNCTION_INFO_V1 ( gtrgm_in  )

◆ PG_FUNCTION_INFO_V1() [2/11]

PG_FUNCTION_INFO_V1 ( gtrgm_out  )

◆ PG_FUNCTION_INFO_V1() [3/11]

PG_FUNCTION_INFO_V1 ( gtrgm_compress  )

◆ PG_FUNCTION_INFO_V1() [4/11]

PG_FUNCTION_INFO_V1 ( gtrgm_decompress  )

◆ PG_FUNCTION_INFO_V1() [5/11]

PG_FUNCTION_INFO_V1 ( gtrgm_consistent  )

◆ PG_FUNCTION_INFO_V1() [6/11]

PG_FUNCTION_INFO_V1 ( gtrgm_distance  )

◆ PG_FUNCTION_INFO_V1() [7/11]

PG_FUNCTION_INFO_V1 ( gtrgm_union  )

◆ PG_FUNCTION_INFO_V1() [8/11]

PG_FUNCTION_INFO_V1 ( gtrgm_same  )

◆ PG_FUNCTION_INFO_V1() [9/11]

PG_FUNCTION_INFO_V1 ( gtrgm_penalty  )

◆ PG_FUNCTION_INFO_V1() [10/11]

PG_FUNCTION_INFO_V1 ( gtrgm_picksplit  )

◆ PG_FUNCTION_INFO_V1() [11/11]

PG_FUNCTION_INFO_V1 ( gtrgm_options  )

◆ sizebitvec()

static int32 sizebitvec ( BITVECP  sign,
int  siglen 
)
static

Definition at line 642 of file trgm_gist.c.

References pg_popcount().

Referenced by gtrgm_penalty(), gtrgm_picksplit(), hemdist(), and hemdistcache().

643 {
644  return pg_popcount(sign, siglen);
645 }
uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.c:282
char sign
Definition: informix.c:668

◆ unionkey()

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

Definition at line 527 of file trgm_gist.c.

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

Referenced by gtrgm_union().

528 {
529  int32 i;
530 
531  if (ISSIGNKEY(add))
532  {
533  BITVECP sadd = GETSIGN(add);
534 
535  if (ISALLTRUE(add))
536  return 1;
537 
538  LOOPBYTE(siglen)
539  sbase[i] |= sadd[i];
540  }
541  else
542  {
543  trgm *ptr = GETARR(add);
544  int32 tmp = 0;
545 
546  for (i = 0; i < ARRNELEM(add); i++)
547  {
548  CPTRGM(((char *) &tmp), ptr + i);
549  HASH(sbase, tmp, siglen);
550  }
551  }
552  return 0;
553 }
#define LOOPBYTE(siglen)
Definition: hstore_gist.c:32
#define ISSIGNKEY(x)
Definition: trgm.h:102
#define GETSIGN(x)
Definition: hstore_gist.c:61
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:417
#define GETARR(x)
Definition: trgm.h:107
#define HASH(sign, val, siglen)
Definition: hstore_gist.c:45
#define ISALLTRUE(x)
Definition: hstore_gist.c:56
char trgm[3]
Definition: trgm.h:42
int i
char * BITVECP
Definition: hstore_gist.c:30
#define CPTRGM(a, b)
Definition: trgm.h:48