aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/tsrank.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2007-09-07 15:09:56 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2007-09-07 15:09:56 +0000
commite5be89981fc70648eedb325781cf2fbd4da05ba8 (patch)
tree8a2c587b7ae857fcbe2c2ed4ff21772c11d935a3 /src/backend/utils/adt/tsrank.c
parentda1248401d00bce0cb75fa3ab278f906f407bec9 (diff)
downloadpostgresql-e5be89981fc70648eedb325781cf2fbd4da05ba8.tar.gz
postgresql-e5be89981fc70648eedb325781cf2fbd4da05ba8.zip
Refactoring by Heikki Linnakangas <heikki@enterprisedb.com> with
small editorization by me - Brake the QueryItem struct into QueryOperator and QueryOperand. Type was really the only common field between them. QueryItem still exists, and is used in the TSQuery struct as before, but it's now a union of the two. Many other changes fell from that, like separation of pushval_asis function into pushValue, pushOperator and pushStop. - Moved some structs that were for internal use only from header files to the right .c-files. - Moved tsvector parser to a new tsvector_parser.c file. Parser code was about half of the size of tsvector.c, it's also used from tsquery.c, and it has some data structures of its own, so it seems better to separate it. Cleaned up the API so that TSVectorParserState is not accessed from outside tsvector_parser.c. - Separated enumerations (#defines, really) used for QueryItem.type field and as return codes from gettoken_query. It was just accidental code sharing. - Removed ParseQueryNode struct used internally by makepol and friends. push*-functions now construct QueryItems directly. - Changed int4 variables to just ints for variables like "i" or "array size", where the storage-size was not significant.
Diffstat (limited to 'src/backend/utils/adt/tsrank.c')
-rw-r--r--src/backend/utils/adt/tsrank.c116
1 files changed, 72 insertions, 44 deletions
diff --git a/src/backend/utils/adt/tsrank.c b/src/backend/utils/adt/tsrank.c
index 8b2ab884c8c..d48e9b4a470 100644
--- a/src/backend/utils/adt/tsrank.c
+++ b/src/backend/utils/adt/tsrank.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/tsrank.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsrank.c,v 1.2 2007/09/07 15:09:56 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -68,7 +68,7 @@ cnt_length(TSVector t)
}
static int4
-WordECompareQueryItem(char *eval, char *qval, WordEntry * ptr, QueryItem * item)
+WordECompareQueryItem(char *eval, char *qval, WordEntry *ptr, QueryOperand *item)
{
if (ptr->len == item->length)
return strncmp(
@@ -80,7 +80,7 @@ WordECompareQueryItem(char *eval, char *qval, WordEntry * ptr, QueryItem * item)
}
static WordEntry *
-find_wordentry(TSVector t, TSQuery q, QueryItem * item)
+find_wordentry(TSVector t, TSQuery q, QueryOperand *item)
{
WordEntry *StopLow = ARRPTR(t);
WordEntry *StopHigh = (WordEntry *) STRPTR(t);
@@ -105,33 +105,48 @@ find_wordentry(TSVector t, TSQuery q, QueryItem * item)
}
+/*
+ * sort QueryOperands by (length, word)
+ */
static int
-compareQueryItem(const void *a, const void *b, void *arg)
+compareQueryOperand(const void *a, const void *b, void *arg)
{
char *operand = (char *) arg;
+ QueryOperand *qa = (*(QueryOperand **) a);
+ QueryOperand *qb = (*(QueryOperand **) b);
- if ((*(QueryItem **) a)->length == (*(QueryItem **) b)->length)
- return strncmp(operand + (*(QueryItem **) a)->distance,
- operand + (*(QueryItem **) b)->distance,
- (*(QueryItem **) b)->length);
+ if (qa->length == qb->length)
+ return strncmp(operand + qa->distance,
+ operand + qb->distance,
+ qb->length);
- return ((*(QueryItem **) a)->length > (*(QueryItem **) b)->length) ? 1 : -1;
+ return (qa->length > qb->length) ? 1 : -1;
}
-static QueryItem **
-SortAndUniqItems(char *operand, QueryItem * item, int *size)
+/*
+ * Returns a sorted, de-duplicated array of QueryOperands in a query.
+ * The returned QueryOperands are pointers to the original QueryOperands
+ * in the query.
+ *
+ * Length of the returned array is stored in *size
+ */
+static QueryOperand **
+SortAndUniqItems(TSQuery q, int *size)
{
- QueryItem **res,
+ char *operand = GETOPERAND(q);
+ QueryItem * item = GETQUERY(q);
+ QueryOperand **res,
**ptr,
**prevptr;
- ptr = res = (QueryItem **) palloc(sizeof(QueryItem *) * *size);
+ ptr = res = (QueryOperand **) palloc(sizeof(QueryOperand *) * *size);
+ /* Collect all operands from the tree to res */
while ((*size)--)
{
- if (item->type == VAL)
+ if (item->type == QI_VAL)
{
- *ptr = item;
+ *ptr = (QueryOperand *) item;
ptr++;
}
item++;
@@ -141,14 +156,15 @@ SortAndUniqItems(char *operand, QueryItem * item, int *size)
if (*size < 2)
return res;
- qsort_arg(res, *size, sizeof(QueryItem **), compareQueryItem, (void *) operand);
+ qsort_arg(res, *size, sizeof(QueryOperand **), compareQueryOperand, (void *) operand);
ptr = res + 1;
prevptr = res;
+ /* remove duplicates */
while (ptr - res < *size)
{
- if (compareQueryItem((void *) ptr, (void *) prevptr, (void *) operand) != 0)
+ if (compareQueryOperand((void *) ptr, (void *) prevptr, (void *) operand) != 0)
{
prevptr++;
*prevptr = *ptr;
@@ -180,10 +196,10 @@ calc_rank_and(float *w, TSVector t, TSQuery q)
lenct,
dist;
float res = -1.0;
- QueryItem **item;
+ QueryOperand **item;
int size = q->size;
- item = SortAndUniqItems(GETOPERAND(q), GETQUERY(q), &size);
+ item = SortAndUniqItems(q, &size);
if (size < 2)
{
pfree(item);
@@ -246,11 +262,11 @@ calc_rank_or(float *w, TSVector t, TSQuery q)
j,
i;
float res = 0.0;
- QueryItem **item;
+ QueryOperand **item;
int size = q->size;
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
- item = SortAndUniqItems(GETOPERAND(q), GETQUERY(q), &size);
+ item = SortAndUniqItems(q, &size);
for (i = 0; i < size; i++)
{
@@ -310,7 +326,8 @@ calc_rank(float *w, TSVector t, TSQuery q, int4 method)
if (!t->size || !q->size)
return 0.0;
- res = (item->type != VAL && item->val == (int4) '&') ?
+ /* XXX: What about NOT? */
+ res = (item->type == QI_OPR && item->operator.oper == OP_AND) ?
calc_rank_and(w, t, q) : calc_rank_or(w, t, q);
if (res < 0)
@@ -453,7 +470,7 @@ compareDocR(const void *a, const void *b)
}
static bool
-checkcondition_QueryItem(void *checkval, QueryItem * val)
+checkcondition_QueryOperand(void *checkval, QueryOperand *val)
{
return (bool) (val->istrue);
}
@@ -467,8 +484,8 @@ reset_istrue_flag(TSQuery query)
/* reset istrue flag */
for (i = 0; i < query->size; i++)
{
- if (item->type == VAL)
- item->istrue = 0;
+ if (item->type == QI_VAL)
+ item->operand.istrue = 0;
item++;
}
}
@@ -484,7 +501,7 @@ typedef struct
static bool
-Cover(DocRepresentation * doc, int len, TSQuery query, Extention * ext)
+Cover(DocRepresentation *doc, int len, TSQuery query, Extention *ext)
{
DocRepresentation *ptr;
int lastpos = ext->pos;
@@ -501,8 +518,11 @@ Cover(DocRepresentation * doc, int len, TSQuery query, Extention * ext)
while (ptr - doc < len)
{
for (i = 0; i < ptr->nitem; i++)
- ptr->item[i]->istrue = 1;
- if (TS_execute(GETQUERY(query), NULL, false, checkcondition_QueryItem))
+ {
+ if(ptr->item[i]->type == QI_VAL)
+ ptr->item[i]->operand.istrue = 1;
+ }
+ if (TS_execute(GETQUERY(query), NULL, false, checkcondition_QueryOperand))
{
if (ptr->pos > ext->q)
{
@@ -527,8 +547,9 @@ Cover(DocRepresentation * doc, int len, TSQuery query, Extention * ext)
while (ptr >= doc + ext->pos)
{
for (i = 0; i < ptr->nitem; i++)
- ptr->item[i]->istrue = 1;
- if (TS_execute(GETQUERY(query), NULL, true, checkcondition_QueryItem))
+ if(ptr->item[i]->type == QI_VAL) /* XXX */
+ ptr->item[i]->operand.istrue = 1;
+ if (TS_execute(GETQUERY(query), NULL, true, checkcondition_QueryOperand))
{
if (ptr->pos < ext->p)
{
@@ -575,10 +596,17 @@ get_docrep(TSVector txt, TSQuery query, int *doclen)
for (i = 0; i < query->size; i++)
{
- if (item[i].type != VAL || item[i].istrue)
+ QueryOperand *curoperand;
+
+ if (item[i].type != QI_VAL)
+ continue;
+
+ curoperand = &item[i].operand;
+
+ if(item[i].operand.istrue)
continue;
- entry = find_wordentry(txt, query, &(item[i]));
+ entry = find_wordentry(txt, query, curoperand);
if (!entry)
continue;
@@ -603,8 +631,6 @@ get_docrep(TSVector txt, TSQuery query, int *doclen)
{
if (j == 0)
{
- QueryItem *kptr,
- *iptr = item + i;
int k;
doc[cur].needfree = false;
@@ -613,14 +639,17 @@ get_docrep(TSVector txt, TSQuery query, int *doclen)
for (k = 0; k < query->size; k++)
{
- kptr = item + k;
+ QueryOperand *kptr = &item[k].operand;
+ QueryOperand *iptr = &item[i].operand;
+
if (k == i ||
- (item[k].type == VAL &&
- compareQueryItem(&kptr, &iptr, operand) == 0))
+ (item[k].type == QI_VAL &&
+ compareQueryOperand(&kptr, &iptr, operand) == 0))
{
+ /* if k == i, we've already checked above that it's type == Q_VAL */
doc[cur].item[doc[cur].nitem] = item + k;
doc[cur].nitem++;
- kptr->istrue = 1;
+ item[k].operand.istrue = 1;
}
}
}
@@ -640,8 +669,7 @@ get_docrep(TSVector txt, TSQuery query, int *doclen)
if (cur > 0)
{
- if (cur > 1)
- qsort((void *) doc, cur, sizeof(DocRepresentation), compareDocR);
+ qsort((void *) doc, cur, sizeof(DocRepresentation), compareDocR);
return doc;
}
@@ -746,7 +774,7 @@ ts_rankcd_wttf(PG_FUNCTION_ARGS)
{
ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
TSVector txt = PG_GETARG_TSVECTOR(1);
- TSQuery query = PG_GETARG_TSQUERY_COPY(2);
+ TSQuery query = PG_GETARG_TSQUERY_COPY(2); /* copy because we modify the istrue-flag */
int method = PG_GETARG_INT32(3);
float res;
@@ -763,7 +791,7 @@ ts_rankcd_wtt(PG_FUNCTION_ARGS)
{
ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
TSVector txt = PG_GETARG_TSVECTOR(1);
- TSQuery query = PG_GETARG_TSQUERY_COPY(2);
+ TSQuery query = PG_GETARG_TSQUERY_COPY(2); /* copy because we modify the istrue-flag */
float res;
res = calc_rank_cd(getWeights(win), txt, query, DEF_NORM_METHOD);
@@ -778,7 +806,7 @@ Datum
ts_rankcd_ttf(PG_FUNCTION_ARGS)
{
TSVector txt = PG_GETARG_TSVECTOR(0);
- TSQuery query = PG_GETARG_TSQUERY_COPY(1);
+ TSQuery query = PG_GETARG_TSQUERY_COPY(1); /* copy because we modify the istrue-flag */
int method = PG_GETARG_INT32(2);
float res;
@@ -793,7 +821,7 @@ Datum
ts_rankcd_tt(PG_FUNCTION_ARGS)
{
TSVector txt = PG_GETARG_TSVECTOR(0);
- TSQuery query = PG_GETARG_TSQUERY_COPY(1);
+ TSQuery query = PG_GETARG_TSQUERY_COPY(1); /* copy because we modify the istrue-flag */
float res;
res = calc_rank_cd(getWeights(NULL), txt, query, DEF_NORM_METHOD);