PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
trgm_gist.c File Reference
#include "postgres.h"
#include "trgm.h"
#include "access/stratnum.h"
#include "fmgr.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)
 

Variables

static const uint8 number_of_ones [256]
 

Macro Definition Documentation

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

Definition at line 28 of file trgm_gist.c.

Referenced by gtrgm_picksplit(), and gtrgm_union().

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

Definition at line 740 of file trgm_gist.c.

Referenced by gtrgm_picksplit().

Function Documentation

static int32 cnt_sml_sign_common ( TRGM qtrg,
BITVECP  sign 
)
static

Definition at line 163 of file trgm_gist.c.

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

Referenced by gtrgm_consistent(), and gtrgm_distance().

164 {
165  int32 count = 0;
166  int32 k,
167  len = ARRNELEM(qtrg);
168  trgm *ptr = GETARR(qtrg);
169  int32 tmp = 0;
170 
171  for (k = 0; k < len; k++)
172  {
173  CPTRGM(((char *) &tmp), ptr + k);
174  count += GETBIT(sign, HASHVAL(tmp));
175  }
176 
177  return count;
178 }
#define ARRNELEM(x)
Definition: trgm.h:105
signed int int32
Definition: c.h:253
#define GETARR(x)
Definition: trgm.h:104
#define GETBIT(x, i)
Definition: blutils.c:34
char sign
Definition: informix.c:693
#define HASHVAL(val)
Definition: hstore_gist.c:37
char trgm[3]
Definition: trgm.h:38
#define CPTRGM(a, b)
Definition: trgm.h:44
static int comparecost ( const void *  a,
const void *  b 
)
static

Definition at line 748 of file trgm_gist.c.

Referenced by gtrgm_picksplit().

749 {
750  if (((const SPLITCOST *) a)->cost == ((const SPLITCOST *) b)->cost)
751  return 0;
752  else
753  return (((const SPLITCOST *) a)->cost > ((const SPLITCOST *) b)->cost) ? 1 : -1;
754 }
static void fillcache ( CACHESIGN item,
TRGM key 
)
static

Definition at line 729 of file trgm_gist.c.

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

Referenced by gtrgm_picksplit().

730 {
731  item->allistrue = false;
732  if (ISARRKEY(key))
733  makesign(item->sign, key);
734  else if (ISALLTRUE(key))
735  item->allistrue = true;
736  else
737  memcpy((void *) item->sign, (void *) GETSIGN(key), sizeof(BITVEC));
738 }
#define GETSIGN(x)
Definition: hstore_gist.c:54
#define ISARRKEY(x)
Definition: trgm.h:98
static void makesign(BITVECP sign, TRGM *a)
Definition: trgm_gist.c:78
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
BITVEC sign
Definition: trgm_gist.c:725
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
bool allistrue
Definition: trgm_gist.c:724
Datum gtrgm_compress ( PG_FUNCTION_ARGS  )

Definition at line 95 of file trgm_gist.c.

References ALLISTRUE, CALCGTSIZE, DatumGetPointer, DatumGetTextP, FALSE, 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, VARHDRSZ, and VARSIZE.

96 {
97  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
98  GISTENTRY *retval = entry;
99 
100  if (entry->leafkey)
101  { /* trgm */
102  TRGM *res;
103  text *val = DatumGetTextP(entry->key);
104 
105  res = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
106  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
107  gistentryinit(*retval, PointerGetDatum(res),
108  entry->rel, entry->page,
109  entry->offset, FALSE);
110  }
111  else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
112  !ISALLTRUE(DatumGetPointer(entry->key)))
113  {
114  int32 i,
115  len;
116  TRGM *res;
118 
119  LOOPBYTE
120  {
121  if ((sign[i] & 0xff) != 0xff)
122  PG_RETURN_POINTER(retval);
123  }
124 
125  len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0);
126  res = (TRGM *) palloc(len);
127  SET_VARSIZE(res, len);
128  res->flag = SIGNKEY | ALLISTRUE;
129 
130  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
131  gistentryinit(*retval, PointerGetDatum(res),
132  entry->rel, entry->page,
133  entry->offset, FALSE);
134  }
135  PG_RETURN_POINTER(retval);
136 }
Relation rel
Definition: gist.h:124
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
#define VARDATA(PTR)
Definition: postgres.h:305
#define VARSIZE(PTR)
Definition: postgres.h:306
#define ISSIGNKEY(x)
Definition: trgm.h:99
#define GETSIGN(x)
Definition: hstore_gist.c:54
#define PointerGetDatum(X)
Definition: postgres.h:564
#define VARHDRSZ
Definition: c.h:441
#define ALLISTRUE
Definition: hstore_gist.c:47
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
signed int int32
Definition: c.h:253
Page page
Definition: gist.h:125
Definition: trgm.h:63
#define FALSE
Definition: c.h:218
char sign
Definition: informix.c:693
Datum key
Definition: gist.h:123
bool leafkey
Definition: gist.h:127
#define SIGNKEY
Definition: trgm.h:95
uint8 flag
Definition: trgm.h:66
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
#define CALCGTSIZE(flag)
Definition: hstore_gist.c:52
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:169
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:321
#define DatumGetTextP(X)
Definition: fmgr.h:248
#define DatumGetPointer(X)
Definition: postgres.h:557
void * palloc(Size size)
Definition: mcxt.c:891
#define LOOPBYTE
Definition: hstore_gist.c:25
int i
Definition: c.h:435
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
char * BITVECP
Definition: hstore_gist.c:20
OffsetNumber offset
Definition: gist.h:126
long val
Definition: informix.c:689
Datum gtrgm_consistent ( PG_FUNCTION_ARGS  )

Definition at line 181 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, ISALLTRUE, GISTENTRY::key, LikeStrategyNumber, MAXALIGN, MemoryContextAlloc(), NULL, 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, similarity_threshold, SimilarityStrategyNumber, gtrgm_consistent_cache::strategy, trgm_contained_by(), trgm_presence_map(), gtrgm_consistent_cache::trigrams, trigramsMatchGraph(), VARDATA, VARHDRSZ, VARSIZE, word_similarity_threshold, and WordSimilarityStrategyNumber.

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

Definition at line 139 of file trgm_gist.c.

References DatumGetPointer, DatumGetTextP, gistentryinit, GISTENTRY::key, GISTENTRY::leafkey, GISTENTRY::offset, GISTENTRY::page, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, and GISTENTRY::rel.

140 {
141  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
142  GISTENTRY *retval;
143  text *key;
144 
145  key = DatumGetTextP(entry->key);
146 
147  if (key != (text *) DatumGetPointer(entry->key))
148  {
149  /* need to pass back the decompressed item */
150  retval = palloc(sizeof(GISTENTRY));
151  gistentryinit(*retval, PointerGetDatum(key),
152  entry->rel, entry->page, entry->offset, entry->leafkey);
153  PG_RETURN_POINTER(retval);
154  }
155  else
156  {
157  /* we can return the entry as-is */
158  PG_RETURN_POINTER(entry);
159  }
160 }
Relation rel
Definition: gist.h:124
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
#define PointerGetDatum(X)
Definition: postgres.h:564
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
Page page
Definition: gist.h:125
Datum key
Definition: gist.h:123
bool leafkey
Definition: gist.h:127
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:169
#define DatumGetTextP(X)
Definition: fmgr.h:248
#define DatumGetPointer(X)
Definition: postgres.h:557
void * palloc(Size size)
Definition: mcxt.c:891
Definition: c.h:435
OffsetNumber offset
Definition: gist.h:126
Datum gtrgm_distance ( PG_FUNCTION_ARGS  )

Definition at line 426 of file trgm_gist.c.

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

427 {
428  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
429  text *query = PG_GETARG_TEXT_P(1);
431 
432  /* Oid subtype = PG_GETARG_OID(3); */
433  bool *recheck = (bool *) PG_GETARG_POINTER(4);
434  TRGM *key = (TRGM *) DatumGetPointer(entry->key);
435  TRGM *qtrg;
436  float8 res;
437  Size querysize = VARSIZE(query);
438  char *cache = (char *) fcinfo->flinfo->fn_extra;
439 
440  /*
441  * Cache the generated trigrams across multiple calls with the same query.
442  */
443  if (cache == NULL ||
444  VARSIZE(cache) != querysize ||
445  memcmp(cache, query, querysize) != 0)
446  {
447  char *newcache;
448 
449  qtrg = generate_trgm(VARDATA(query), querysize - VARHDRSZ);
450 
451  newcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
452  MAXALIGN(querysize) +
453  VARSIZE(qtrg));
454 
455  memcpy(newcache, query, querysize);
456  memcpy(newcache + MAXALIGN(querysize), qtrg, VARSIZE(qtrg));
457 
458  if (cache)
459  pfree(cache);
460  fcinfo->flinfo->fn_extra = newcache;
461  cache = newcache;
462  }
463 
464  qtrg = (TRGM *) (cache + MAXALIGN(querysize));
465 
466  switch (strategy)
467  {
470  *recheck = strategy == WordDistanceStrategyNumber;
471  if (GIST_LEAF(entry))
472  { /* all leafs contains orig trgm */
473 
474  /*
475  * Prevent gcc optimizing the sml variable using volatile
476  * keyword. Otherwise res can differ from the
477  * word_similarity_dist_op() function.
478  */
479  float4 volatile sml = cnt_sml(qtrg, key, *recheck);
480 
481  res = 1.0 - sml;
482  }
483  else if (ISALLTRUE(key))
484  { /* all leafs contains orig trgm */
485  res = 0.0;
486  }
487  else
488  { /* non-leaf contains signature */
489  int32 count = cnt_sml_sign_common(qtrg, GETSIGN(key));
490  int32 len = ARRNELEM(qtrg);
491 
492  res = (len == 0) ? -1.0 : 1.0 - ((float8) count) / ((float8) len);
493  }
494  break;
495  default:
496  elog(ERROR, "unrecognized strategy number: %d", strategy);
497  res = 0; /* keep compiler quiet */
498  break;
499  }
500 
501  PG_RETURN_FLOAT8(res);
502 }
#define GIST_LEAF(entry)
Definition: gist.h:133
#define VARDATA(PTR)
Definition: postgres.h:305
static int32 cnt_sml_sign_common(TRGM *qtrg, BITVECP sign)
Definition: trgm_gist.c:163
#define VARSIZE(PTR)
Definition: postgres.h:306
#define GETSIGN(x)
Definition: hstore_gist.c:54
#define DistanceStrategyNumber
Definition: trgm.h:30
#define VARHDRSZ
Definition: c.h:441
#define WordDistanceStrategyNumber
Definition: trgm.h:36
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:310
uint16 StrategyNumber
Definition: stratnum.h:22
float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
Definition: trgm_op.c:928
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
#define ARRNELEM(x)
Definition: trgm.h:105
signed int int32
Definition: c.h:253
void pfree(void *pointer)
Definition: mcxt.c:992
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:378
Definition: trgm.h:63
Datum key
Definition: gist.h:123
float float4
Definition: c.h:377
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
#define NULL
Definition: c.h:226
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:321
size_t Size
Definition: c.h:353
#define MAXALIGN(LEN)
Definition: c.h:584
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:228
#define DatumGetPointer(X)
Definition: postgres.h:557
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
Definition: c.h:435
#define elog
Definition: elog.h:219
Datum gtrgm_in ( PG_FUNCTION_ARGS  )

Definition at line 64 of file trgm_gist.c.

References elog, ERROR, and PG_RETURN_DATUM.

65 {
66  elog(ERROR, "not implemented");
67  PG_RETURN_DATUM(0);
68 }
#define ERROR
Definition: elog.h:43
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
#define elog
Definition: elog.h:219
Datum gtrgm_out ( PG_FUNCTION_ARGS  )

Definition at line 71 of file trgm_gist.c.

References elog, ERROR, and PG_RETURN_DATUM.

72 {
73  elog(ERROR, "not implemented");
74  PG_RETURN_DATUM(0);
75 }
#define ERROR
Definition: elog.h:43
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
#define elog
Definition: elog.h:219
Datum gtrgm_penalty ( PG_FUNCTION_ARGS  )

Definition at line 668 of file trgm_gist.c.

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

669 {
670  GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
671  GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
672  float *penalty = (float *) PG_GETARG_POINTER(2);
673  TRGM *origval = (TRGM *) DatumGetPointer(origentry->key);
674  TRGM *newval = (TRGM *) DatumGetPointer(newentry->key);
675  BITVECP orig = GETSIGN(origval);
676 
677  *penalty = 0.0;
678 
679  if (ISARRKEY(newval))
680  {
681  char *cache = (char *) fcinfo->flinfo->fn_extra;
682  TRGM *cachedVal = (TRGM *) (cache + MAXALIGN(sizeof(BITVEC)));
683  Size newvalsize = VARSIZE(newval);
684  BITVECP sign;
685 
686  /*
687  * Cache the sign data across multiple calls with the same newval.
688  */
689  if (cache == NULL ||
690  VARSIZE(cachedVal) != newvalsize ||
691  memcmp(cachedVal, newval, newvalsize) != 0)
692  {
693  char *newcache;
694 
695  newcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
696  MAXALIGN(sizeof(BITVEC)) +
697  newvalsize);
698 
699  makesign((BITVECP) newcache, newval);
700 
701  cachedVal = (TRGM *) (newcache + MAXALIGN(sizeof(BITVEC)));
702  memcpy(cachedVal, newval, newvalsize);
703 
704  if (cache)
705  pfree(cache);
706  fcinfo->flinfo->fn_extra = newcache;
707  cache = newcache;
708  }
709 
710  sign = (BITVECP) cache;
711 
712  if (ISALLTRUE(origval))
713  *penalty = ((float) (SIGLENBIT - sizebitvec(sign))) / (float) (SIGLENBIT + 1);
714  else
715  *penalty = hemdistsign(sign, orig);
716  }
717  else
718  *penalty = hemdist(origval, newval);
719  PG_RETURN_POINTER(penalty);
720 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
static int hemdist(TRGM *a, TRGM *b)
Definition: trgm_gist.c:652
#define VARSIZE(PTR)
Definition: postgres.h:306
#define GETSIGN(x)
Definition: hstore_gist.c:54
#define SIGLENBIT
Definition: hstore_gist.c:17
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
#define ISARRKEY(x)
Definition: trgm.h:98
void pfree(void *pointer)
Definition: mcxt.c:992
Definition: trgm.h:63
static void makesign(BITVECP sign, TRGM *a)
Definition: trgm_gist.c:78
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
char sign
Definition: informix.c:693
Datum key
Definition: gist.h:123
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
static int hemdistsign(BITVECP a, BITVECP b)
Definition: trgm_gist.c:637
#define NULL
Definition: c.h:226
size_t Size
Definition: c.h:353
#define newval
#define MAXALIGN(LEN)
Definition: c.h:584
#define DatumGetPointer(X)
Definition: postgres.h:557
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
char * BITVECP
Definition: hstore_gist.c:20
static int32 sizebitvec(BITVECP sign)
Definition: trgm_gist.c:626
Datum gtrgm_picksplit ( PG_FUNCTION_ARGS  )

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

775 {
777  OffsetNumber maxoff = entryvec->n - 2;
779  OffsetNumber k,
780  j;
781  TRGM *datum_l,
782  *datum_r;
783  BITVECP union_l,
784  union_r;
785  int32 size_alpha,
786  size_beta;
787  int32 size_waste,
788  waste = -1;
789  int32 nbytes;
790  OffsetNumber seed_1 = 0,
791  seed_2 = 0;
792  OffsetNumber *left,
793  *right;
794  BITVECP ptr;
795  int i;
796  CACHESIGN *cache;
797  SPLITCOST *costvector;
798 
799  /* cache the sign data for each existing item */
800  cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2));
801  for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k))
802  fillcache(&cache[k], GETENTRY(entryvec, k));
803 
804  /* now find the two furthest-apart items */
805  for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
806  {
807  for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
808  {
809  size_waste = hemdistcache(&(cache[j]), &(cache[k]));
810  if (size_waste > waste)
811  {
812  waste = size_waste;
813  seed_1 = k;
814  seed_2 = j;
815  }
816  }
817  }
818 
819  /* just in case we didn't make a selection ... */
820  if (seed_1 == 0 || seed_2 == 0)
821  {
822  seed_1 = 1;
823  seed_2 = 2;
824  }
825 
826  /* initialize the result vectors */
827  nbytes = (maxoff + 2) * sizeof(OffsetNumber);
828  v->spl_left = left = (OffsetNumber *) palloc(nbytes);
829  v->spl_right = right = (OffsetNumber *) palloc(nbytes);
830  v->spl_nleft = 0;
831  v->spl_nright = 0;
832 
833  /* form initial .. */
834  if (cache[seed_1].allistrue)
835  {
836  datum_l = (TRGM *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
837  SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
838  datum_l->flag = SIGNKEY | ALLISTRUE;
839  }
840  else
841  {
842  datum_l = (TRGM *) palloc(CALCGTSIZE(SIGNKEY, 0));
843  SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY, 0));
844  datum_l->flag = SIGNKEY;
845  memcpy((void *) GETSIGN(datum_l), (void *) cache[seed_1].sign, sizeof(BITVEC));
846  }
847  if (cache[seed_2].allistrue)
848  {
849  datum_r = (TRGM *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
850  SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
851  datum_r->flag = SIGNKEY | ALLISTRUE;
852  }
853  else
854  {
855  datum_r = (TRGM *) palloc(CALCGTSIZE(SIGNKEY, 0));
856  SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY, 0));
857  datum_r->flag = SIGNKEY;
858  memcpy((void *) GETSIGN(datum_r), (void *) cache[seed_2].sign, sizeof(BITVEC));
859  }
860 
861  union_l = GETSIGN(datum_l);
862  union_r = GETSIGN(datum_r);
863  maxoff = OffsetNumberNext(maxoff);
864  fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff));
865  /* sort before ... */
866  costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
867  for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
868  {
869  costvector[j - 1].pos = j;
870  size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]));
871  size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]));
872  costvector[j - 1].cost = abs(size_alpha - size_beta);
873  }
874  qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
875 
876  for (k = 0; k < maxoff; k++)
877  {
878  j = costvector[k].pos;
879  if (j == seed_1)
880  {
881  *left++ = j;
882  v->spl_nleft++;
883  continue;
884  }
885  else if (j == seed_2)
886  {
887  *right++ = j;
888  v->spl_nright++;
889  continue;
890  }
891 
892  if (ISALLTRUE(datum_l) || cache[j].allistrue)
893  {
894  if (ISALLTRUE(datum_l) && cache[j].allistrue)
895  size_alpha = 0;
896  else
897  size_alpha = SIGLENBIT - sizebitvec(
898  (cache[j].allistrue) ? GETSIGN(datum_l) : GETSIGN(cache[j].sign)
899  );
900  }
901  else
902  size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l));
903 
904  if (ISALLTRUE(datum_r) || cache[j].allistrue)
905  {
906  if (ISALLTRUE(datum_r) && cache[j].allistrue)
907  size_beta = 0;
908  else
909  size_beta = SIGLENBIT - sizebitvec(
910  (cache[j].allistrue) ? GETSIGN(datum_r) : GETSIGN(cache[j].sign)
911  );
912  }
913  else
914  size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r));
915 
916  if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
917  {
918  if (ISALLTRUE(datum_l) || cache[j].allistrue)
919  {
920  if (!ISALLTRUE(datum_l))
921  MemSet((void *) GETSIGN(datum_l), 0xff, sizeof(BITVEC));
922  }
923  else
924  {
925  ptr = cache[j].sign;
926  LOOPBYTE
927  union_l[i] |= ptr[i];
928  }
929  *left++ = j;
930  v->spl_nleft++;
931  }
932  else
933  {
934  if (ISALLTRUE(datum_r) || cache[j].allistrue)
935  {
936  if (!ISALLTRUE(datum_r))
937  MemSet((void *) GETSIGN(datum_r), 0xff, sizeof(BITVEC));
938  }
939  else
940  {
941  ptr = cache[j].sign;
942  LOOPBYTE
943  union_r[i] |= ptr[i];
944  }
945  *right++ = j;
946  v->spl_nright++;
947  }
948  }
949 
950  *right = *left = FirstOffsetNumber;
951  v->spl_ldatum = PointerGetDatum(datum_l);
952  v->spl_rdatum = PointerGetDatum(datum_r);
953 
955 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
OffsetNumber pos
Definition: hstore_gist.c:323
#define GETSIGN(x)
Definition: hstore_gist.c:54
#define PointerGetDatum(X)
Definition: postgres.h:564
#define SIGLENBIT
Definition: hstore_gist.c:17
static int hemdistcache(CACHESIGN *a, CACHESIGN *b)
Definition: trgm_gist.c:758
OffsetNumber * spl_left
Definition: gist.h:105
Datum spl_rdatum
Definition: gist.h:112
int32 n
Definition: gist.h:160
static int comparecost(const void *a, const void *b)
Definition: trgm_gist.c:748
#define ALLISTRUE
Definition: hstore_gist.c:47
#define MemSet(start, val, len)
Definition: c.h:853
static void fillcache(CACHESIGN *item, TRGM *key)
Definition: trgm_gist.c:729
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
int spl_nleft
Definition: gist.h:106
signed int int32
Definition: c.h:253
int32 cost
Definition: hstore_gist.c:324
#define WISH_F(a, b, c)
Definition: trgm_gist.c:740
uint16 OffsetNumber
Definition: off.h:24
Definition: trgm.h:63
int spl_nright
Definition: gist.h:111
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
BITVEC sign
Definition: trgm_gist.c:725
char sign
Definition: informix.c:693
#define FirstOffsetNumber
Definition: off.h:27
#define SIGNKEY
Definition: trgm.h:95
#define GETENTRY(vec, pos)
Definition: trgm_gist.c:28
uint8 flag
Definition: trgm.h:66
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
static int hemdistsign(BITVECP a, BITVECP b)
Definition: trgm_gist.c:637
#define CALCGTSIZE(flag)
Definition: hstore_gist.c:52
Datum spl_ldatum
Definition: gist.h:107
#define OffsetNumberNext(offsetNumber)
Definition: off.h:53
OffsetNumber * spl_right
Definition: gist.h:110
void * palloc(Size size)
Definition: mcxt.c:891
#define LOOPBYTE
Definition: hstore_gist.c:25
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
char * BITVECP
Definition: hstore_gist.c:20
#define qsort(a, b, c, d)
Definition: port.h:440
static int32 sizebitvec(BITVECP sign)
Definition: trgm_gist.c:626
Datum gtrgm_same ( PG_FUNCTION_ARGS  )

Definition at line 568 of file trgm_gist.c.

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

569 {
570  TRGM *a = (TRGM *) PG_GETARG_POINTER(0);
571  TRGM *b = (TRGM *) PG_GETARG_POINTER(1);
572  bool *result = (bool *) PG_GETARG_POINTER(2);
573 
574  if (ISSIGNKEY(a))
575  { /* then b also ISSIGNKEY */
576  if (ISALLTRUE(a) && ISALLTRUE(b))
577  *result = true;
578  else if (ISALLTRUE(a))
579  *result = false;
580  else if (ISALLTRUE(b))
581  *result = false;
582  else
583  {
584  int32 i;
585  BITVECP sa = GETSIGN(a),
586  sb = GETSIGN(b);
587 
588  *result = true;
589  LOOPBYTE
590  {
591  if (sa[i] != sb[i])
592  {
593  *result = false;
594  break;
595  }
596  }
597  }
598  }
599  else
600  { /* a and b ISARRKEY */
601  int32 lena = ARRNELEM(a),
602  lenb = ARRNELEM(b);
603 
604  if (lena != lenb)
605  *result = false;
606  else
607  {
608  trgm *ptra = GETARR(a),
609  *ptrb = GETARR(b);
610  int32 i;
611 
612  *result = true;
613  for (i = 0; i < lena; i++)
614  if (CMPTRGM(ptra + i, ptrb + i))
615  {
616  *result = false;
617  break;
618  }
619  }
620  }
621 
622  PG_RETURN_POINTER(result);
623 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
#define CMPTRGM(a, b)
Definition: trgm.h:42
#define ISSIGNKEY(x)
Definition: trgm.h:99
#define GETSIGN(x)
Definition: hstore_gist.c:54
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
#define ARRNELEM(x)
Definition: trgm.h:105
signed int int32
Definition: c.h:253
#define GETARR(x)
Definition: trgm.h:104
Definition: trgm.h:63
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
char trgm[3]
Definition: trgm.h:38
#define LOOPBYTE
Definition: hstore_gist.c:25
int i
char * BITVECP
Definition: hstore_gist.c:20
Datum gtrgm_union ( PG_FUNCTION_ARGS  )

Definition at line 535 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().

536 {
538  int32 len = entryvec->n;
539  int *size = (int *) PG_GETARG_POINTER(1);
540  BITVEC base;
541  int32 i;
542  int32 flag = 0;
543  TRGM *result;
544 
545  MemSet((void *) base, 0, sizeof(BITVEC));
546  for (i = 0; i < len; i++)
547  {
548  if (unionkey(base, GETENTRY(entryvec, i)))
549  {
550  flag = ALLISTRUE;
551  break;
552  }
553  }
554 
555  flag |= SIGNKEY;
556  len = CALCGTSIZE(flag, 0);
557  result = (TRGM *) palloc(len);
558  SET_VARSIZE(result, len);
559  result->flag = flag;
560  if (!ISALLTRUE(result))
561  memcpy((void *) GETSIGN(result), (void *) base, sizeof(BITVEC));
562  *size = len;
563 
564  PG_RETURN_POINTER(result);
565 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
#define GETSIGN(x)
Definition: hstore_gist.c:54
int32 n
Definition: gist.h:160
#define ALLISTRUE
Definition: hstore_gist.c:47
#define MemSet(start, val, len)
Definition: c.h:853
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
signed int int32
Definition: c.h:253
static int32 unionkey(BITVECP sbase, TRGM *add)
Definition: trgm_gist.c:505
Definition: trgm.h:63
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
char * flag(int b)
Definition: test-ctype.c:33
#define SIGNKEY
Definition: trgm.h:95
#define GETENTRY(vec, pos)
Definition: trgm_gist.c:28
uint8 flag
Definition: trgm.h:66
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
#define CALCGTSIZE(flag)
Definition: hstore_gist.c:52
void * palloc(Size size)
Definition: mcxt.c:891
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
static int hemdist ( TRGM a,
TRGM b 
)
static

Definition at line 652 of file trgm_gist.c.

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

Referenced by gtrgm_penalty().

653 {
654  if (ISALLTRUE(a))
655  {
656  if (ISALLTRUE(b))
657  return 0;
658  else
659  return SIGLENBIT - sizebitvec(GETSIGN(b));
660  }
661  else if (ISALLTRUE(b))
662  return SIGLENBIT - sizebitvec(GETSIGN(a));
663 
664  return hemdistsign(GETSIGN(a), GETSIGN(b));
665 }
#define GETSIGN(x)
Definition: hstore_gist.c:54
#define SIGLENBIT
Definition: hstore_gist.c:17
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
static int hemdistsign(BITVECP a, BITVECP b)
Definition: trgm_gist.c:637
static int32 sizebitvec(BITVECP sign)
Definition: trgm_gist.c:626
static int hemdistcache ( CACHESIGN a,
CACHESIGN b 
)
static

Definition at line 758 of file trgm_gist.c.

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

Referenced by gtrgm_picksplit().

759 {
760  if (a->allistrue)
761  {
762  if (b->allistrue)
763  return 0;
764  else
765  return SIGLENBIT - sizebitvec(b->sign);
766  }
767  else if (b->allistrue)
768  return SIGLENBIT - sizebitvec(a->sign);
769 
770  return hemdistsign(a->sign, b->sign);
771 }
#define SIGLENBIT
Definition: hstore_gist.c:17
BITVEC sign
Definition: trgm_gist.c:725
static int hemdistsign(BITVECP a, BITVECP b)
Definition: trgm_gist.c:637
bool allistrue
Definition: trgm_gist.c:724
static int32 sizebitvec(BITVECP sign)
Definition: trgm_gist.c:626
static int hemdistsign ( BITVECP  a,
BITVECP  b 
)
static

Definition at line 637 of file trgm_gist.c.

References i, LOOPBYTE, and number_of_ones.

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

638 {
639  int i,
640  diff,
641  dist = 0;
642 
643  LOOPBYTE
644  {
645  diff = (unsigned char) (a[i] ^ b[i]);
646  dist += number_of_ones[diff];
647  }
648  return dist;
649 }
static const uint8 number_of_ones[256]
Definition: trgm_gist.c:43
#define LOOPBYTE
Definition: hstore_gist.c:25
int i
static void makesign ( BITVECP  sign,
TRGM a 
)
static

Definition at line 78 of file trgm_gist.c.

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

Referenced by fillcache(), and gtrgm_penalty().

79 {
80  int32 k,
81  len = ARRNELEM(a);
82  trgm *ptr = GETARR(a);
83  int32 tmp = 0;
84 
85  MemSet((void *) sign, 0, sizeof(BITVEC));
86  SETBIT(sign, SIGLENBIT); /* set last unused bit */
87  for (k = 0; k < len; k++)
88  {
89  CPTRGM(((char *) &tmp), ptr + k);
90  HASH(sign, tmp);
91  }
92 }
#define SETBIT(x, i)
Definition: blutils.c:33
#define SIGLENBIT
Definition: hstore_gist.c:17
#define MemSet(start, val, len)
Definition: c.h:853
#define HASH(sign, val)
Definition: hstore_gist.c:38
#define ARRNELEM(x)
Definition: trgm.h:105
signed int int32
Definition: c.h:253
#define GETARR(x)
Definition: trgm.h:104
char BITVEC[SIGLEN]
Definition: hstore_gist.c:19
char sign
Definition: informix.c:693
char trgm[3]
Definition: trgm.h:38
#define CPTRGM(a, b)
Definition: trgm.h:44
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  )
static int32 sizebitvec ( BITVECP  sign)
static

Definition at line 626 of file trgm_gist.c.

References i, LOOPBYTE, and number_of_ones.

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

627 {
628  int32 size = 0,
629  i;
630 
631  LOOPBYTE
632  size += number_of_ones[(unsigned char) sign[i]];
633  return size;
634 }
static const uint8 number_of_ones[256]
Definition: trgm_gist.c:43
signed int int32
Definition: c.h:253
char sign
Definition: informix.c:693
#define LOOPBYTE
Definition: hstore_gist.c:25
int i
static int32 unionkey ( BITVECP  sbase,
TRGM add 
)
static

Definition at line 505 of file trgm_gist.c.

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

Referenced by gtrgm_union().

506 {
507  int32 i;
508 
509  if (ISSIGNKEY(add))
510  {
511  BITVECP sadd = GETSIGN(add);
512 
513  if (ISALLTRUE(add))
514  return 1;
515 
516  LOOPBYTE
517  sbase[i] |= sadd[i];
518  }
519  else
520  {
521  trgm *ptr = GETARR(add);
522  int32 tmp = 0;
523 
524  for (i = 0; i < ARRNELEM(add); i++)
525  {
526  CPTRGM(((char *) &tmp), ptr + i);
527  HASH(sbase, tmp);
528  }
529  }
530  return 0;
531 }
#define ISSIGNKEY(x)
Definition: trgm.h:99
#define GETSIGN(x)
Definition: hstore_gist.c:54
#define HASH(sign, val)
Definition: hstore_gist.c:38
#define ARRNELEM(x)
Definition: trgm.h:105
signed int int32
Definition: c.h:253
#define GETARR(x)
Definition: trgm.h:104
#define ISALLTRUE(x)
Definition: hstore_gist.c:49
char trgm[3]
Definition: trgm.h:38
#define LOOPBYTE
Definition: hstore_gist.c:25
int i
char * BITVECP
Definition: hstore_gist.c:20
#define CPTRGM(a, b)
Definition: trgm.h:44

Variable Documentation

const uint8 number_of_ones[256]
static
Initial value:
= {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
}

Definition at line 43 of file trgm_gist.c.

Referenced by hemdistsign(), and sizebitvec().