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

Go to the source code of this file.

Data Structures

struct  gtrgm_consistent_cache
 
struct  CACHESIGN
 
struct  SPLITCOST
 

Macros

#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)
 
Datum gtrgm_in (PG_FUNCTION_ARGS)
 
Datum gtrgm_out (PG_FUNCTION_ARGS)
 
static void makesign (BITVECP sign, TRGM *a)
 
Datum gtrgm_compress (PG_FUNCTION_ARGS)
 
Datum gtrgm_decompress (PG_FUNCTION_ARGS)
 
static int32 cnt_sml_sign_common (TRGM *qtrg, BITVECP sign)
 
Datum gtrgm_consistent (PG_FUNCTION_ARGS)
 
Datum gtrgm_distance (PG_FUNCTION_ARGS)
 
static int32 unionkey (BITVECP sbase, TRGM *add)
 
Datum gtrgm_union (PG_FUNCTION_ARGS)
 
Datum gtrgm_same (PG_FUNCTION_ARGS)
 
static int32 sizebitvec (BITVECP sign)
 
static int hemdistsign (BITVECP a, BITVECP b)
 
static int hemdist (TRGM *a, TRGM *b)
 
Datum gtrgm_penalty (PG_FUNCTION_ARGS)
 
static void fillcache (CACHESIGN *item, TRGM *key)
 
static int comparecost (const void *a, const void *b)
 
static int hemdistcache (CACHESIGN *a, CACHESIGN *b)
 
Datum gtrgm_picksplit (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ GETENTRY

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

Definition at line 29 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 726 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 
)
static

Definition at line 144 of file trgm_gist.c.

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

Referenced by gtrgm_consistent(), and gtrgm_distance().

145 {
146  int32 count = 0;
147  int32 k,
148  len = ARRNELEM(qtrg);
149  trgm *ptr = GETARR(qtrg);
150  int32 tmp = 0;
151 
152  for (k = 0; k < len; k++)
153  {
154  CPTRGM(((char *) &tmp), ptr + k);
155  count += GETBIT(sign, HASHVAL(tmp));
156  }
157 
158  return count;
159 }
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:346
#define GETARR(x)
Definition: trgm.h:107
#define GETBIT(x, i)
Definition: blutils.c:34
char sign
Definition: informix.c:688
#define HASHVAL(val)
Definition: hstore_gist.c:34
char trgm[3]
Definition: trgm.h:41
#define CPTRGM(a, b)
Definition: trgm.h:47

◆ comparecost()

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

Definition at line 734 of file trgm_gist.c.

Referenced by gtrgm_picksplit().

735 {
736  if (((const SPLITCOST *) a)->cost == ((const SPLITCOST *) b)->cost)
737  return 0;
738  else
739  return (((const SPLITCOST *) a)->cost > ((const SPLITCOST *) b)->cost) ? 1 : -1;
740 }

◆ fillcache()

static void fillcache ( CACHESIGN item,
TRGM key 
)
static

Definition at line 715 of file trgm_gist.c.

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

Referenced by gtrgm_picksplit().

716 {
717  item->allistrue = false;
718  if (ISARRKEY(key))
719  makesign(item->sign, key);
720  else if (ISALLTRUE(key))
721  item->allistrue = true;
722  else
723  memcpy((void *) item->sign, (void *) GETSIGN(key), sizeof(BITVEC));
724 }
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define ISARRKEY(x)
Definition: trgm.h:101
static void makesign(BITVECP sign, TRGM *a)
Definition: trgm_gist.c:59
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
BITVEC sign
Definition: trgm_gist.c:711
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
bool allistrue
Definition: trgm_gist.c:710

◆ gtrgm_compress()

Datum gtrgm_compress ( PG_FUNCTION_ARGS  )

Definition at line 76 of file trgm_gist.c.

References ALLISTRUE, CALCGTSIZE, DatumGetPointer, DatumGetTextPP, TRGM::flag, generate_trgm(), GETSIGN, gistentryinit, i, ISALLTRUE, ISSIGNKEY, GISTENTRY::key, GISTENTRY::leafkey, LOOPBYTE, GISTENTRY::offset, GISTENTRY::page, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, GISTENTRY::rel, SET_VARSIZE, sign, SIGNKEY, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

77 {
78  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
79  GISTENTRY *retval = entry;
80 
81  if (entry->leafkey)
82  { /* trgm */
83  TRGM *res;
84  text *val = DatumGetTextPP(entry->key);
85 
87  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
88  gistentryinit(*retval, PointerGetDatum(res),
89  entry->rel, entry->page,
90  entry->offset, false);
91  }
92  else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
93  !ISALLTRUE(DatumGetPointer(entry->key)))
94  {
95  int32 i,
96  len;
97  TRGM *res;
99 
100  LOOPBYTE
101  {
102  if ((sign[i] & 0xff) != 0xff)
103  PG_RETURN_POINTER(retval);
104  }
105 
106  len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0);
107  res = (TRGM *) palloc(len);
108  SET_VARSIZE(res, len);
109  res->flag = SIGNKEY | ALLISTRUE;
110 
111  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
112  gistentryinit(*retval, PointerGetDatum(res),
113  entry->rel, entry->page,
114  entry->offset, false);
115  }
116  PG_RETURN_POINTER(retval);
117 }
Relation rel
Definition: gist.h:132
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define ISSIGNKEY(x)
Definition: trgm.h:102
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define PointerGetDatum(X)
Definition: postgres.h:556
#define DatumGetTextPP(X)
Definition: fmgr.h:286
#define ALLISTRUE
Definition: hstore_gist.c:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
signed int int32
Definition: c.h:346
Page page
Definition: gist.h:133
Definition: trgm.h:66
char sign
Definition: informix.c:688
Datum key
Definition: gist.h:131
bool leafkey
Definition: gist.h:135
#define SIGNKEY
Definition: trgm.h:98
uint8 flag
Definition: trgm.h:69
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
#define CALCGTSIZE(flag)
Definition: hstore_gist.c:49
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:215
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:376
#define DatumGetPointer(X)
Definition: postgres.h:549
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
#define LOOPBYTE
Definition: hstore_gist.c:22
int i
Definition: c.h:549
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
char * BITVECP
Definition: hstore_gist.c:20
OffsetNumber offset
Definition: gist.h:134
long val
Definition: informix.c:684

◆ gtrgm_consistent()

Datum gtrgm_consistent ( PG_FUNCTION_ARGS  )

Definition at line 162 of file trgm_gist.c.

References ARRNELEM, cnt_sml(), cnt_sml_sign_common(), CPTRGM, createTrgmNFA(), DatumGetPointer, elog, ERROR, generate_trgm(), generate_wildcard_trgm(), 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.

163 {
164  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
165  text *query = PG_GETARG_TEXT_P(1);
167 
168  /* Oid subtype = PG_GETARG_OID(3); */
169  bool *recheck = (bool *) PG_GETARG_POINTER(4);
170  TRGM *key = (TRGM *) DatumGetPointer(entry->key);
171  TRGM *qtrg;
172  bool res;
173  Size querysize = VARSIZE(query);
174  gtrgm_consistent_cache *cache;
175  double nlimit;
176 
177  /*
178  * We keep the extracted trigrams in cache, because trigram extraction is
179  * relatively CPU-expensive. When trying to reuse a cached value, check
180  * strategy number not just query itself, because trigram extraction
181  * depends on strategy.
182  *
183  * The cached structure is a single palloc chunk containing the
184  * gtrgm_consistent_cache header, then the input query (4-byte length
185  * word, uncompressed, starting at a MAXALIGN boundary), then the TRGM
186  * value (also starting at a MAXALIGN boundary). However we don't try to
187  * include the regex graph (if any) in that struct. (XXX currently, this
188  * approach can leak regex graphs across index rescans. Not clear if
189  * that's worth fixing.)
190  */
191  cache = (gtrgm_consistent_cache *) fcinfo->flinfo->fn_extra;
192  if (cache == NULL ||
193  cache->strategy != strategy ||
194  VARSIZE(cache->query) != querysize ||
195  memcmp((char *) cache->query, (char *) query, querysize) != 0)
196  {
197  gtrgm_consistent_cache *newcache;
198  TrgmPackedGraph *graph = NULL;
199  Size qtrgsize;
200 
201  switch (strategy)
202  {
206  qtrg = generate_trgm(VARDATA(query),
207  querysize - VARHDRSZ);
208  break;
209  case ILikeStrategyNumber:
210 #ifndef IGNORECASE
211  elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
212 #endif
213  /* FALL THRU */
214  case LikeStrategyNumber:
215  qtrg = generate_wildcard_trgm(VARDATA(query),
216  querysize - VARHDRSZ);
217  break;
219 #ifndef IGNORECASE
220  elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
221 #endif
222  /* FALL THRU */
224  qtrg = createTrgmNFA(query, PG_GET_COLLATION(),
225  &graph, fcinfo->flinfo->fn_mcxt);
226  /* just in case an empty array is returned ... */
227  if (qtrg && ARRNELEM(qtrg) <= 0)
228  {
229  pfree(qtrg);
230  qtrg = NULL;
231  }
232  break;
233  default:
234  elog(ERROR, "unrecognized strategy number: %d", strategy);
235  qtrg = NULL; /* keep compiler quiet */
236  break;
237  }
238 
239  qtrgsize = qtrg ? VARSIZE(qtrg) : 0;
240 
241  newcache = (gtrgm_consistent_cache *)
242  MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
244  MAXALIGN(querysize) +
245  qtrgsize);
246 
247  newcache->strategy = strategy;
248  newcache->query = (text *)
249  ((char *) newcache + MAXALIGN(sizeof(gtrgm_consistent_cache)));
250  memcpy((char *) newcache->query, (char *) query, querysize);
251  if (qtrg)
252  {
253  newcache->trigrams = (TRGM *)
254  ((char *) newcache->query + MAXALIGN(querysize));
255  memcpy((char *) newcache->trigrams, (char *) qtrg, qtrgsize);
256  /* release qtrg in case it was made in fn_mcxt */
257  pfree(qtrg);
258  }
259  else
260  newcache->trigrams = NULL;
261  newcache->graph = graph;
262 
263  if (cache)
264  pfree(cache);
265  fcinfo->flinfo->fn_extra = (void *) newcache;
266  cache = newcache;
267  }
268 
269  qtrg = cache->trigrams;
270 
271  switch (strategy)
272  {
276 
277  /*
278  * Similarity search is exact. (Strict) word similarity search is
279  * inexact
280  */
281  *recheck = (strategy != SimilarityStrategyNumber);
282 
283  nlimit = index_strategy_get_limit(strategy);
284 
285  if (GIST_LEAF(entry))
286  { /* all leafs contains orig trgm */
287  double tmpsml = cnt_sml(qtrg, key, *recheck);
288 
289  res = (tmpsml >= nlimit);
290  }
291  else if (ISALLTRUE(key))
292  { /* non-leaf contains signature */
293  res = true;
294  }
295  else
296  { /* non-leaf contains signature */
297  int32 count = cnt_sml_sign_common(qtrg, GETSIGN(key));
298  int32 len = ARRNELEM(qtrg);
299 
300  if (len == 0)
301  res = false;
302  else
303  res = (((((float8) count) / ((float8) len))) >= nlimit);
304  }
305  break;
306  case ILikeStrategyNumber:
307 #ifndef IGNORECASE
308  elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
309 #endif
310  /* FALL THRU */
311  case LikeStrategyNumber:
312  /* Wildcard search is inexact */
313  *recheck = true;
314 
315  /*
316  * Check if all the extracted trigrams can be present in child
317  * nodes.
318  */
319  if (GIST_LEAF(entry))
320  { /* all leafs contains orig trgm */
321  res = trgm_contained_by(qtrg, key);
322  }
323  else if (ISALLTRUE(key))
324  { /* non-leaf contains signature */
325  res = true;
326  }
327  else
328  { /* non-leaf contains signature */
329  int32 k,
330  tmp = 0,
331  len = ARRNELEM(qtrg);
332  trgm *ptr = GETARR(qtrg);
333  BITVECP sign = GETSIGN(key);
334 
335  res = true;
336  for (k = 0; k < len; k++)
337  {
338  CPTRGM(((char *) &tmp), ptr + k);
339  if (!GETBIT(sign, HASHVAL(tmp)))
340  {
341  res = false;
342  break;
343  }
344  }
345  }
346  break;
348 #ifndef IGNORECASE
349  elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
350 #endif
351  /* FALL THRU */
353  /* Regexp search is inexact */
354  *recheck = true;
355 
356  /* Check regex match as much as we can with available info */
357  if (qtrg)
358  {
359  if (GIST_LEAF(entry))
360  { /* all leafs contains orig trgm */
361  bool *check;
362 
363  check = trgm_presence_map(qtrg, key);
364  res = trigramsMatchGraph(cache->graph, check);
365  pfree(check);
366  }
367  else if (ISALLTRUE(key))
368  { /* non-leaf contains signature */
369  res = true;
370  }
371  else
372  { /* non-leaf contains signature */
373  int32 k,
374  tmp = 0,
375  len = ARRNELEM(qtrg);
376  trgm *ptr = GETARR(qtrg);
377  BITVECP sign = GETSIGN(key);
378  bool *check;
379 
380  /*
381  * GETBIT() tests may give false positives, due to limited
382  * size of the sign array. But since trigramsMatchGraph()
383  * implements a monotone boolean function, false positives
384  * in the check array can't lead to false negative answer.
385  * So we can apply trigramsMatchGraph despite uncertainty,
386  * and that usefully improves the quality of the search.
387  */
388  check = (bool *) palloc(len * sizeof(bool));
389  for (k = 0; k < len; k++)
390  {
391  CPTRGM(((char *) &tmp), ptr + k);
392  check[k] = GETBIT(sign, HASHVAL(tmp));
393  }
394  res = trigramsMatchGraph(cache->graph, check);
395  pfree(check);
396  }
397  }
398  else
399  {
400  /* trigram-free query must be rechecked everywhere */
401  res = true;
402  }
403  break;
404  default:
405  elog(ERROR, "unrecognized strategy number: %d", strategy);
406  res = false; /* keep compiler quiet */
407  break;
408  }
409 
410  PG_RETURN_BOOL(res);
411 }
#define GIST_LEAF(entry)
Definition: gist.h:141
bool trigramsMatchGraph(TrgmPackedGraph *graph, bool *check)
Definition: trgm_regexp.c:641
#define VARDATA(PTR)
Definition: postgres.h:302
#define RegExpStrategyNumber
Definition: trgm.h:34
static int32 cnt_sml_sign_common(TRGM *qtrg, BITVECP sign)
Definition: trgm_gist.c:144
TRGM * generate_wildcard_trgm(const char *str, int slen)
Definition: trgm_op.c:886
#define SimilarityStrategyNumber
Definition: trgm.h:30
#define VARSIZE(PTR)
Definition: postgres.h:303
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define VARHDRSZ
Definition: c.h:555
TRGM * createTrgmNFA(text *text_re, Oid collation, TrgmPackedGraph **graph, MemoryContext rcontext)
Definition: trgm_regexp.c:523
#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:1018
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define ARRNELEM(x)
Definition: trgm.h:108
bool * trgm_presence_map(TRGM *query, TRGM *key)
Definition: trgm_op.c:1105
#define PG_GET_COLLATION()
Definition: fmgr.h:193
signed int int32
Definition: c.h:346
#define GETARR(x)
Definition: trgm.h:107
void pfree(void *pointer)
Definition: mcxt.c:1056
#define GETBIT(x, i)
Definition: blutils.c:34
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:491
TrgmPackedGraph * graph
Definition: trgm_gist.c:21
Definition: trgm.h:66
char sign
Definition: informix.c:688
StrategyNumber strategy
Definition: trgm_gist.c:16
Datum key
Definition: gist.h:131
#define LikeStrategyNumber
Definition: trgm.h:32
double index_strategy_get_limit(StrategyNumber strategy)
Definition: trgm_op.c:132
#define HASHVAL(val)
Definition: hstore_gist.c:34
bool trgm_contained_by(TRGM *trg1, TRGM *trg2)
Definition: trgm_op.c:1066
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
#define WordSimilarityStrategyNumber
Definition: trgm.h:36
char trgm[3]
Definition: trgm.h:41
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:376
size_t Size
Definition: c.h:466
#define MAXALIGN(LEN)
Definition: c.h:685
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:267
#define DatumGetPointer(X)
Definition: postgres.h:549
void * palloc(Size size)
Definition: mcxt.c:949
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:330
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
#define elog(elevel,...)
Definition: elog.h:226
Definition: c.h:549
char * BITVECP
Definition: hstore_gist.c:20
#define ILikeStrategyNumber
Definition: trgm.h:33
#define CPTRGM(a, b)
Definition: trgm.h:47

◆ gtrgm_decompress()

Datum gtrgm_decompress ( PG_FUNCTION_ARGS  )

Definition at line 120 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.

121 {
122  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
123  GISTENTRY *retval;
124  text *key;
125 
126  key = DatumGetTextPP(entry->key);
127 
128  if (key != (text *) DatumGetPointer(entry->key))
129  {
130  /* need to pass back the decompressed item */
131  retval = palloc(sizeof(GISTENTRY));
132  gistentryinit(*retval, PointerGetDatum(key),
133  entry->rel, entry->page, entry->offset, entry->leafkey);
134  PG_RETURN_POINTER(retval);
135  }
136  else
137  {
138  /* we can return the entry as-is */
139  PG_RETURN_POINTER(entry);
140  }
141 }
Relation rel
Definition: gist.h:132
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
#define PointerGetDatum(X)
Definition: postgres.h:556
#define DatumGetTextPP(X)
Definition: fmgr.h:286
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
Page page
Definition: gist.h:133
Datum key
Definition: gist.h:131
bool leafkey
Definition: gist.h:135
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:215
#define DatumGetPointer(X)
Definition: postgres.h:549
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:549
OffsetNumber offset
Definition: gist.h:134

◆ gtrgm_distance()

Datum gtrgm_distance ( PG_FUNCTION_ARGS  )

Definition at line 414 of file trgm_gist.c.

References ARRNELEM, cnt_sml(), cnt_sml_sign_common(), DatumGetPointer, DistanceStrategyNumber, elog, ERROR, generate_trgm(), 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.

415 {
416  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
417  text *query = PG_GETARG_TEXT_P(1);
419 
420  /* Oid subtype = PG_GETARG_OID(3); */
421  bool *recheck = (bool *) PG_GETARG_POINTER(4);
422  TRGM *key = (TRGM *) DatumGetPointer(entry->key);
423  TRGM *qtrg;
424  float8 res;
425  Size querysize = VARSIZE(query);
426  char *cache = (char *) fcinfo->flinfo->fn_extra;
427 
428  /*
429  * Cache the generated trigrams across multiple calls with the same query.
430  */
431  if (cache == NULL ||
432  VARSIZE(cache) != querysize ||
433  memcmp(cache, query, querysize) != 0)
434  {
435  char *newcache;
436 
437  qtrg = generate_trgm(VARDATA(query), querysize - VARHDRSZ);
438 
439  newcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
440  MAXALIGN(querysize) +
441  VARSIZE(qtrg));
442 
443  memcpy(newcache, query, querysize);
444  memcpy(newcache + MAXALIGN(querysize), qtrg, VARSIZE(qtrg));
445 
446  if (cache)
447  pfree(cache);
448  fcinfo->flinfo->fn_extra = newcache;
449  cache = newcache;
450  }
451 
452  qtrg = (TRGM *) (cache + MAXALIGN(querysize));
453 
454  switch (strategy)
455  {
459  /* Only plain trigram distance is exact */
460  *recheck = (strategy != DistanceStrategyNumber);
461  if (GIST_LEAF(entry))
462  { /* all leafs contains orig trgm */
463 
464  /*
465  * Prevent gcc optimizing the sml variable using volatile
466  * keyword. Otherwise res can differ from the
467  * word_similarity_dist_op() function.
468  */
469  float4 volatile sml = cnt_sml(qtrg, key, *recheck);
470 
471  res = 1.0 - sml;
472  }
473  else if (ISALLTRUE(key))
474  { /* all leafs contains orig trgm */
475  res = 0.0;
476  }
477  else
478  { /* non-leaf contains signature */
479  int32 count = cnt_sml_sign_common(qtrg, GETSIGN(key));
480  int32 len = ARRNELEM(qtrg);
481 
482  res = (len == 0) ? -1.0 : 1.0 - ((float8) count) / ((float8) len);
483  }
484  break;
485  default:
486  elog(ERROR, "unrecognized strategy number: %d", strategy);
487  res = 0; /* keep compiler quiet */
488  break;
489  }
490 
491  PG_RETURN_FLOAT8(res);
492 }
#define GIST_LEAF(entry)
Definition: gist.h:141
#define StrictWordDistanceStrategyNumber
Definition: trgm.h:39
#define VARDATA(PTR)
Definition: postgres.h:302
static int32 cnt_sml_sign_common(TRGM *qtrg, BITVECP sign)
Definition: trgm_gist.c:144
#define VARSIZE(PTR)
Definition: postgres.h:303
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define DistanceStrategyNumber
Definition: trgm.h:31
#define VARHDRSZ
Definition: c.h:555
#define WordDistanceStrategyNumber
Definition: trgm.h:37
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:356
uint16 StrategyNumber
Definition: stratnum.h:22
float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
Definition: trgm_op.c:1018
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:346
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:491
Definition: trgm.h:66
Datum key
Definition: gist.h:131
float float4
Definition: c.h:490
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:376
size_t Size
Definition: c.h:466
#define MAXALIGN(LEN)
Definition: c.h:685
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:267
#define DatumGetPointer(X)
Definition: postgres.h:549
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:330
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
#define elog(elevel,...)
Definition: elog.h:226
Definition: c.h:549

◆ gtrgm_in()

Datum gtrgm_in ( PG_FUNCTION_ARGS  )

Definition at line 45 of file trgm_gist.c.

References elog, ERROR, and PG_RETURN_DATUM.

46 {
47  elog(ERROR, "not implemented");
48  PG_RETURN_DATUM(0);
49 }
#define ERROR
Definition: elog.h:43
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define elog(elevel,...)
Definition: elog.h:226

◆ gtrgm_out()

Datum gtrgm_out ( PG_FUNCTION_ARGS  )

Definition at line 52 of file trgm_gist.c.

References elog, ERROR, and PG_RETURN_DATUM.

53 {
54  elog(ERROR, "not implemented");
55  PG_RETURN_DATUM(0);
56 }
#define ERROR
Definition: elog.h:43
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define elog(elevel,...)
Definition: elog.h:226

◆ gtrgm_penalty()

Datum gtrgm_penalty ( PG_FUNCTION_ARGS  )

Definition at line 654 of file trgm_gist.c.

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

655 {
656  GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
657  GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
658  float *penalty = (float *) PG_GETARG_POINTER(2);
659  TRGM *origval = (TRGM *) DatumGetPointer(origentry->key);
660  TRGM *newval = (TRGM *) DatumGetPointer(newentry->key);
661  BITVECP orig = GETSIGN(origval);
662 
663  *penalty = 0.0;
664 
665  if (ISARRKEY(newval))
666  {
667  char *cache = (char *) fcinfo->flinfo->fn_extra;
668  TRGM *cachedVal = (TRGM *) (cache + MAXALIGN(sizeof(BITVEC)));
669  Size newvalsize = VARSIZE(newval);
670  BITVECP sign;
671 
672  /*
673  * Cache the sign data across multiple calls with the same newval.
674  */
675  if (cache == NULL ||
676  VARSIZE(cachedVal) != newvalsize ||
677  memcmp(cachedVal, newval, newvalsize) != 0)
678  {
679  char *newcache;
680 
681  newcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
682  MAXALIGN(sizeof(BITVEC)) +
683  newvalsize);
684 
685  makesign((BITVECP) newcache, newval);
686 
687  cachedVal = (TRGM *) (newcache + MAXALIGN(sizeof(BITVEC)));
688  memcpy(cachedVal, newval, newvalsize);
689 
690  if (cache)
691  pfree(cache);
692  fcinfo->flinfo->fn_extra = newcache;
693  cache = newcache;
694  }
695 
696  sign = (BITVECP) cache;
697 
698  if (ISALLTRUE(origval))
699  *penalty = ((float) (SIGLENBIT - sizebitvec(sign))) / (float) (SIGLENBIT + 1);
700  else
701  *penalty = hemdistsign(sign, orig);
702  }
703  else
704  *penalty = hemdist(origval, newval);
705  PG_RETURN_POINTER(penalty);
706 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
static int hemdist(TRGM *a, TRGM *b)
Definition: trgm_gist.c:638
#define VARSIZE(PTR)
Definition: postgres.h:303
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define SIGLENBIT
Definition: hstore_gist.c:17
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define ISARRKEY(x)
Definition: trgm.h:101
void pfree(void *pointer)
Definition: mcxt.c:1056
Definition: trgm.h:66
static void makesign(BITVECP sign, TRGM *a)
Definition: trgm_gist.c:59
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
char sign
Definition: informix.c:688
Datum key
Definition: gist.h:131
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
static int hemdistsign(BITVECP a, BITVECP b)
Definition: trgm_gist.c:622
size_t Size
Definition: c.h:466
#define newval
#define MAXALIGN(LEN)
Definition: c.h:685
#define DatumGetPointer(X)
Definition: postgres.h:549
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
char * BITVECP
Definition: hstore_gist.c:20
static int32 sizebitvec(BITVECP sign)
Definition: trgm_gist.c:616

◆ gtrgm_picksplit()

Datum gtrgm_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 760 of file trgm_gist.c.

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

761 {
763  OffsetNumber maxoff = entryvec->n - 2;
765  OffsetNumber k,
766  j;
767  TRGM *datum_l,
768  *datum_r;
769  BITVECP union_l,
770  union_r;
771  int32 size_alpha,
772  size_beta;
773  int32 size_waste,
774  waste = -1;
775  int32 nbytes;
776  OffsetNumber seed_1 = 0,
777  seed_2 = 0;
778  OffsetNumber *left,
779  *right;
780  BITVECP ptr;
781  int i;
782  CACHESIGN *cache;
783  SPLITCOST *costvector;
784 
785  /* cache the sign data for each existing item */
786  cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2));
787  for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k))
788  fillcache(&cache[k], GETENTRY(entryvec, k));
789 
790  /* now find the two furthest-apart items */
791  for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
792  {
793  for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
794  {
795  size_waste = hemdistcache(&(cache[j]), &(cache[k]));
796  if (size_waste > waste)
797  {
798  waste = size_waste;
799  seed_1 = k;
800  seed_2 = j;
801  }
802  }
803  }
804 
805  /* just in case we didn't make a selection ... */
806  if (seed_1 == 0 || seed_2 == 0)
807  {
808  seed_1 = 1;
809  seed_2 = 2;
810  }
811 
812  /* initialize the result vectors */
813  nbytes = (maxoff + 2) * sizeof(OffsetNumber);
814  v->spl_left = left = (OffsetNumber *) palloc(nbytes);
815  v->spl_right = right = (OffsetNumber *) palloc(nbytes);
816  v->spl_nleft = 0;
817  v->spl_nright = 0;
818 
819  /* form initial .. */
820  if (cache[seed_1].allistrue)
821  {
822  datum_l = (TRGM *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
823  SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
824  datum_l->flag = SIGNKEY | ALLISTRUE;
825  }
826  else
827  {
828  datum_l = (TRGM *) palloc(CALCGTSIZE(SIGNKEY, 0));
829  SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY, 0));
830  datum_l->flag = SIGNKEY;
831  memcpy((void *) GETSIGN(datum_l), (void *) cache[seed_1].sign, sizeof(BITVEC));
832  }
833  if (cache[seed_2].allistrue)
834  {
835  datum_r = (TRGM *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
836  SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
837  datum_r->flag = SIGNKEY | ALLISTRUE;
838  }
839  else
840  {
841  datum_r = (TRGM *) palloc(CALCGTSIZE(SIGNKEY, 0));
842  SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY, 0));
843  datum_r->flag = SIGNKEY;
844  memcpy((void *) GETSIGN(datum_r), (void *) cache[seed_2].sign, sizeof(BITVEC));
845  }
846 
847  union_l = GETSIGN(datum_l);
848  union_r = GETSIGN(datum_r);
849  maxoff = OffsetNumberNext(maxoff);
850  fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff));
851  /* sort before ... */
852  costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
853  for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
854  {
855  costvector[j - 1].pos = j;
856  size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]));
857  size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]));
858  costvector[j - 1].cost = abs(size_alpha - size_beta);
859  }
860  qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
861 
862  for (k = 0; k < maxoff; k++)
863  {
864  j = costvector[k].pos;
865  if (j == seed_1)
866  {
867  *left++ = j;
868  v->spl_nleft++;
869  continue;
870  }
871  else if (j == seed_2)
872  {
873  *right++ = j;
874  v->spl_nright++;
875  continue;
876  }
877 
878  if (ISALLTRUE(datum_l) || cache[j].allistrue)
879  {
880  if (ISALLTRUE(datum_l) && cache[j].allistrue)
881  size_alpha = 0;
882  else
883  size_alpha = SIGLENBIT - sizebitvec(
884  (cache[j].allistrue) ? GETSIGN(datum_l) : GETSIGN(cache[j].sign)
885  );
886  }
887  else
888  size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l));
889 
890  if (ISALLTRUE(datum_r) || cache[j].allistrue)
891  {
892  if (ISALLTRUE(datum_r) && cache[j].allistrue)
893  size_beta = 0;
894  else
895  size_beta = SIGLENBIT - sizebitvec(
896  (cache[j].allistrue) ? GETSIGN(datum_r) : GETSIGN(cache[j].sign)
897  );
898  }
899  else
900  size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r));
901 
902  if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
903  {
904  if (ISALLTRUE(datum_l) || cache[j].allistrue)
905  {
906  if (!ISALLTRUE(datum_l))
907  MemSet((void *) GETSIGN(datum_l), 0xff, sizeof(BITVEC));
908  }
909  else
910  {
911  ptr = cache[j].sign;
912  LOOPBYTE
913  union_l[i] |= ptr[i];
914  }
915  *left++ = j;
916  v->spl_nleft++;
917  }
918  else
919  {
920  if (ISALLTRUE(datum_r) || cache[j].allistrue)
921  {
922  if (!ISALLTRUE(datum_r))
923  MemSet((void *) GETSIGN(datum_r), 0xff, sizeof(BITVEC));
924  }
925  else
926  {
927  ptr = cache[j].sign;
928  LOOPBYTE
929  union_r[i] |= ptr[i];
930  }
931  *right++ = j;
932  v->spl_nright++;
933  }
934  }
935 
936  *right = *left = FirstOffsetNumber;
937  v->spl_ldatum = PointerGetDatum(datum_l);
938  v->spl_rdatum = PointerGetDatum(datum_r);
939 
941 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
OffsetNumber pos
Definition: hstore_gist.c:320
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define PointerGetDatum(X)
Definition: postgres.h:556
#define SIGLENBIT
Definition: hstore_gist.c:17
static int hemdistcache(CACHESIGN *a, CACHESIGN *b)
Definition: trgm_gist.c:744
OffsetNumber * spl_left
Definition: gist.h:113
Datum spl_rdatum
Definition: gist.h:120
int32 n
Definition: gist.h:206
static int comparecost(const void *a, const void *b)
Definition: trgm_gist.c:734
#define ALLISTRUE
Definition: hstore_gist.c:44
#define MemSet(start, val, len)
Definition: c.h:955
static void fillcache(CACHESIGN *item, TRGM *key)
Definition: trgm_gist.c:715
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
int spl_nleft
Definition: gist.h:114
signed int int32
Definition: c.h:346
int32 cost
Definition: hstore_gist.c:321
#define WISH_F(a, b, c)
Definition: trgm_gist.c:726
uint16 OffsetNumber
Definition: off.h:24
Definition: trgm.h:66
int spl_nright
Definition: gist.h:119
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
BITVEC sign
Definition: trgm_gist.c:711
char sign
Definition: informix.c:688
#define FirstOffsetNumber
Definition: off.h:27
#define SIGNKEY
Definition: trgm.h:98
#define GETENTRY(vec, pos)
Definition: trgm_gist.c:29
uint8 flag
Definition: trgm.h:69
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
static int hemdistsign(BITVECP a, BITVECP b)
Definition: trgm_gist.c:622
#define CALCGTSIZE(flag)
Definition: hstore_gist.c:49
Datum spl_ldatum
Definition: gist.h:115
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
OffsetNumber * spl_right
Definition: gist.h:118
void * palloc(Size size)
Definition: mcxt.c:949
#define LOOPBYTE
Definition: hstore_gist.c:22
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
char * BITVECP
Definition: hstore_gist.c:20
#define qsort(a, b, c, d)
Definition: port.h:492
static int32 sizebitvec(BITVECP sign)
Definition: trgm_gist.c:616

◆ gtrgm_same()

Datum gtrgm_same ( PG_FUNCTION_ARGS  )

Definition at line 558 of file trgm_gist.c.

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

559 {
560  TRGM *a = (TRGM *) PG_GETARG_POINTER(0);
561  TRGM *b = (TRGM *) PG_GETARG_POINTER(1);
562  bool *result = (bool *) PG_GETARG_POINTER(2);
563 
564  if (ISSIGNKEY(a))
565  { /* then b also ISSIGNKEY */
566  if (ISALLTRUE(a) && ISALLTRUE(b))
567  *result = true;
568  else if (ISALLTRUE(a))
569  *result = false;
570  else if (ISALLTRUE(b))
571  *result = false;
572  else
573  {
574  int32 i;
575  BITVECP sa = GETSIGN(a),
576  sb = GETSIGN(b);
577 
578  *result = true;
579  LOOPBYTE
580  {
581  if (sa[i] != sb[i])
582  {
583  *result = false;
584  break;
585  }
586  }
587  }
588  }
589  else
590  { /* a and b ISARRKEY */
591  int32 lena = ARRNELEM(a),
592  lenb = ARRNELEM(b);
593 
594  if (lena != lenb)
595  *result = false;
596  else
597  {
598  trgm *ptra = GETARR(a),
599  *ptrb = GETARR(b);
600  int32 i;
601 
602  *result = true;
603  for (i = 0; i < lena; i++)
604  if (CMPTRGM(ptra + i, ptrb + i))
605  {
606  *result = false;
607  break;
608  }
609  }
610  }
611 
612  PG_RETURN_POINTER(result);
613 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
#define CMPTRGM(a, b)
Definition: trgm.h:45
#define ISSIGNKEY(x)
Definition: trgm.h:102
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:346
#define GETARR(x)
Definition: trgm.h:107
Definition: trgm.h:66
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
char trgm[3]
Definition: trgm.h:41
#define LOOPBYTE
Definition: hstore_gist.c:22
int i
char * BITVECP
Definition: hstore_gist.c:20

◆ gtrgm_union()

Datum gtrgm_union ( PG_FUNCTION_ARGS  )

Definition at line 525 of file trgm_gist.c.

References ALLISTRUE, CALCGTSIZE, flag(), TRGM::flag, GETENTRY, GETSIGN, i, ISALLTRUE, MemSet, GistEntryVector::n, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, SET_VARSIZE, SIGNKEY, and unionkey().

526 {
528  int32 len = entryvec->n;
529  int *size = (int *) PG_GETARG_POINTER(1);
530  BITVEC base;
531  int32 i;
532  int32 flag = 0;
533  TRGM *result;
534 
535  MemSet((void *) base, 0, sizeof(BITVEC));
536  for (i = 0; i < len; i++)
537  {
538  if (unionkey(base, GETENTRY(entryvec, i)))
539  {
540  flag = ALLISTRUE;
541  break;
542  }
543  }
544 
545  flag |= SIGNKEY;
546  len = CALCGTSIZE(flag, 0);
547  result = (TRGM *) palloc(len);
548  SET_VARSIZE(result, len);
549  result->flag = flag;
550  if (!ISALLTRUE(result))
551  memcpy((void *) GETSIGN(result), (void *) base, sizeof(BITVEC));
552  *size = len;
553 
554  PG_RETURN_POINTER(result);
555 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
#define GETSIGN(x)
Definition: hstore_gist.c:51
int32 n
Definition: gist.h:206
#define ALLISTRUE
Definition: hstore_gist.c:44
#define MemSet(start, val, len)
Definition: c.h:955
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
signed int int32
Definition: c.h:346
static int32 unionkey(BITVECP sbase, TRGM *add)
Definition: trgm_gist.c:495
Definition: trgm.h:66
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
char * flag(int b)
Definition: test-ctype.c:33
#define SIGNKEY
Definition: trgm.h:98
#define GETENTRY(vec, pos)
Definition: trgm_gist.c:29
uint8 flag
Definition: trgm.h:69
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
#define CALCGTSIZE(flag)
Definition: hstore_gist.c:49
void * palloc(Size size)
Definition: mcxt.c:949
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ hemdist()

static int hemdist ( TRGM a,
TRGM b 
)
static

Definition at line 638 of file trgm_gist.c.

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

Referenced by gtrgm_penalty().

639 {
640  if (ISALLTRUE(a))
641  {
642  if (ISALLTRUE(b))
643  return 0;
644  else
645  return SIGLENBIT - sizebitvec(GETSIGN(b));
646  }
647  else if (ISALLTRUE(b))
648  return SIGLENBIT - sizebitvec(GETSIGN(a));
649 
650  return hemdistsign(GETSIGN(a), GETSIGN(b));
651 }
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define SIGLENBIT
Definition: hstore_gist.c:17
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
static int hemdistsign(BITVECP a, BITVECP b)
Definition: trgm_gist.c:622
static int32 sizebitvec(BITVECP sign)
Definition: trgm_gist.c:616

◆ hemdistcache()

static int hemdistcache ( CACHESIGN a,
CACHESIGN b 
)
static

Definition at line 744 of file trgm_gist.c.

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

Referenced by gtrgm_picksplit().

745 {
746  if (a->allistrue)
747  {
748  if (b->allistrue)
749  return 0;
750  else
751  return SIGLENBIT - sizebitvec(b->sign);
752  }
753  else if (b->allistrue)
754  return SIGLENBIT - sizebitvec(a->sign);
755 
756  return hemdistsign(a->sign, b->sign);
757 }
#define SIGLENBIT
Definition: hstore_gist.c:17
BITVEC sign
Definition: trgm_gist.c:711
static int hemdistsign(BITVECP a, BITVECP b)
Definition: trgm_gist.c:622
bool allistrue
Definition: trgm_gist.c:710
static int32 sizebitvec(BITVECP sign)
Definition: trgm_gist.c:616

◆ hemdistsign()

static int hemdistsign ( BITVECP  a,
BITVECP  b 
)
static

Definition at line 622 of file trgm_gist.c.

References i, LOOPBYTE, and pg_number_of_ones.

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

623 {
624  int i,
625  diff,
626  dist = 0;
627 
628  LOOPBYTE
629  {
630  diff = (unsigned char) (a[i] ^ b[i]);
631  /* Using the popcount functions here isn't likely to win */
632  dist += pg_number_of_ones[diff];
633  }
634  return dist;
635 }
PGDLLIMPORT const uint8 pg_number_of_ones[256]
Definition: pg_bitutils.c:87
#define LOOPBYTE
Definition: hstore_gist.c:22
int i

◆ makesign()

static void makesign ( BITVECP  sign,
TRGM a 
)
static

Definition at line 59 of file trgm_gist.c.

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

Referenced by fillcache(), and gtrgm_penalty().

60 {
61  int32 k,
62  len = ARRNELEM(a);
63  trgm *ptr = GETARR(a);
64  int32 tmp = 0;
65 
66  MemSet((void *) sign, 0, sizeof(BITVEC));
67  SETBIT(sign, SIGLENBIT); /* set last unused bit */
68  for (k = 0; k < len; k++)
69  {
70  CPTRGM(((char *) &tmp), ptr + k);
71  HASH(sign, tmp);
72  }
73 }
#define SETBIT(x, i)
Definition: blutils.c:33
#define SIGLENBIT
Definition: hstore_gist.c:17
#define MemSet(start, val, len)
Definition: c.h:955
#define HASH(sign, val)
Definition: hstore_gist.c:35
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:346
#define GETARR(x)
Definition: trgm.h:107
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
char sign
Definition: informix.c:688
char trgm[3]
Definition: trgm.h:41
#define CPTRGM(a, b)
Definition: trgm.h:47

◆ PG_FUNCTION_INFO_V1() [1/10]

PG_FUNCTION_INFO_V1 ( gtrgm_in  )

◆ PG_FUNCTION_INFO_V1() [2/10]

PG_FUNCTION_INFO_V1 ( gtrgm_out  )

◆ PG_FUNCTION_INFO_V1() [3/10]

PG_FUNCTION_INFO_V1 ( gtrgm_compress  )

◆ PG_FUNCTION_INFO_V1() [4/10]

PG_FUNCTION_INFO_V1 ( gtrgm_decompress  )

◆ PG_FUNCTION_INFO_V1() [5/10]

PG_FUNCTION_INFO_V1 ( gtrgm_consistent  )

◆ PG_FUNCTION_INFO_V1() [6/10]

PG_FUNCTION_INFO_V1 ( gtrgm_distance  )

◆ PG_FUNCTION_INFO_V1() [7/10]

PG_FUNCTION_INFO_V1 ( gtrgm_union  )

◆ PG_FUNCTION_INFO_V1() [8/10]

PG_FUNCTION_INFO_V1 ( gtrgm_same  )

◆ PG_FUNCTION_INFO_V1() [9/10]

PG_FUNCTION_INFO_V1 ( gtrgm_penalty  )

◆ PG_FUNCTION_INFO_V1() [10/10]

PG_FUNCTION_INFO_V1 ( gtrgm_picksplit  )

◆ sizebitvec()

static int32 sizebitvec ( BITVECP  sign)
static

Definition at line 616 of file trgm_gist.c.

References pg_popcount(), and SIGLEN.

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

617 {
618  return pg_popcount(sign, SIGLEN);
619 }
uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.c:282
char sign
Definition: informix.c:688
#define SIGLEN
Definition: hstore_gist.c:16

◆ unionkey()

static int32 unionkey ( BITVECP  sbase,
TRGM add 
)
static

Definition at line 495 of file trgm_gist.c.

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

Referenced by gtrgm_union().

496 {
497  int32 i;
498 
499  if (ISSIGNKEY(add))
500  {
501  BITVECP sadd = GETSIGN(add);
502 
503  if (ISALLTRUE(add))
504  return 1;
505 
506  LOOPBYTE
507  sbase[i] |= sadd[i];
508  }
509  else
510  {
511  trgm *ptr = GETARR(add);
512  int32 tmp = 0;
513 
514  for (i = 0; i < ARRNELEM(add); i++)
515  {
516  CPTRGM(((char *) &tmp), ptr + i);
517  HASH(sbase, tmp);
518  }
519  }
520  return 0;
521 }
#define ISSIGNKEY(x)
Definition: trgm.h:102
#define GETSIGN(x)
Definition: hstore_gist.c:51
#define HASH(sign, val)
Definition: hstore_gist.c:35
#define ARRNELEM(x)
Definition: trgm.h:108
signed int int32
Definition: c.h:346
#define GETARR(x)
Definition: trgm.h:107
#define ISALLTRUE(x)
Definition: hstore_gist.c:46
char trgm[3]
Definition: trgm.h:41
#define LOOPBYTE
Definition: hstore_gist.c:22
int i
char * BITVECP
Definition: hstore_gist.c:20
#define CPTRGM(a, b)
Definition: trgm.h:47