PostgreSQL Source Code git master
Loading...
Searching...
No Matches
tsrank.c File Reference
#include "postgres.h"
#include <limits.h>
#include <math.h>
#include "miscadmin.h"
#include "tsearch/ts_utils.h"
#include "utils/array.h"
#include "utils/fmgrprotos.h"
Include dependency graph for tsrank.c:

Go to the source code of this file.

Data Structures

struct  DocRepresentation
 
struct  QueryRepresentationOperand
 
struct  QueryRepresentation
 
struct  CoverExt
 

Macros

#define NUM_WEIGHTS   4
 
#define wpos(wep)   ( w[ WEP_GETWEIGHT(wep) ] )
 
#define RANK_NO_NORM   0x00
 
#define RANK_NORM_LOGLENGTH   0x01
 
#define RANK_NORM_LENGTH   0x02
 
#define RANK_NORM_EXTDIST   0x04
 
#define RANK_NORM_UNIQ   0x08
 
#define RANK_NORM_LOGUNIQ   0x10
 
#define RANK_NORM_RDIVRPLUS1   0x20
 
#define DEF_NORM_METHOD   RANK_NO_NORM
 
#define WordECompareQueryItem(e, q, p, i, m)
 
#define MAXQROPOS   MAXENTRYPOS
 
#define QR_GET_OPERAND_DATA(q, v)    ( (q)->operandData + (((QueryItem*)(v)) - GETQUERY((q)->query)) )
 

Functions

static float calc_rank_or (const float *w, TSVector t, TSQuery q)
 
static float calc_rank_and (const float *w, TSVector t, TSQuery q)
 
static float4 word_distance (int32 w)
 
static int cnt_length (TSVector t)
 
static WordEntryfind_wordentry (TSVector t, TSQuery q, QueryOperand *item, int32 *nitem)
 
static int compareQueryOperand (const void *a, const void *b, void *arg)
 
static QueryOperand ** SortAndUniqItems (TSQuery q, int *size)
 
static float calc_rank (const float *w, TSVector t, TSQuery q, int32 method)
 
static void getWeights (ArrayType *win, float *ws)
 
Datum ts_rank_wttf (PG_FUNCTION_ARGS)
 
Datum ts_rank_wtt (PG_FUNCTION_ARGS)
 
Datum ts_rank_ttf (PG_FUNCTION_ARGS)
 
Datum ts_rank_tt (PG_FUNCTION_ARGS)
 
static int compareDocR (const void *va, const void *vb)
 
static TSTernaryValue checkcondition_QueryOperand (void *checkval, QueryOperand *val, ExecPhraseData *data)
 
static void resetQueryRepresentation (QueryRepresentation *qr, bool reverseinsert)
 
static void fillQueryRepresentationData (QueryRepresentation *qr, DocRepresentation *entry)
 
static bool Cover (DocRepresentation *doc, int len, QueryRepresentation *qr, CoverExt *ext)
 
static DocRepresentationget_docrep (TSVector txt, QueryRepresentation *qr, int *doclen)
 
static float4 calc_rank_cd (const float4 *arrdata, TSVector txt, TSQuery query, int method)
 
Datum ts_rankcd_wttf (PG_FUNCTION_ARGS)
 
Datum ts_rankcd_wtt (PG_FUNCTION_ARGS)
 
Datum ts_rankcd_ttf (PG_FUNCTION_ARGS)
 
Datum ts_rankcd_tt (PG_FUNCTION_ARGS)
 

Variables

static const float default_weights [NUM_WEIGHTS] = {0.1f, 0.2f, 0.4f, 1.0f}
 

Macro Definition Documentation

◆ DEF_NORM_METHOD

#define DEF_NORM_METHOD   RANK_NO_NORM

Definition at line 36 of file tsrank.c.

◆ MAXQROPOS

#define MAXQROPOS   MAXENTRYPOS

Definition at line 568 of file tsrank.c.

◆ NUM_WEIGHTS

#define NUM_WEIGHTS   4

Definition at line 24 of file tsrank.c.

◆ QR_GET_OPERAND_DATA

#define QR_GET_OPERAND_DATA (   q,
 
)     ( (q)->operandData + (((QueryItem*)(v)) - GETQUERY((q)->query)) )

Definition at line 584 of file tsrank.c.

592{
595
596 if (!opData->operandexists)
597 return TS_NO;
598
599 if (data)
600 {
601 data->npos = opData->npos;
602 data->pos = opData->pos;
603 if (opData->reverseinsert)
604 data->pos += MAXQROPOS - opData->npos;
605 }
606
607 return TS_YES;
608}
609
610typedef struct
611{
612 int pos;
613 int p;
614 int q;
615 DocRepresentation *begin;
617} CoverExt;
618
619static void
621{
622 int i;
623
624 for (i = 0; i < qr->query->size; i++)
625 {
626 qr->operandData[i].operandexists = false;
627 qr->operandData[i].reverseinsert = reverseinsert;
628 qr->operandData[i].npos = 0;
629 }
630}
631
632static void
634{
635 int i;
636 int lastPos;
638
639 for (i = 0; i < entry->data.query.nitem; i++)
640 {
641 if (entry->data.query.items[i]->type != QI_VAL)
642 continue;
643
645
646 opData->operandexists = true;
647
648 if (opData->npos == 0)
649 {
650 lastPos = (opData->reverseinsert) ? (MAXQROPOS - 1) : 0;
651 opData->pos[lastPos] = entry->pos;
652 opData->npos++;
653 continue;
654 }
655
656 lastPos = opData->reverseinsert ?
657 (MAXQROPOS - opData->npos) :
658 (opData->npos - 1);
659
660 if (WEP_GETPOS(opData->pos[lastPos]) != WEP_GETPOS(entry->pos))
661 {
662 lastPos = opData->reverseinsert ?
663 (MAXQROPOS - 1 - opData->npos) :
664 (opData->npos);
665
666 opData->pos[lastPos] = entry->pos;
667 opData->npos++;
668 }
669 }
670}
671
672static bool
674{
676 int lastpos = ext->pos;
677 bool found = false;
678
679 /*
680 * since this function recurses, it could be driven to stack overflow.
681 * (though any decent compiler will optimize away the tail-recursion.
682 */
684
686
687 ext->p = INT_MAX;
688 ext->q = 0;
689 ptr = doc + ext->pos;
690
691 /* find upper bound of cover from current position, move up */
692 while (ptr - doc < len)
693 {
695
696 if (TS_execute(GETQUERY(qr->query), qr,
698 {
699 if (WEP_GETPOS(ptr->pos) > ext->q)
700 {
701 ext->q = WEP_GETPOS(ptr->pos);
702 ext->end = ptr;
703 lastpos = ptr - doc;
704 found = true;
705 }
706 break;
707 }
708 ptr++;
709 }
710
711 if (!found)
712 return false;
713
715
716 ptr = doc + lastpos;
717
718 /* find lower bound of cover from found upper bound, move down */
719 while (ptr >= doc + ext->pos)
720 {
721 /*
722 * we scan doc from right to left, so pos info in reverse order!
723 */
725
726 if (TS_execute(GETQUERY(qr->query), qr,
728 {
729 if (WEP_GETPOS(ptr->pos) < ext->p)
730 {
731 ext->begin = ptr;
732 ext->p = WEP_GETPOS(ptr->pos);
733 }
734 break;
735 }
736 ptr--;
737 }
738
739 if (ext->p <= ext->q)
740 {
741 /*
742 * set position for next try to next lexeme after beginning of found
743 * cover
744 */
745 ext->pos = (ptr - doc) + 1;
746 return true;
747 }
748
749 ext->pos++;
750 return Cover(doc, len, qr, ext);
751}
752
753static DocRepresentation *
755{
756 QueryItem *item = GETQUERY(qr->query);
757 WordEntry *entry,
758 *firstentry;
759 WordEntryPos *post;
760 int32 dimt, /* number of 'post' items */
761 j,
762 i,
763 nitem;
764 int len = qr->query->size * 4,
765 cur = 0;
767
769
770 /*
771 * Iterate through query to make DocRepresentation for words and it's
772 * entries satisfied by query
773 */
774 for (i = 0; i < qr->query->size; i++)
775 {
776 QueryOperand *curoperand;
777
778 if (item[i].type != QI_VAL)
779 continue;
780
781 curoperand = &item[i].qoperand;
782
783 firstentry = entry = find_wordentry(txt, qr->query, curoperand, &nitem);
784 if (!entry)
785 continue;
786
787 /* iterations over entries in tsvector */
788 while (entry - firstentry < nitem)
789 {
790 if (entry->haspos)
791 {
792 dimt = POSDATALEN(txt, entry);
793 post = POSDATAPTR(txt, entry);
794 }
795 else
796 {
797 /* ignore words without positions */
798 entry++;
799 continue;
800 }
801
802 while (cur + dimt >= len)
803 {
804 len *= 2;
806 }
807
808 /* iterations over entry's positions */
809 for (j = 0; j < dimt; j++)
810 {
811 if (curoperand->weight == 0 ||
812 curoperand->weight & (1 << WEP_GETWEIGHT(post[j])))
813 {
814 doc[cur].pos = post[j];
815 doc[cur].data.map.entry = entry;
816 doc[cur].data.map.item = (QueryItem *) curoperand;
817 cur++;
818 }
819 }
820
821 entry++;
822 }
823 }
824
825 if (cur > 0)
826 {
828 *wptr = doc,
829 storage;
830
831 /*
832 * Sort representation in ascending order by pos and entry
833 */
835
836 /*
837 * Join QueryItem per WordEntry and its position
838 */
839 storage.pos = doc->pos;
840 storage.data.query.items = palloc_array(QueryItem *, qr->query->size);
841 storage.data.query.items[0] = doc->data.map.item;
842 storage.data.query.nitem = 1;
843
844 while (rptr - doc < cur)
845 {
846 if (rptr->pos == (rptr - 1)->pos &&
847 rptr->data.map.entry == (rptr - 1)->data.map.entry)
848 {
849 storage.data.query.items[storage.data.query.nitem] = rptr->data.map.item;
850 storage.data.query.nitem++;
851 }
852 else
853 {
854 *wptr = storage;
855 wptr++;
856 storage.pos = rptr->pos;
857 storage.data.query.items = palloc_array(QueryItem *, qr->query->size);
858 storage.data.query.items[0] = rptr->data.map.item;
859 storage.data.query.nitem = 1;
860 }
861
862 rptr++;
863 }
864
865 *wptr = storage;
866 wptr++;
867
868 *doclen = wptr - doc;
869 return doc;
870 }
871
872 pfree(doc);
873 return NULL;
874}
875
876static float4
877calc_rank_cd(const float4 *arrdata, TSVector txt, TSQuery query, int method)
878{
880 int len,
881 i,
882 doclen = 0;
883 CoverExt ext;
884 double Wdoc = 0.0;
885 double invws[NUM_WEIGHTS];
886 double SumDist = 0.0,
887 PrevExtPos = 0.0;
888 int NExtent = 0;
890
891
892 for (i = 0; i < NUM_WEIGHTS; i++)
893 {
894 invws[i] = ((double) ((arrdata[i] >= 0) ? arrdata[i] : default_weights[i]));
895 if (invws[i] > 1.0)
898 errmsg("weight out of range")));
899 invws[i] = 1.0 / invws[i];
900 }
901
902 qr.query = query;
903 qr.operandData = palloc0_array(QueryRepresentationOperand, query->size);
904
905 doc = get_docrep(txt, &qr, &doclen);
906 if (!doc)
907 {
908 pfree(qr.operandData);
909 return 0.0;
910 }
911
912 MemSet(&ext, 0, sizeof(CoverExt));
913 while (Cover(doc, doclen, &qr, &ext))
914 {
915 double Cpos = 0.0;
916 double InvSum = 0.0;
917 double CurExtPos;
918 int nNoise;
919 DocRepresentation *ptr = ext.begin;
920
921 while (ptr <= ext.end)
922 {
923 InvSum += invws[WEP_GETWEIGHT(ptr->pos)];
924 ptr++;
925 }
926
927 Cpos = ((double) (ext.end - ext.begin + 1)) / InvSum;
928
929 /*
930 * if doc are big enough then ext.q may be equal to ext.p due to limit
931 * of positional information. In this case we approximate number of
932 * noise word as half cover's length
933 */
934 nNoise = (ext.q - ext.p) - (ext.end - ext.begin);
935 if (nNoise < 0)
936 nNoise = (ext.end - ext.begin) / 2;
937 Wdoc += Cpos / ((double) (1 + nNoise));
938
939 CurExtPos = ((double) (ext.q + ext.p)) / 2.0;
940 if (NExtent > 0 && CurExtPos > PrevExtPos /* prevent division by
941 * zero in a case of
942 * multiple lexize */ )
943 SumDist += 1.0 / (CurExtPos - PrevExtPos);
944
946 NExtent++;
947 }
948
949 if ((method & RANK_NORM_LOGLENGTH) && txt->size > 0)
950 Wdoc /= log((double) (cnt_length(txt) + 1));
951
952 if (method & RANK_NORM_LENGTH)
953 {
954 len = cnt_length(txt);
955 if (len > 0)
956 Wdoc /= (double) len;
957 }
958
959 if ((method & RANK_NORM_EXTDIST) && NExtent > 0 && SumDist > 0)
960 Wdoc /= ((double) NExtent) / SumDist;
961
962 if ((method & RANK_NORM_UNIQ) && txt->size > 0)
963 Wdoc /= (double) (txt->size);
964
965 if ((method & RANK_NORM_LOGUNIQ) && txt->size > 0)
966 Wdoc /= log((double) (txt->size + 1)) / log(2.0);
967
968 if (method & RANK_NORM_RDIVRPLUS1)
969 Wdoc /= (Wdoc + 1);
970
971 pfree(doc);
972
973 pfree(qr.operandData);
974
975 return (float4) Wdoc;
976}
977
978Datum
980{
983 TSQuery query = PG_GETARG_TSQUERY(2);
984 int method = PG_GETARG_INT32(3);
985 float weights[NUM_WEIGHTS];
986 float res;
987
989 res = calc_rank_cd(weights, txt, query, method);
990
993 PG_FREE_IF_COPY(query, 2);
994 PG_RETURN_FLOAT4(res);
995}
996
997Datum
999{
1002 TSQuery query = PG_GETARG_TSQUERY(2);
1003 float weights[NUM_WEIGHTS];
1004 float res;
1005
1007 res = calc_rank_cd(weights, txt, query, DEF_NORM_METHOD);
1008
1009 PG_FREE_IF_COPY(win, 0);
1010 PG_FREE_IF_COPY(txt, 1);
1011 PG_FREE_IF_COPY(query, 2);
1012 PG_RETURN_FLOAT4(res);
1013}
1014
1015Datum
1017{
1019 TSQuery query = PG_GETARG_TSQUERY(1);
1020 int method = PG_GETARG_INT32(2);
1021 float res;
1022
1023 res = calc_rank_cd(default_weights, txt, query, method);
1024
1025 PG_FREE_IF_COPY(txt, 0);
1026 PG_FREE_IF_COPY(query, 1);
1027 PG_RETURN_FLOAT4(res);
1028}
1029
1030Datum
1032{
1034 TSQuery query = PG_GETARG_TSQUERY(1);
1035 float res;
1036
1038
1039 PG_FREE_IF_COPY(txt, 0);
1040 PG_FREE_IF_COPY(query, 1);
1041 PG_RETURN_FLOAT4(res);
1042}
#define GETQUERY(x)
Definition _int.h:157
int32_t int32
Definition c.h:620
float float4
Definition c.h:713
#define MemSet(start, val, len)
Definition c.h:1107
struct cursor * cur
Definition ecpg.c:29
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
#define palloc_array(type, count)
Definition fe_memutils.h:91
#define palloc0_array(type, count)
Definition fe_memutils.h:92
#define PG_FREE_IF_COPY(ptr, n)
Definition fmgr.h:260
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_DETOAST_DATUM(datum)
Definition fmgr.h:240
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_RETURN_FLOAT4(x)
Definition fmgr.h:368
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define storage
long val
Definition informix.c:689
int j
Definition isn.c:78
int i
Definition isn.c:77
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1635
void pfree(void *pointer)
Definition mcxt.c:1619
static char * errmsg
const void size_t len
const void * data
#define qsort(a, b, c, d)
Definition port.h:496
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
void check_stack_depth(void)
Definition stack_depth.c:96
int pos
Definition tsrank.c:613
int p
Definition tsrank.c:614
DocRepresentation * begin
Definition tsrank.c:616
DocRepresentation * end
Definition tsrank.c:617
int q
Definition tsrank.c:615
QueryItem ** items
Definition tsrank.c:533
WordEntryPos pos
Definition tsrank.c:543
struct DocRepresentation::@33::@34 query
union DocRepresentation::@33 data
uint8 weight
Definition ts_type.h:159
uint32 pos
Definition ts_type.h:46
uint32 haspos
Definition ts_type.h:44
#define PG_GETARG_TSVECTOR(n)
Definition ts_type.h:135
#define WEP_GETPOS(x)
Definition ts_type.h:80
#define POSDATALEN(x, e)
Definition ts_type.h:110
#define PG_GETARG_TSQUERY(n)
Definition ts_type.h:267
uint16 WordEntryPos
Definition ts_type.h:63
#define QI_VAL
Definition ts_type.h:149
#define POSDATAPTR(x, e)
Definition ts_type.h:111
#define WEP_GETWEIGHT(x)
Definition ts_type.h:79
@ TS_NO
Definition ts_utils.h:132
@ TS_YES
Definition ts_utils.h:133
#define TS_EXEC_EMPTY
Definition ts_utils.h:186
#define RANK_NORM_RDIVRPLUS1
Definition tsrank.c:35
Datum ts_rankcd_wtt(PG_FUNCTION_ARGS)
Definition tsrank.c:999
static DocRepresentation * get_docrep(TSVector txt, QueryRepresentation *qr, int *doclen)
Definition tsrank.c:755
Datum ts_rankcd_wttf(PG_FUNCTION_ARGS)
Definition tsrank.c:980
static int compareDocR(const void *va, const void *vb)
Definition tsrank.c:547
#define RANK_NORM_UNIQ
Definition tsrank.c:33
#define RANK_NORM_LOGLENGTH
Definition tsrank.c:30
static TSTernaryValue checkcondition_QueryOperand(void *checkval, QueryOperand *val, ExecPhraseData *data)
Definition tsrank.c:591
#define RANK_NORM_LENGTH
Definition tsrank.c:31
static void resetQueryRepresentation(QueryRepresentation *qr, bool reverseinsert)
Definition tsrank.c:621
static float4 calc_rank_cd(const float4 *arrdata, TSVector txt, TSQuery query, int method)
Definition tsrank.c:878
static int cnt_length(TSVector t)
Definition tsrank.c:54
static WordEntry * find_wordentry(TSVector t, TSQuery q, QueryOperand *item, int32 *nitem)
Definition tsrank.c:87
#define MAXQROPOS
Definition tsrank.c:568
#define DEF_NORM_METHOD
Definition tsrank.c:36
static void getWeights(ArrayType *win, float *ws)
Definition tsrank.c:428
static void fillQueryRepresentationData(QueryRepresentation *qr, DocRepresentation *entry)
Definition tsrank.c:634
static const float default_weights[NUM_WEIGHTS]
Definition tsrank.c:25
#define NUM_WEIGHTS
Definition tsrank.c:24
#define QR_GET_OPERAND_DATA(q, v)
Definition tsrank.c:584
Datum ts_rankcd_ttf(PG_FUNCTION_ARGS)
Definition tsrank.c:1017
Datum ts_rankcd_tt(PG_FUNCTION_ARGS)
Definition tsrank.c:1032
#define RANK_NORM_EXTDIST
Definition tsrank.c:32
static bool Cover(DocRepresentation *doc, int len, QueryRepresentation *qr, CoverExt *ext)
Definition tsrank.c:674
#define RANK_NORM_LOGUNIQ
Definition tsrank.c:34
bool TS_execute(QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond)
QueryOperand qoperand
Definition ts_type.h:210
QueryItemType type
Definition ts_type.h:208
const char * type

◆ RANK_NO_NORM

#define RANK_NO_NORM   0x00

Definition at line 29 of file tsrank.c.

◆ RANK_NORM_EXTDIST

#define RANK_NORM_EXTDIST   0x04

Definition at line 32 of file tsrank.c.

◆ RANK_NORM_LENGTH

#define RANK_NORM_LENGTH   0x02

Definition at line 31 of file tsrank.c.

◆ RANK_NORM_LOGLENGTH

#define RANK_NORM_LOGLENGTH   0x01

Definition at line 30 of file tsrank.c.

◆ RANK_NORM_LOGUNIQ

#define RANK_NORM_LOGUNIQ   0x10

Definition at line 34 of file tsrank.c.

◆ RANK_NORM_RDIVRPLUS1

#define RANK_NORM_RDIVRPLUS1   0x20

Definition at line 35 of file tsrank.c.

◆ RANK_NORM_UNIQ

#define RANK_NORM_UNIQ   0x08

Definition at line 33 of file tsrank.c.

◆ WordECompareQueryItem

#define WordECompareQueryItem (   e,
  q,
  p,
  i,
 
)
Value:
tsCompareString((q) + (i)->distance, (i)->length, \
(e) + (p)->pos, (p)->len, (m))
e
int32 tsCompareString(char *a, int lena, char *b, int lenb, bool prefix)

Definition at line 76 of file tsrank.c.

◆ wpos

#define wpos (   wep)    ( w[ WEP_GETWEIGHT(wep) ] )

Definition at line 27 of file tsrank.c.

Function Documentation

◆ calc_rank()

static float calc_rank ( const float w,
TSVector  t,
TSQuery  q,
int32  method 
)
static

Definition at line 381 of file tsrank.c.

382{
383 QueryItem *item = GETQUERY(q);
384 float res = 0.0;
385 int len;
386
387 if (!t->size || !q->size)
388 return 0.0;
389
390 /* XXX: What about NOT? */
391 res = (item->type == QI_OPR && (item->qoperator.oper == OP_AND ||
392 item->qoperator.oper == OP_PHRASE)) ?
393 calc_rank_and(w, t, q) :
394 calc_rank_or(w, t, q);
395
396 if (res < 0)
397 res = 1e-20f;
398
399 if ((method & RANK_NORM_LOGLENGTH) && t->size > 0)
400 res /= log((double) (cnt_length(t) + 1)) / log(2.0);
401
402 if (method & RANK_NORM_LENGTH)
403 {
404 len = cnt_length(t);
405 if (len > 0)
406 res /= (float) len;
407 }
408
409 /* RANK_NORM_EXTDIST not applicable */
410
411 if ((method & RANK_NORM_UNIQ) && t->size > 0)
412 res /= (float) (t->size);
413
414 if ((method & RANK_NORM_LOGUNIQ) && t->size > 0)
415 res /= log((double) (t->size + 1)) / log(2.0);
416
417 if (method & RANK_NORM_RDIVRPLUS1)
418 res /= (res + 1);
419
420 return res;
421}
int32 size
Definition ts_type.h:221
int32 size
Definition ts_type.h:93
#define QI_OPR
Definition ts_type.h:150
#define OP_AND
Definition ts_type.h:180
#define OP_PHRASE
Definition ts_type.h:182
static float calc_rank_or(const float *w, TSVector t, TSQuery q)
Definition tsrank.c:284
static float calc_rank_and(const float *w, TSVector t, TSQuery q)
Definition tsrank.c:201
QueryOperator qoperator
Definition ts_type.h:209

References calc_rank_and(), calc_rank_or(), cnt_length(), fb(), GETQUERY, len, OP_AND, OP_PHRASE, QueryOperator::oper, QI_OPR, QueryItem::qoperator, RANK_NORM_LENGTH, RANK_NORM_LOGLENGTH, RANK_NORM_LOGUNIQ, RANK_NORM_RDIVRPLUS1, RANK_NORM_UNIQ, TSVectorData::size, TSQueryData::size, and QueryItem::type.

Referenced by ts_rank_tt(), ts_rank_ttf(), ts_rank_wtt(), and ts_rank_wttf().

◆ calc_rank_and()

static float calc_rank_and ( const float w,
TSVector  t,
TSQuery  q 
)
static

Definition at line 201 of file tsrank.c.

202{
203 WordEntryPosVector **pos;
206 int i,
207 k,
208 l,
209 p;
210 WordEntry *entry,
211 *firstentry;
212 WordEntryPos *post,
213 *ct;
214 int32 dimt,
215 lenct,
216 dist,
217 nitem;
218 float res = -1.0;
219 QueryOperand **item;
220 int size = q->size;
221
222 item = SortAndUniqItems(q, &size);
223 if (size < 2)
224 {
225 pfree(item);
226 return calc_rank_or(w, t, q);
227 }
229
230 /* A dummy WordEntryPos array to use when haspos is false */
231 posnull.npos = 1;
232 posnull.pos[0] = 0;
233 WEP_SETPOS(posnull.pos[0], MAXENTRYPOS - 1);
235
236 for (i = 0; i < size; i++)
237 {
238 firstentry = entry = find_wordentry(t, q, item[i], &nitem);
239 if (!entry)
240 continue;
241
242 while (entry - firstentry < nitem)
243 {
244 if (entry->haspos)
245 pos[i] = _POSVECPTR(t, entry);
246 else
247 pos[i] = POSNULL;
248
249 dimt = pos[i]->npos;
250 post = pos[i]->pos;
251 for (k = 0; k < i; k++)
252 {
253 if (!pos[k])
254 continue;
255 lenct = pos[k]->npos;
256 ct = pos[k]->pos;
257 for (l = 0; l < dimt; l++)
258 {
259 for (p = 0; p < lenct; p++)
260 {
261 dist = abs((int) WEP_GETPOS(post[l]) - (int) WEP_GETPOS(ct[p]));
262 if (dist || (dist == 0 && (pos[i] == POSNULL || pos[k] == POSNULL)))
263 {
264 float curw;
265
266 if (!dist)
268 curw = sqrt(wpos(post[l]) * wpos(ct[p]) * word_distance(dist));
269 res = (res < 0) ? curw : 1.0 - (1.0 - res) * (1.0 - curw);
270 }
271 }
272 }
273 }
274
275 entry++;
276 }
277 }
278 pfree(pos);
279 pfree(item);
280 return res;
281}
WordEntryPos pos[FLEXIBLE_ARRAY_MEMBER]
Definition ts_type.h:68
#define _POSVECPTR(x, e)
Definition ts_type.h:109
#define MAXENTRYPOS
Definition ts_type.h:85
#define WEP_SETPOS(x, v)
Definition ts_type.h:83
#define wpos(wep)
Definition tsrank.c:27
static float4 word_distance(int32 w)
Definition tsrank.c:45
static QueryOperand ** SortAndUniqItems(TSQuery q, int *size)
Definition tsrank.c:155

References _POSVECPTR, calc_rank_or(), fb(), find_wordentry(), WordEntry::haspos, i, MAXENTRYPOS, WordEntryPosVector::npos, palloc0_array, pfree(), WordEntryPosVector::pos, TSQueryData::size, SortAndUniqItems(), WEP_GETPOS, WEP_SETPOS, word_distance(), and wpos.

Referenced by calc_rank().

◆ calc_rank_cd()

static float4 calc_rank_cd ( const float4 arrdata,
TSVector  txt,
TSQuery  query,
int  method 
)
static

Definition at line 878 of file tsrank.c.

879{
881 int len,
882 i,
883 doclen = 0;
884 CoverExt ext;
885 double Wdoc = 0.0;
886 double invws[NUM_WEIGHTS];
887 double SumDist = 0.0,
888 PrevExtPos = 0.0;
889 int NExtent = 0;
891
892
893 for (i = 0; i < NUM_WEIGHTS; i++)
894 {
895 invws[i] = ((double) ((arrdata[i] >= 0) ? arrdata[i] : default_weights[i]));
896 if (invws[i] > 1.0)
899 errmsg("weight out of range")));
900 invws[i] = 1.0 / invws[i];
901 }
902
903 qr.query = query;
904 qr.operandData = palloc0_array(QueryRepresentationOperand, query->size);
905
906 doc = get_docrep(txt, &qr, &doclen);
907 if (!doc)
908 {
909 pfree(qr.operandData);
910 return 0.0;
911 }
912
913 MemSet(&ext, 0, sizeof(CoverExt));
914 while (Cover(doc, doclen, &qr, &ext))
915 {
916 double Cpos = 0.0;
917 double InvSum = 0.0;
918 double CurExtPos;
919 int nNoise;
920 DocRepresentation *ptr = ext.begin;
921
922 while (ptr <= ext.end)
923 {
924 InvSum += invws[WEP_GETWEIGHT(ptr->pos)];
925 ptr++;
926 }
927
928 Cpos = ((double) (ext.end - ext.begin + 1)) / InvSum;
929
930 /*
931 * if doc are big enough then ext.q may be equal to ext.p due to limit
932 * of positional information. In this case we approximate number of
933 * noise word as half cover's length
934 */
935 nNoise = (ext.q - ext.p) - (ext.end - ext.begin);
936 if (nNoise < 0)
937 nNoise = (ext.end - ext.begin) / 2;
938 Wdoc += Cpos / ((double) (1 + nNoise));
939
940 CurExtPos = ((double) (ext.q + ext.p)) / 2.0;
941 if (NExtent > 0 && CurExtPos > PrevExtPos /* prevent division by
942 * zero in a case of
943 * multiple lexize */ )
944 SumDist += 1.0 / (CurExtPos - PrevExtPos);
945
947 NExtent++;
948 }
949
950 if ((method & RANK_NORM_LOGLENGTH) && txt->size > 0)
951 Wdoc /= log((double) (cnt_length(txt) + 1));
952
953 if (method & RANK_NORM_LENGTH)
954 {
955 len = cnt_length(txt);
956 if (len > 0)
957 Wdoc /= (double) len;
958 }
959
960 if ((method & RANK_NORM_EXTDIST) && NExtent > 0 && SumDist > 0)
961 Wdoc /= ((double) NExtent) / SumDist;
962
963 if ((method & RANK_NORM_UNIQ) && txt->size > 0)
964 Wdoc /= (double) (txt->size);
965
966 if ((method & RANK_NORM_LOGUNIQ) && txt->size > 0)
967 Wdoc /= log((double) (txt->size + 1)) / log(2.0);
968
969 if (method & RANK_NORM_RDIVRPLUS1)
970 Wdoc /= (Wdoc + 1);
971
972 pfree(doc);
973
974 pfree(qr.operandData);
975
976 return (float4) Wdoc;
977}

References CoverExt::begin, cnt_length(), Cover(), default_weights, CoverExt::end, ereport, errcode(), errmsg, ERROR, fb(), get_docrep(), i, len, MemSet, NUM_WEIGHTS, CoverExt::p, palloc0_array, pfree(), DocRepresentation::pos, CoverExt::q, RANK_NORM_EXTDIST, RANK_NORM_LENGTH, RANK_NORM_LOGLENGTH, RANK_NORM_LOGUNIQ, RANK_NORM_RDIVRPLUS1, RANK_NORM_UNIQ, TSQueryData::size, and WEP_GETWEIGHT.

Referenced by ts_rankcd_tt(), ts_rankcd_ttf(), ts_rankcd_wtt(), and ts_rankcd_wttf().

◆ calc_rank_or()

static float calc_rank_or ( const float w,
TSVector  t,
TSQuery  q 
)
static

Definition at line 284 of file tsrank.c.

285{
286 WordEntry *entry,
287 *firstentry;
289 WordEntryPos *post;
290 int32 dimt,
291 j,
292 i,
293 nitem;
294 float res = 0.0;
295 QueryOperand **item;
296 int size = q->size;
297
298 /* A dummy WordEntryPos array to use when haspos is false */
299 posnull.npos = 1;
300 posnull.pos[0] = 0;
301
302 item = SortAndUniqItems(q, &size);
303
304 for (i = 0; i < size; i++)
305 {
306 float resj,
307 wjm;
308 int32 jm;
309
310 firstentry = entry = find_wordentry(t, q, item[i], &nitem);
311 if (!entry)
312 continue;
313
314 while (entry - firstentry < nitem)
315 {
316 /* Identify the weight data to use */
317 if (entry->haspos)
318 {
319 dimt = POSDATALEN(t, entry);
320 post = POSDATAPTR(t, entry);
321 }
322 else
323 {
324 dimt = posnull.npos;
325 post = posnull.pos;
326 }
327
328 /*
329 * Compute the score for this term, then add it to "res".
330 *
331 * The ideal score for a term is the weighted harmonic sum:
332 *
333 * resj = sum(wi / i^2, i = 1..noccurrences)
334 *
335 * where wi is the weight of the i-th occurrence and weights are
336 * sorted in descending order so that the highest-weight
337 * occurrence gets the smallest divisor (i=1) and thus contributes
338 * the most.
339 *
340 * This result should be divided by pi^2/6 ~= 1.64493406685, which
341 * is the limit of sum(1/i^2, i=1..inf). This normalizes the score
342 * to the [0, 1] range.
343 *
344 * As an approximation for efficiency, we skip doing a sort and
345 * instead just promote the single highest-weight occurrence to
346 * position i=1. This is done by taking the raw (unsorted) sum
347 * resj, subtracting the maximum weight's actual contribution
348 * wjm/(jm+1)^2, and adding back its corrected contribution
349 * wjm/1^2 = wjm.
350 *
351 * The remaining occurrences are left in their original order.
352 */
353
354 /* calculate harmonic sum without re-ordering */
355 resj = 0.0;
356 wjm = -1.0;
357 jm = 0;
358 for (j = 0; j < dimt; j++)
359 {
360 resj = resj + wpos(post[j]) / ((j + 1) * (j + 1));
361 if (wpos(post[j]) > wjm)
362 {
363 wjm = wpos(post[j]);
364 jm = j;
365 }
366 }
367
368 /* apply correction as explained above, then add to res */
369 res = res + (resj - wjm / ((jm + 1) * (jm + 1)) + wjm) / 1.64493406685;
370
371 entry++;
372 }
373 }
374 if (size > 0)
375 res = res / size;
376 pfree(item);
377 return res;
378}

References fb(), find_wordentry(), WordEntry::haspos, i, j, pfree(), POSDATALEN, POSDATAPTR, TSQueryData::size, SortAndUniqItems(), and wpos.

Referenced by calc_rank(), and calc_rank_and().

◆ checkcondition_QueryOperand()

static TSTernaryValue checkcondition_QueryOperand ( void checkval,
QueryOperand val,
ExecPhraseData data 
)
static

Definition at line 591 of file tsrank.c.

593{
596
597 if (!opData->operandexists)
598 return TS_NO;
599
600 if (data)
601 {
602 data->npos = opData->npos;
603 data->pos = opData->pos;
604 if (opData->reverseinsert)
605 data->pos += MAXQROPOS - opData->npos;
606 }
607
608 return TS_YES;
609}

References data, fb(), MAXQROPOS, QR_GET_OPERAND_DATA, TS_NO, TS_YES, and val.

Referenced by Cover().

◆ cnt_length()

static int cnt_length ( TSVector  t)
static

Definition at line 54 of file tsrank.c.

55{
56 WordEntry *ptr = ARRPTR(t),
57 *end = (WordEntry *) STRPTR(t);
58 int len = 0;
59
60 while (ptr < end)
61 {
62 int clen = POSDATALEN(t, ptr);
63
64 if (clen == 0)
65 len += 1;
66 else
67 len += clen;
68
69 ptr++;
70 }
71
72 return len;
73}
#define ARRPTR(x)
Definition cube.c:28
#define STRPTR(x)
Definition hstore.h:76

References ARRPTR, fb(), len, POSDATALEN, and STRPTR.

Referenced by calc_rank(), and calc_rank_cd().

◆ compareDocR()

static int compareDocR ( const void va,
const void vb 
)
static

Definition at line 547 of file tsrank.c.

548{
549 const DocRepresentation *a = (const DocRepresentation *) va;
550 const DocRepresentation *b = (const DocRepresentation *) vb;
551
552 if (WEP_GETPOS(a->pos) == WEP_GETPOS(b->pos))
553 {
554 if (WEP_GETWEIGHT(a->pos) == WEP_GETWEIGHT(b->pos))
555 {
556 if (a->data.map.entry == b->data.map.entry)
557 return 0;
558
559 return (a->data.map.entry > b->data.map.entry) ? 1 : -1;
560 }
561
562 return (WEP_GETWEIGHT(a->pos) > WEP_GETWEIGHT(b->pos)) ? 1 : -1;
563 }
564
565 return (WEP_GETPOS(a->pos) > WEP_GETPOS(b->pos)) ? 1 : -1;
566}
int b
Definition isn.c:74
int a
Definition isn.c:73

References a, b, fb(), WEP_GETPOS, and WEP_GETWEIGHT.

Referenced by get_docrep().

◆ compareQueryOperand()

static int compareQueryOperand ( const void a,
const void b,
void arg 
)
static

Definition at line 136 of file tsrank.c.

137{
138 char *operand = (char *) arg;
139 QueryOperand *qa = (*(QueryOperand *const *) a);
140 QueryOperand *qb = (*(QueryOperand *const *) b);
141
142 return tsCompareString(operand + qa->distance, qa->length,
143 operand + qb->distance, qb->length,
144 false);
145}
Datum arg
Definition elog.c:1323

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

Referenced by SortAndUniqItems().

◆ Cover()

static bool Cover ( DocRepresentation doc,
int  len,
QueryRepresentation qr,
CoverExt ext 
)
static

Definition at line 674 of file tsrank.c.

675{
677 int lastpos = ext->pos;
678 bool found = false;
679
680 /*
681 * since this function recurses, it could be driven to stack overflow.
682 * (though any decent compiler will optimize away the tail-recursion.
683 */
685
687
688 ext->p = INT_MAX;
689 ext->q = 0;
690 ptr = doc + ext->pos;
691
692 /* find upper bound of cover from current position, move up */
693 while (ptr - doc < len)
694 {
696
697 if (TS_execute(GETQUERY(qr->query), qr,
699 {
700 if (WEP_GETPOS(ptr->pos) > ext->q)
701 {
702 ext->q = WEP_GETPOS(ptr->pos);
703 ext->end = ptr;
704 lastpos = ptr - doc;
705 found = true;
706 }
707 break;
708 }
709 ptr++;
710 }
711
712 if (!found)
713 return false;
714
716
717 ptr = doc + lastpos;
718
719 /* find lower bound of cover from found upper bound, move down */
720 while (ptr >= doc + ext->pos)
721 {
722 /*
723 * we scan doc from right to left, so pos info in reverse order!
724 */
726
727 if (TS_execute(GETQUERY(qr->query), qr,
729 {
730 if (WEP_GETPOS(ptr->pos) < ext->p)
731 {
732 ext->begin = ptr;
733 ext->p = WEP_GETPOS(ptr->pos);
734 }
735 break;
736 }
737 ptr--;
738 }
739
740 if (ext->p <= ext->q)
741 {
742 /*
743 * set position for next try to next lexeme after beginning of found
744 * cover
745 */
746 ext->pos = (ptr - doc) + 1;
747 return true;
748 }
749
750 ext->pos++;
751 return Cover(doc, len, qr, ext);
752}

References CoverExt::begin, check_stack_depth(), checkcondition_QueryOperand(), Cover(), CoverExt::end, fb(), fillQueryRepresentationData(), GETQUERY, len, CoverExt::p, DocRepresentation::pos, CoverExt::pos, CoverExt::q, resetQueryRepresentation(), TS_EXEC_EMPTY, TS_execute(), and WEP_GETPOS.

Referenced by calc_rank_cd(), and Cover().

◆ fillQueryRepresentationData()

static void fillQueryRepresentationData ( QueryRepresentation qr,
DocRepresentation entry 
)
static

Definition at line 634 of file tsrank.c.

635{
636 int i;
637 int lastPos;
639
640 for (i = 0; i < entry->data.query.nitem; i++)
641 {
642 if (entry->data.query.items[i]->type != QI_VAL)
643 continue;
644
646
647 opData->operandexists = true;
648
649 if (opData->npos == 0)
650 {
651 lastPos = (opData->reverseinsert) ? (MAXQROPOS - 1) : 0;
652 opData->pos[lastPos] = entry->pos;
653 opData->npos++;
654 continue;
655 }
656
657 lastPos = opData->reverseinsert ?
658 (MAXQROPOS - opData->npos) :
659 (opData->npos - 1);
660
661 if (WEP_GETPOS(opData->pos[lastPos]) != WEP_GETPOS(entry->pos))
662 {
663 lastPos = opData->reverseinsert ?
664 (MAXQROPOS - 1 - opData->npos) :
665 (opData->npos);
666
667 opData->pos[lastPos] = entry->pos;
668 opData->npos++;
669 }
670 }
671}

References DocRepresentation::data, fb(), i, DocRepresentation::items, MAXQROPOS, DocRepresentation::nitem, DocRepresentation::pos, QI_VAL, QR_GET_OPERAND_DATA, DocRepresentation::query, QueryItem::type, and WEP_GETPOS.

Referenced by Cover().

◆ find_wordentry()

static WordEntry * find_wordentry ( TSVector  t,
TSQuery  q,
QueryOperand item,
int32 nitem 
)
static

Definition at line 87 of file tsrank.c.

88{
92 int difference;
93
94 *nitem = 0;
95
96 /* Loop invariant: StopLow <= item < StopHigh */
97 while (StopLow < StopHigh)
98 {
101 if (difference == 0)
102 {
104 *nitem = 1;
105 break;
106 }
107 else if (difference > 0)
108 StopLow = StopMiddle + 1;
109 else
111 }
112
113 if (item->prefix)
114 {
115 if (StopLow >= StopHigh)
117
118 *nitem = 0;
119
120 while (StopMiddle < (WordEntry *) STRPTR(t) &&
121 WordECompareQueryItem(STRPTR(t), GETOPERAND(q), StopMiddle, item, true) == 0)
122 {
123 (*nitem)++;
124 StopMiddle++;
125 }
126 }
127
128 return (*nitem > 0) ? StopHigh : NULL;
129}
Datum difference(PG_FUNCTION_ARGS)
#define GETOPERAND(x)
Definition ltree.h:165
bool prefix
Definition ts_type.h:163
#define WordECompareQueryItem(e, q, p, i, m)
Definition tsrank.c:76

References ARRPTR, difference(), fb(), GETOPERAND, QueryOperand::prefix, STRPTR, and WordECompareQueryItem.

Referenced by calc_rank_and(), calc_rank_or(), and get_docrep().

◆ get_docrep()

static DocRepresentation * get_docrep ( TSVector  txt,
QueryRepresentation qr,
int doclen 
)
static

Definition at line 755 of file tsrank.c.

756{
757 QueryItem *item = GETQUERY(qr->query);
758 WordEntry *entry,
759 *firstentry;
760 WordEntryPos *post;
761 int32 dimt, /* number of 'post' items */
762 j,
763 i,
764 nitem;
765 int len = qr->query->size * 4,
766 cur = 0;
768
770
771 /*
772 * Iterate through query to make DocRepresentation for words and it's
773 * entries satisfied by query
774 */
775 for (i = 0; i < qr->query->size; i++)
776 {
777 QueryOperand *curoperand;
778
779 if (item[i].type != QI_VAL)
780 continue;
781
782 curoperand = &item[i].qoperand;
783
784 firstentry = entry = find_wordentry(txt, qr->query, curoperand, &nitem);
785 if (!entry)
786 continue;
787
788 /* iterations over entries in tsvector */
789 while (entry - firstentry < nitem)
790 {
791 if (entry->haspos)
792 {
793 dimt = POSDATALEN(txt, entry);
794 post = POSDATAPTR(txt, entry);
795 }
796 else
797 {
798 /* ignore words without positions */
799 entry++;
800 continue;
801 }
802
803 while (cur + dimt >= len)
804 {
805 len *= 2;
807 }
808
809 /* iterations over entry's positions */
810 for (j = 0; j < dimt; j++)
811 {
812 if (curoperand->weight == 0 ||
813 curoperand->weight & (1 << WEP_GETWEIGHT(post[j])))
814 {
815 doc[cur].pos = post[j];
816 doc[cur].data.map.entry = entry;
817 doc[cur].data.map.item = (QueryItem *) curoperand;
818 cur++;
819 }
820 }
821
822 entry++;
823 }
824 }
825
826 if (cur > 0)
827 {
829 *wptr = doc,
830 storage;
831
832 /*
833 * Sort representation in ascending order by pos and entry
834 */
836
837 /*
838 * Join QueryItem per WordEntry and its position
839 */
840 storage.pos = doc->pos;
841 storage.data.query.items = palloc_array(QueryItem *, qr->query->size);
842 storage.data.query.items[0] = doc->data.map.item;
843 storage.data.query.nitem = 1;
844
845 while (rptr - doc < cur)
846 {
847 if (rptr->pos == (rptr - 1)->pos &&
848 rptr->data.map.entry == (rptr - 1)->data.map.entry)
849 {
850 storage.data.query.items[storage.data.query.nitem] = rptr->data.map.item;
851 storage.data.query.nitem++;
852 }
853 else
854 {
855 *wptr = storage;
856 wptr++;
857 storage.pos = rptr->pos;
858 storage.data.query.items = palloc_array(QueryItem *, qr->query->size);
859 storage.data.query.items[0] = rptr->data.map.item;
860 storage.data.query.nitem = 1;
861 }
862
863 rptr++;
864 }
865
866 *wptr = storage;
867 wptr++;
868
869 *doclen = wptr - doc;
870 return doc;
871 }
872
873 pfree(doc);
874 return NULL;
875}

References compareDocR(), cur, fb(), find_wordentry(), GETQUERY, WordEntry::haspos, i, j, len, palloc_array, pfree(), WordEntry::pos, POSDATALEN, POSDATAPTR, QI_VAL, QueryItem::qoperand, qsort, repalloc(), storage, type, QueryOperand::weight, and WEP_GETWEIGHT.

Referenced by calc_rank_cd().

◆ getWeights()

static void getWeights ( ArrayType win,
float ws 
)
static

Definition at line 428 of file tsrank.c.

429{
430 int i;
432
433 Assert(win != NULL);
434
435 if (ARR_NDIM(win) != 1)
438 errmsg("array of weight must be one-dimensional")));
439
443 errmsg("array of weight is too short")));
444
448 errmsg("array of weight must not contain nulls")));
449
451 for (i = 0; i < NUM_WEIGHTS; i++)
452 {
453 ws[i] = (arrdata[i] >= 0) ? arrdata[i] : default_weights[i];
454 if (ws[i] > 1.0)
457 errmsg("weight out of range")));
458 }
459}
#define ARR_NDIM(a)
Definition array.h:290
#define ARR_DATA_PTR(a)
Definition array.h:322
#define ARR_DIMS(a)
Definition array.h:294
bool array_contains_nulls(const ArrayType *array)
int ArrayGetNItems(int ndim, const int *dims)
Definition arrayutils.c:57
#define Assert(condition)
Definition c.h:943

References ARR_DATA_PTR, ARR_DIMS, ARR_NDIM, array_contains_nulls(), ArrayGetNItems(), Assert, default_weights, ereport, errcode(), errmsg, ERROR, fb(), i, and NUM_WEIGHTS.

Referenced by ts_rank_wtt(), ts_rank_wttf(), ts_rankcd_wtt(), and ts_rankcd_wttf().

◆ resetQueryRepresentation()

static void resetQueryRepresentation ( QueryRepresentation qr,
bool  reverseinsert 
)
static

Definition at line 621 of file tsrank.c.

622{
623 int i;
624
625 for (i = 0; i < qr->query->size; i++)
626 {
627 qr->operandData[i].operandexists = false;
628 qr->operandData[i].reverseinsert = reverseinsert;
629 qr->operandData[i].npos = 0;
630 }
631}

References fb(), and i.

Referenced by Cover().

◆ SortAndUniqItems()

static QueryOperand ** SortAndUniqItems ( TSQuery  q,
int size 
)
static

Definition at line 155 of file tsrank.c.

156{
157 char *operand = GETOPERAND(q);
158 QueryItem *item = GETQUERY(q);
159 QueryOperand **res,
160 **ptr,
161 **prevptr;
162
163 ptr = res = palloc_array(QueryOperand *, *size);
164
165 /* Collect all operands from the tree to res */
166 while ((*size)--)
167 {
168 if (item->type == QI_VAL)
169 {
170 *ptr = (QueryOperand *) item;
171 ptr++;
172 }
173 item++;
174 }
175
176 *size = ptr - res;
177 if (*size < 2)
178 return res;
179
180 qsort_arg(res, *size, sizeof(QueryOperand *), compareQueryOperand, operand);
181
182 ptr = res + 1;
183 prevptr = res;
184
185 /* remove duplicates */
186 while (ptr - res < *size)
187 {
188 if (compareQueryOperand(ptr, prevptr, operand) != 0)
189 {
190 prevptr++;
191 *prevptr = *ptr;
192 }
193 ptr++;
194 }
195
196 *size = prevptr + 1 - res;
197 return res;
198}
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
static int compareQueryOperand(const void *a, const void *b, void *arg)
Definition tsrank.c:136

References compareQueryOperand(), fb(), GETOPERAND, GETQUERY, palloc_array, QI_VAL, qsort_arg(), and QueryItem::type.

Referenced by calc_rank_and(), and calc_rank_or().

◆ ts_rank_tt()

Datum ts_rank_tt ( PG_FUNCTION_ARGS  )

Definition at line 514 of file tsrank.c.

515{
517 TSQuery query = PG_GETARG_TSQUERY(1);
518 float res;
519
521
523 PG_FREE_IF_COPY(query, 1);
524 PG_RETURN_FLOAT4(res);
525}
static float calc_rank(const float *w, TSVector t, TSQuery q, int32 method)
Definition tsrank.c:381

References calc_rank(), DEF_NORM_METHOD, default_weights, fb(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, and PG_RETURN_FLOAT4.

◆ ts_rank_ttf()

Datum ts_rank_ttf ( PG_FUNCTION_ARGS  )

Definition at line 499 of file tsrank.c.

500{
502 TSQuery query = PG_GETARG_TSQUERY(1);
503 int method = PG_GETARG_INT32(2);
504 float res;
505
506 res = calc_rank(default_weights, txt, query, method);
507
509 PG_FREE_IF_COPY(query, 1);
510 PG_RETURN_FLOAT4(res);
511}

References calc_rank(), default_weights, fb(), PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, and PG_RETURN_FLOAT4.

◆ ts_rank_wtt()

◆ ts_rank_wttf()

Datum ts_rank_wttf ( PG_FUNCTION_ARGS  )

Definition at line 462 of file tsrank.c.

463{
466 TSQuery query = PG_GETARG_TSQUERY(2);
467 int method = PG_GETARG_INT32(3);
468 float weights[NUM_WEIGHTS];
469 float res;
470
472 res = calc_rank(weights, txt, query, method);
473
476 PG_FREE_IF_COPY(query, 2);
477 PG_RETURN_FLOAT4(res);
478}

References calc_rank(), fb(), getWeights(), NUM_WEIGHTS, PG_DETOAST_DATUM, PG_FREE_IF_COPY, PG_GETARG_DATUM, PG_GETARG_INT32, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, and PG_RETURN_FLOAT4.

◆ ts_rankcd_tt()

Datum ts_rankcd_tt ( PG_FUNCTION_ARGS  )

Definition at line 1032 of file tsrank.c.

1033{
1035 TSQuery query = PG_GETARG_TSQUERY(1);
1036 float res;
1037
1039
1040 PG_FREE_IF_COPY(txt, 0);
1041 PG_FREE_IF_COPY(query, 1);
1042 PG_RETURN_FLOAT4(res);
1043}

References calc_rank_cd(), DEF_NORM_METHOD, default_weights, fb(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, and PG_RETURN_FLOAT4.

◆ ts_rankcd_ttf()

Datum ts_rankcd_ttf ( PG_FUNCTION_ARGS  )

Definition at line 1017 of file tsrank.c.

1018{
1020 TSQuery query = PG_GETARG_TSQUERY(1);
1021 int method = PG_GETARG_INT32(2);
1022 float res;
1023
1024 res = calc_rank_cd(default_weights, txt, query, method);
1025
1026 PG_FREE_IF_COPY(txt, 0);
1027 PG_FREE_IF_COPY(query, 1);
1028 PG_RETURN_FLOAT4(res);
1029}

References calc_rank_cd(), default_weights, fb(), PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, and PG_RETURN_FLOAT4.

◆ ts_rankcd_wtt()

Datum ts_rankcd_wtt ( PG_FUNCTION_ARGS  )

◆ ts_rankcd_wttf()

Datum ts_rankcd_wttf ( PG_FUNCTION_ARGS  )

Definition at line 980 of file tsrank.c.

981{
984 TSQuery query = PG_GETARG_TSQUERY(2);
985 int method = PG_GETARG_INT32(3);
986 float weights[NUM_WEIGHTS];
987 float res;
988
990 res = calc_rank_cd(weights, txt, query, method);
991
994 PG_FREE_IF_COPY(query, 2);
995 PG_RETURN_FLOAT4(res);
996}

References calc_rank_cd(), fb(), getWeights(), NUM_WEIGHTS, PG_DETOAST_DATUM, PG_FREE_IF_COPY, PG_GETARG_DATUM, PG_GETARG_INT32, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, and PG_RETURN_FLOAT4.

◆ word_distance()

static float4 word_distance ( int32  w)
static

Definition at line 45 of file tsrank.c.

46{
47 if (w > 100)
48 return 1e-30f;
49
50 return 1.0 / (1.005 + 0.05 * exp(((float4) w) / 1.5 - 2));
51}

References fb().

Referenced by calc_rank_and().

Variable Documentation

◆ default_weights

const float default_weights[NUM_WEIGHTS] = {0.1f, 0.2f, 0.4f, 1.0f}
static

Definition at line 25 of file tsrank.c.

25{0.1f, 0.2f, 0.4f, 1.0f};

Referenced by calc_rank_cd(), getWeights(), ts_rank_tt(), ts_rank_ttf(), ts_rankcd_tt(), and ts_rankcd_ttf().