PostgreSQL Source Code  git master
tsvector.c File Reference
#include "postgres.h"
#include "libpq/pqformat.h"
#include "nodes/miscnodes.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "varatt.h"
Include dependency graph for tsvector.c:

Go to the source code of this file.

Data Structures

struct  WordEntryIN
 

Functions

int compareWordEntryPos (const void *a, const void *b)
 
static int uniquePos (WordEntryPos *a, int l)
 
static int compareentry (const void *va, const void *vb, void *arg)
 
static int uniqueentry (WordEntryIN *a, int l, char *buf, int *outbuflen)
 
static int WordEntryCMP (WordEntry *a, WordEntry *b, char *buf)
 
Datum tsvectorin (PG_FUNCTION_ARGS)
 
Datum tsvectorout (PG_FUNCTION_ARGS)
 
Datum tsvectorsend (PG_FUNCTION_ARGS)
 
Datum tsvectorrecv (PG_FUNCTION_ARGS)
 

Function Documentation

◆ compareentry()

static int compareentry ( const void *  va,
const void *  vb,
void *  arg 
)
static

Definition at line 85 of file tsvector.c.

86 {
87  const WordEntryIN *a = (const WordEntryIN *) va;
88  const WordEntryIN *b = (const WordEntryIN *) vb;
89  char *BufferStr = (char *) arg;
90 
91  return tsCompareString(&BufferStr[a->entry.pos], a->entry.len,
92  &BufferStr[b->entry.pos], b->entry.len,
93  false);
94 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69
void * arg
int32 tsCompareString(char *a, int lena, char *b, int lenb, bool prefix)
Definition: tsvector_op.c:1154

References a, arg, b, and tsCompareString().

Referenced by tsvectorrecv(), uniqueentry(), and WordEntryCMP().

◆ compareWordEntryPos()

int compareWordEntryPos ( const void *  a,
const void *  b 
)

Definition at line 35 of file tsvector.c.

36 {
37  int apos = WEP_GETPOS(*(const WordEntryPos *) a);
38  int bpos = WEP_GETPOS(*(const WordEntryPos *) b);
39 
40  if (apos == bpos)
41  return 0;
42  return (apos > bpos) ? 1 : -1;
43 }
#define WEP_GETPOS(x)
Definition: ts_type.h:80
uint16 WordEntryPos
Definition: ts_type.h:63

References a, b, and WEP_GETPOS.

Referenced by checkcondition_str(), and uniquePos().

◆ tsvectorin()

Datum tsvectorin ( PG_FUNCTION_ARGS  )

Definition at line 179 of file tsvector.c.

180 {
181  char *buf = PG_GETARG_CSTRING(0);
182  Node *escontext = fcinfo->context;
184  WordEntryIN *arr;
185  int totallen;
186  int arrlen; /* allocated size of arr */
187  WordEntry *inarr;
188  int len = 0;
189  TSVector in;
190  int i;
191  char *token;
192  int toklen;
193  WordEntryPos *pos;
194  int poslen;
195  char *strbuf;
196  int stroff;
197 
198  /*
199  * Tokens are appended to tmpbuf, cur is a pointer to the end of used
200  * space in tmpbuf.
201  */
202  char *tmpbuf;
203  char *cur;
204  int buflen = 256; /* allocated size of tmpbuf */
205 
206  state = init_tsvector_parser(buf, 0, escontext);
207 
208  arrlen = 64;
209  arr = (WordEntryIN *) palloc(sizeof(WordEntryIN) * arrlen);
210  cur = tmpbuf = (char *) palloc(buflen);
211 
212  while (gettoken_tsvector(state, &token, &toklen, &pos, &poslen, NULL))
213  {
214  if (toklen >= MAXSTRLEN)
215  ereturn(escontext, (Datum) 0,
216  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
217  errmsg("word is too long (%ld bytes, max %ld bytes)",
218  (long) toklen,
219  (long) (MAXSTRLEN - 1))));
220 
221  if (cur - tmpbuf > MAXSTRPOS)
222  ereturn(escontext, (Datum) 0,
223  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
224  errmsg("string is too long for tsvector (%ld bytes, max %ld bytes)",
225  (long) (cur - tmpbuf), (long) MAXSTRPOS)));
226 
227  /*
228  * Enlarge buffers if needed
229  */
230  if (len >= arrlen)
231  {
232  arrlen *= 2;
233  arr = (WordEntryIN *)
234  repalloc(arr, sizeof(WordEntryIN) * arrlen);
235  }
236  while ((cur - tmpbuf) + toklen >= buflen)
237  {
238  int dist = cur - tmpbuf;
239 
240  buflen *= 2;
241  tmpbuf = (char *) repalloc(tmpbuf, buflen);
242  cur = tmpbuf + dist;
243  }
244  arr[len].entry.len = toklen;
245  arr[len].entry.pos = cur - tmpbuf;
246  memcpy(cur, token, toklen);
247  cur += toklen;
248 
249  if (poslen != 0)
250  {
251  arr[len].entry.haspos = 1;
252  arr[len].pos = pos;
253  arr[len].poslen = poslen;
254  }
255  else
256  {
257  arr[len].entry.haspos = 0;
258  arr[len].pos = NULL;
259  arr[len].poslen = 0;
260  }
261  len++;
262  }
263 
265 
266  /* Did gettoken_tsvector fail? */
267  if (SOFT_ERROR_OCCURRED(escontext))
268  PG_RETURN_NULL();
269 
270  if (len > 0)
271  len = uniqueentry(arr, len, tmpbuf, &buflen);
272  else
273  buflen = 0;
274 
275  if (buflen > MAXSTRPOS)
276  ereturn(escontext, (Datum) 0,
277  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
278  errmsg("string is too long for tsvector (%d bytes, max %d bytes)", buflen, MAXSTRPOS)));
279 
280  totallen = CALCDATASIZE(len, buflen);
281  in = (TSVector) palloc0(totallen);
282  SET_VARSIZE(in, totallen);
283  in->size = len;
284  inarr = ARRPTR(in);
285  strbuf = STRPTR(in);
286  stroff = 0;
287  for (i = 0; i < len; i++)
288  {
289  memcpy(strbuf + stroff, &tmpbuf[arr[i].entry.pos], arr[i].entry.len);
290  arr[i].entry.pos = stroff;
291  stroff += arr[i].entry.len;
292  if (arr[i].entry.haspos)
293  {
294  /* This should be unreachable because of MAXNUMPOS restrictions */
295  if (arr[i].poslen > 0xFFFF)
296  elog(ERROR, "positions array too long");
297 
298  /* Copy number of positions */
299  stroff = SHORTALIGN(stroff);
300  *(uint16 *) (strbuf + stroff) = (uint16) arr[i].poslen;
301  stroff += sizeof(uint16);
302 
303  /* Copy positions */
304  memcpy(strbuf + stroff, arr[i].pos, arr[i].poslen * sizeof(WordEntryPos));
305  stroff += arr[i].poslen * sizeof(WordEntryPos);
306 
307  pfree(arr[i].pos);
308  }
309  inarr[i] = arr[i].entry;
310  }
311 
312  Assert((strbuf + stroff - (char *) in) == totallen);
313 
314  PG_RETURN_TSVECTOR(in);
315 }
unsigned short uint16
Definition: c.h:489
#define SHORTALIGN(LEN)
Definition: c.h:791
#define ARRPTR(x)
Definition: cube.c:25
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
#define ERROR
Definition: elog.h:39
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
#define STRPTR(x)
Definition: hstore.h:76
#define token
Definition: indent_globs.h:126
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
Definition: mcxt.c:1456
void * palloc0(Size size)
Definition: mcxt.c:1257
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1476
void * palloc(Size size)
Definition: mcxt.c:1226
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:52
const void size_t len
static char * buf
Definition: pg_test_fsync.c:67
uintptr_t Datum
Definition: postgres.h:64
Definition: nodes.h:129
int32 size
Definition: ts_type.h:93
int poslen
Definition: tsvector.c:29
WordEntryPos * pos
Definition: tsvector.c:28
WordEntry entry
Definition: tsvector.c:27
uint32 pos
Definition: ts_type.h:46
uint32 haspos
Definition: ts_type.h:44
uint32 len
Definition: ts_type.h:45
Definition: regguts.h:323
#define PG_RETURN_TSVECTOR(x)
Definition: ts_type.h:137
TSVectorData * TSVector
Definition: ts_type.h:98
#define MAXSTRLEN
Definition: ts_type.h:49
#define MAXSTRPOS
Definition: ts_type.h:50
static int uniqueentry(WordEntryIN *a, int l, char *buf, int *outbuflen)
Definition: tsvector.c:101
void close_tsvector_parser(TSVectorParseState state)
bool gettoken_tsvector(TSVectorParseState state, char **strval, int *lenval, WordEntryPos **pos_ptr, int *poslen, char **endptr)
TSVectorParseState init_tsvector_parser(char *input, int flags, Node *escontext)
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305
static StringInfoData tmpbuf
Definition: walsender.c:160

References ARRPTR, Assert(), buf, CALCDATASIZE, close_tsvector_parser(), cur, elog(), WordEntryIN::entry, ereturn, errcode(), errmsg(), ERROR, gettoken_tsvector(), WordEntry::haspos, i, init_tsvector_parser(), WordEntry::len, len, MAXSTRLEN, MAXSTRPOS, palloc(), palloc0(), pfree(), PG_GETARG_CSTRING, PG_RETURN_NULL, PG_RETURN_TSVECTOR, WordEntryIN::pos, WordEntry::pos, WordEntryIN::poslen, repalloc(), SET_VARSIZE, SHORTALIGN, TSVectorData::size, SOFT_ERROR_OCCURRED, STRPTR, tmpbuf, token, and uniqueentry().

◆ tsvectorout()

Datum tsvectorout ( PG_FUNCTION_ARGS  )

Definition at line 318 of file tsvector.c.

319 {
320  TSVector out = PG_GETARG_TSVECTOR(0);
321  char *outbuf;
322  int32 i,
323  lenbuf = 0,
324  pp;
325  WordEntry *ptr = ARRPTR(out);
326  char *curbegin,
327  *curin,
328  *curout;
329 
330  lenbuf = out->size * 2 /* '' */ + out->size - 1 /* space */ + 2 /* \0 */ ;
331  for (i = 0; i < out->size; i++)
332  {
333  lenbuf += ptr[i].len * 2 * pg_database_encoding_max_length() /* for escape */ ;
334  if (ptr[i].haspos)
335  lenbuf += 1 /* : */ + 7 /* int2 + , + weight */ * POSDATALEN(out, &(ptr[i]));
336  }
337 
338  curout = outbuf = (char *) palloc(lenbuf);
339  for (i = 0; i < out->size; i++)
340  {
341  curbegin = curin = STRPTR(out) + ptr->pos;
342  if (i != 0)
343  *curout++ = ' ';
344  *curout++ = '\'';
345  while (curin - curbegin < ptr->len)
346  {
347  int len = pg_mblen(curin);
348 
349  if (t_iseq(curin, '\''))
350  *curout++ = '\'';
351  else if (t_iseq(curin, '\\'))
352  *curout++ = '\\';
353 
354  while (len--)
355  *curout++ = *curin++;
356  }
357 
358  *curout++ = '\'';
359  if ((pp = POSDATALEN(out, ptr)) != 0)
360  {
361  WordEntryPos *wptr;
362 
363  *curout++ = ':';
364  wptr = POSDATAPTR(out, ptr);
365  while (pp)
366  {
367  curout += sprintf(curout, "%d", WEP_GETPOS(*wptr));
368  switch (WEP_GETWEIGHT(*wptr))
369  {
370  case 3:
371  *curout++ = 'A';
372  break;
373  case 2:
374  *curout++ = 'B';
375  break;
376  case 1:
377  *curout++ = 'C';
378  break;
379  case 0:
380  default:
381  break;
382  }
383 
384  if (pp > 1)
385  *curout++ = ',';
386  pp--;
387  wptr++;
388  }
389  }
390  ptr++;
391  }
392 
393  *curout = '\0';
394  PG_FREE_IF_COPY(out, 0);
395  PG_RETURN_CSTRING(outbuf);
396 }
signed int int32
Definition: c.h:478
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1553
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1024
#define sprintf
Definition: port.h:240
#define t_iseq(x, c)
Definition: ts_locale.h:38
#define PG_GETARG_TSVECTOR(n)
Definition: ts_type.h:135
#define POSDATALEN(x, e)
Definition: ts_type.h:110
#define POSDATAPTR(x, e)
Definition: ts_type.h:111
#define WEP_GETWEIGHT(x)
Definition: ts_type.h:79

References ARRPTR, i, WordEntry::len, len, palloc(), pg_database_encoding_max_length(), PG_FREE_IF_COPY, PG_GETARG_TSVECTOR, pg_mblen(), PG_RETURN_CSTRING, WordEntry::pos, POSDATALEN, POSDATAPTR, TSVectorData::size, sprintf, STRPTR, t_iseq, WEP_GETPOS, and WEP_GETWEIGHT.

◆ tsvectorrecv()

Datum tsvectorrecv ( PG_FUNCTION_ARGS  )

Definition at line 450 of file tsvector.c.

451 {
453  TSVector vec;
454  int i;
455  int32 nentries;
456  int datalen; /* number of bytes used in the variable size
457  * area after fixed size TSVector header and
458  * WordEntries */
459  Size hdrlen;
460  Size len; /* allocated size of vec */
461  bool needSort = false;
462 
463  nentries = pq_getmsgint(buf, sizeof(int32));
464  if (nentries < 0 || nentries > (MaxAllocSize / sizeof(WordEntry)))
465  elog(ERROR, "invalid size of tsvector");
466 
467  hdrlen = DATAHDRSIZE + sizeof(WordEntry) * nentries;
468 
469  len = hdrlen * 2; /* times two to make room for lexemes */
470  vec = (TSVector) palloc0(len);
471  vec->size = nentries;
472 
473  datalen = 0;
474  for (i = 0; i < nentries; i++)
475  {
476  const char *lexeme;
477  uint16 npos;
478  size_t lex_len;
479 
480  lexeme = pq_getmsgstring(buf);
481  npos = (uint16) pq_getmsgint(buf, sizeof(uint16));
482 
483  /* sanity checks */
484 
485  lex_len = strlen(lexeme);
486  if (lex_len > MAXSTRLEN)
487  elog(ERROR, "invalid tsvector: lexeme too long");
488 
489  if (datalen > MAXSTRPOS)
490  elog(ERROR, "invalid tsvector: maximum total lexeme length exceeded");
491 
492  if (npos > MAXNUMPOS)
493  elog(ERROR, "unexpected number of tsvector positions");
494 
495  /*
496  * Looks valid. Fill the WordEntry struct, and copy lexeme.
497  *
498  * But make sure the buffer is large enough first.
499  */
500  while (hdrlen + SHORTALIGN(datalen + lex_len) +
501  (npos + 1) * sizeof(WordEntryPos) >= len)
502  {
503  len *= 2;
504  vec = (TSVector) repalloc(vec, len);
505  }
506 
507  vec->entries[i].haspos = (npos > 0) ? 1 : 0;
508  vec->entries[i].len = lex_len;
509  vec->entries[i].pos = datalen;
510 
511  memcpy(STRPTR(vec) + datalen, lexeme, lex_len);
512 
513  datalen += lex_len;
514 
515  if (i > 0 && WordEntryCMP(&vec->entries[i],
516  &vec->entries[i - 1],
517  STRPTR(vec)) <= 0)
518  needSort = true;
519 
520  /* Receive positions */
521  if (npos > 0)
522  {
523  uint16 j;
524  WordEntryPos *wepptr;
525 
526  /*
527  * Pad to 2-byte alignment if necessary. Though we used palloc0
528  * for the initial allocation, subsequent repalloc'd memory areas
529  * are not initialized to zero.
530  */
531  if (datalen != SHORTALIGN(datalen))
532  {
533  *(STRPTR(vec) + datalen) = '\0';
534  datalen = SHORTALIGN(datalen);
535  }
536 
537  memcpy(STRPTR(vec) + datalen, &npos, sizeof(uint16));
538 
539  wepptr = POSDATAPTR(vec, &vec->entries[i]);
540  for (j = 0; j < npos; j++)
541  {
542  wepptr[j] = (WordEntryPos) pq_getmsgint(buf, sizeof(WordEntryPos));
543  if (j > 0 && WEP_GETPOS(wepptr[j]) <= WEP_GETPOS(wepptr[j - 1]))
544  elog(ERROR, "position information is misordered");
545  }
546 
547  datalen += (npos + 1) * sizeof(WordEntry);
548  }
549  }
550 
551  SET_VARSIZE(vec, hdrlen + datalen);
552 
553  if (needSort)
554  qsort_arg(ARRPTR(vec), vec->size, sizeof(WordEntry),
555  compareentry, STRPTR(vec));
556 
557  PG_RETURN_TSVECTOR(vec);
558 }
size_t Size
Definition: c.h:589
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
int j
Definition: isn.c:74
#define MaxAllocSize
Definition: memutils.h:40
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:418
const char * pq_getmsgstring(StringInfo msg)
Definition: pqformat.c:582
StringInfoData * StringInfo
Definition: stringinfo.h:44
WordEntry entries[FLEXIBLE_ARRAY_MEMBER]
Definition: ts_type.h:94
#define MAXNUMPOS
Definition: ts_type.h:86
#define DATAHDRSIZE
Definition: ts_type.h:100
static int compareentry(const void *va, const void *vb, void *arg)
Definition: tsvector.c:85
static int WordEntryCMP(WordEntry *a, WordEntry *b, char *buf)
Definition: tsvector.c:172

References ARRPTR, buf, compareentry(), DATAHDRSIZE, elog(), TSVectorData::entries, ERROR, WordEntry::haspos, i, j, WordEntry::len, len, MaxAllocSize, MAXNUMPOS, MAXSTRLEN, MAXSTRPOS, palloc0(), PG_GETARG_POINTER, PG_RETURN_TSVECTOR, WordEntry::pos, POSDATAPTR, pq_getmsgint(), pq_getmsgstring(), qsort_arg(), repalloc(), SET_VARSIZE, SHORTALIGN, TSVectorData::size, STRPTR, WEP_GETPOS, and WordEntryCMP().

◆ tsvectorsend()

Datum tsvectorsend ( PG_FUNCTION_ARGS  )

Definition at line 411 of file tsvector.c.

412 {
413  TSVector vec = PG_GETARG_TSVECTOR(0);
415  int i,
416  j;
417  WordEntry *weptr = ARRPTR(vec);
418 
420 
421  pq_sendint32(&buf, vec->size);
422  for (i = 0; i < vec->size; i++)
423  {
424  uint16 npos;
425 
426  /*
427  * the strings in the TSVector array are not null-terminated, so we
428  * have to send the null-terminator separately
429  */
430  pq_sendtext(&buf, STRPTR(vec) + weptr->pos, weptr->len);
431  pq_sendbyte(&buf, '\0');
432 
433  npos = POSDATALEN(vec, weptr);
434  pq_sendint16(&buf, npos);
435 
436  if (npos > 0)
437  {
438  WordEntryPos *wepptr = POSDATAPTR(vec, weptr);
439 
440  for (j = 0; j < npos; j++)
441  pq_sendint16(&buf, wepptr[j]);
442  }
443  weptr++;
444  }
445 
447 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:175
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:349
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:161
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:137

References ARRPTR, buf, i, j, WordEntry::len, PG_GETARG_TSVECTOR, PG_RETURN_BYTEA_P, WordEntry::pos, POSDATALEN, POSDATAPTR, pq_begintypsend(), pq_endtypsend(), pq_sendbyte(), pq_sendint16(), pq_sendint32(), pq_sendtext(), TSVectorData::size, and STRPTR.

◆ uniqueentry()

static int uniqueentry ( WordEntryIN a,
int  l,
char *  buf,
int *  outbuflen 
)
static

Definition at line 101 of file tsvector.c.

102 {
103  int buflen;
104  WordEntryIN *ptr,
105  *res;
106 
107  Assert(l >= 1);
108 
109  if (l > 1)
110  qsort_arg(a, l, sizeof(WordEntryIN), compareentry, buf);
111 
112  buflen = 0;
113  res = a;
114  ptr = a + 1;
115  while (ptr - a < l)
116  {
117  if (!(ptr->entry.len == res->entry.len &&
118  strncmp(&buf[ptr->entry.pos], &buf[res->entry.pos],
119  res->entry.len) == 0))
120  {
121  /* done accumulating data into *res, count space needed */
122  buflen += res->entry.len;
123  if (res->entry.haspos)
124  {
125  res->poslen = uniquePos(res->pos, res->poslen);
126  buflen = SHORTALIGN(buflen);
127  buflen += res->poslen * sizeof(WordEntryPos) + sizeof(uint16);
128  }
129  res++;
130  if (res != ptr)
131  memcpy(res, ptr, sizeof(WordEntryIN));
132  }
133  else if (ptr->entry.haspos)
134  {
135  if (res->entry.haspos)
136  {
137  /* append ptr's positions to res's positions */
138  int newlen = ptr->poslen + res->poslen;
139 
140  res->pos = (WordEntryPos *)
141  repalloc(res->pos, newlen * sizeof(WordEntryPos));
142  memcpy(&res->pos[res->poslen], ptr->pos,
143  ptr->poslen * sizeof(WordEntryPos));
144  res->poslen = newlen;
145  pfree(ptr->pos);
146  }
147  else
148  {
149  /* just give ptr's positions to pos */
150  res->entry.haspos = 1;
151  res->pos = ptr->pos;
152  res->poslen = ptr->poslen;
153  }
154  }
155  ptr++;
156  }
157 
158  /* count space needed for last item */
159  buflen += res->entry.len;
160  if (res->entry.haspos)
161  {
162  res->poslen = uniquePos(res->pos, res->poslen);
163  buflen = SHORTALIGN(buflen);
164  buflen += res->poslen * sizeof(WordEntryPos) + sizeof(uint16);
165  }
166 
167  *outbuflen = buflen;
168  return res + 1 - a;
169 }
static int uniquePos(WordEntryPos *a, int l)
Definition: tsvector.c:53

References a, Assert(), buf, compareentry(), WordEntryIN::entry, WordEntry::haspos, WordEntry::len, pfree(), WordEntryIN::pos, WordEntry::pos, WordEntryIN::poslen, qsort_arg(), repalloc(), res, SHORTALIGN, and uniquePos().

Referenced by tsvectorin().

◆ uniquePos()

static int uniquePos ( WordEntryPos a,
int  l 
)
static

Definition at line 53 of file tsvector.c.

54 {
55  WordEntryPos *ptr,
56  *res;
57 
58  if (l <= 1)
59  return l;
60 
62 
63  res = a;
64  ptr = a + 1;
65  while (ptr - a < l)
66  {
67  if (WEP_GETPOS(*ptr) != WEP_GETPOS(*res))
68  {
69  res++;
70  *res = *ptr;
71  if (res - a >= MAXNUMPOS - 1 ||
72  WEP_GETPOS(*res) == MAXENTRYPOS - 1)
73  break;
74  }
75  else if (WEP_GETWEIGHT(*ptr) > WEP_GETWEIGHT(*res))
77  ptr++;
78  }
79 
80  return res + 1 - a;
81 }
#define qsort(a, b, c, d)
Definition: port.h:445
#define MAXENTRYPOS
Definition: ts_type.h:85
#define WEP_SETWEIGHT(x, v)
Definition: ts_type.h:82
int compareWordEntryPos(const void *a, const void *b)
Definition: tsvector.c:35

References a, compareWordEntryPos(), MAXENTRYPOS, MAXNUMPOS, qsort, res, WEP_GETPOS, WEP_GETWEIGHT, and WEP_SETWEIGHT.

Referenced by uniqueentry().

◆ WordEntryCMP()

static int WordEntryCMP ( WordEntry a,
WordEntry b,
char *  buf 
)
static

Definition at line 172 of file tsvector.c.

173 {
174  return compareentry(a, b, buf);
175 }

References a, b, buf, and compareentry().

Referenced by tsvectorrecv().