@@ -43,6 +43,8 @@ static float weights[] = {0.1, 0.2, 0.4, 1.0};
4343
4444#define DEF_NORM_METHOD 0
4545
46+ static float calc_rank_or (float * w ,tsvector * t ,QUERYTYPE * q );
47+ static float calc_rank_and (float * w ,tsvector * t ,QUERYTYPE * q );
4648/*
4749 * Returns a weight of a word collocation
4850 */
@@ -112,6 +114,55 @@ find_wordentry(tsvector * t, QUERYTYPE * q, ITEM * item)
112114return NULL ;
113115}
114116
117+
118+ static char * SortAndUniqOperand = NULL ;
119+
120+ static int
121+ compareITEM (const void * a ,const void * b ) {
122+ if ( (* (ITEM * * )a )-> length == (* (ITEM * * )b )-> length )
123+ return strncmp (SortAndUniqOperand + (* (ITEM * * )a )-> distance ,
124+ SortAndUniqOperand + (* (ITEM * * )b )-> distance ,
125+ (* (ITEM * * )b )-> length );
126+
127+ return ((* (ITEM * * )a )-> length > (* (ITEM * * )b )-> length ) ?1 :-1 ;
128+ }
129+
130+ static ITEM * *
131+ SortAndUniqItems (char * operand ,ITEM * item ,int * size ) {
132+ ITEM * * res ,* * ptr ,* * prevptr ;
133+
134+ ptr = res = (ITEM * * )palloc (sizeof (ITEM * )* * size );
135+
136+ while ( (* size )-- ) {
137+ if (item -> type == VAL ) {
138+ * ptr = item ;
139+ ptr ++ ;
140+ }
141+ item ++ ;
142+ }
143+
144+ * size = ptr - res ;
145+ if (* size < 2 )
146+ return res ;
147+
148+ SortAndUniqOperand = operand ;
149+ qsort (res ,* size ,sizeof (ITEM * * ),compareITEM );
150+
151+ ptr = res + 1 ;
152+ prevptr = res ;
153+
154+ while (ptr - res < * size ) {
155+ if (compareITEM ( (void * )ptr , (void * )prevptr )!= 0 ) {
156+ prevptr ++ ;
157+ * prevptr = * ptr ;
158+ }
159+ ptr ++ ;
160+ }
161+
162+ * size = prevptr + 1 - res ;
163+ return res ;
164+ }
165+
115166static WordEntryPos POSNULL []= {
1161670 ,
1171680
@@ -120,7 +171,7 @@ static WordEntryPos POSNULL[] = {
120171static float
121172calc_rank_and (float * w ,tsvector * t ,QUERYTYPE * q )
122173{
123- uint16 * * pos = ( uint16 * * ) palloc ( sizeof ( uint16 * ) * q -> size ) ;
174+ uint16 * * pos ;
124175int i ,
125176k ,
126177l ,
@@ -132,19 +183,22 @@ calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
132183lenct ,
133184dist ;
134185float res = -1.0 ;
135- ITEM * item = GETQUERY (q );
136-
137- memset (pos ,0 ,sizeof (uint16 * * )* q -> size );
186+ ITEM * * item ;
187+ int size = q -> size ;
188+
189+ item = SortAndUniqItems (GETOPERAND (q ),GETQUERY (q ),& size );
190+ if (size < 2 ) {
191+ pfree (item );
192+ return calc_rank_or (w ,t ,q );
193+ }
194+ pos = (uint16 * * )palloc (sizeof (uint16 * )* q -> size );
195+ memset (pos ,0 ,sizeof (uint16 * )* q -> size );
138196* (uint16 * )POSNULL = lengthof (POSNULL )- 1 ;
139- WEP_SETPOS (POSNULL [1 ],MAXENTRYPOS - 1 );
197+ WEP_SETPOS (POSNULL [1 ],MAXENTRYPOS - 1 );
140198
141- for (i = 0 ;i < q -> size ;i ++ )
199+ for (i = 0 ;i < size ;i ++ )
142200{
143-
144- if (item [i ].type != VAL )
145- continue ;
146-
147- entry = find_wordentry (t ,q ,& (item [i ]));
201+ entry = find_wordentry (t ,q ,item [i ]);
148202if (!entry )
149203continue ;
150204
@@ -181,6 +235,7 @@ calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
181235}
182236}
183237pfree (pos );
238+ pfree (item );
184239return res ;
185240}
186241
@@ -193,16 +248,15 @@ calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
193248j ,
194249i ;
195250float res = -1.0 ;
196- ITEM * item = GETQUERY (q );
251+ ITEM * * item ;
252+ int size = q -> size ;
197253
198254* (uint16 * )POSNULL = lengthof (POSNULL )- 1 ;
255+ item = SortAndUniqItems (GETOPERAND (q ),GETQUERY (q ),& size );
199256
200- for (i = 0 ;i < q -> size ;i ++ )
257+ for (i = 0 ;i < size ;i ++ )
201258{
202- if (item [i ].type != VAL )
203- continue ;
204-
205- entry = find_wordentry (t ,q ,& (item [i ]));
259+ entry = find_wordentry (t ,q ,item [i ]);
206260if (!entry )
207261continue ;
208262
@@ -225,6 +279,7 @@ calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
225279res = 1.0 - (1.0 - res )* (1.0 - wpos (post [j ]));
226280}
227281}
282+ pfree (item );
228283return res ;
229284}
230285
@@ -349,7 +404,7 @@ checkcondition_DR(void *checkval, ITEM * val)
349404
350405while (ptr - ((ChkDocR * )checkval )-> doc < ((ChkDocR * )checkval )-> len )
351406{
352- if (val == ptr -> item )
407+ if (val == ptr -> item || compareITEM ( & val , & ( ptr -> item ) ) == 0 )
353408return true;
354409ptr ++ ;
355410}
@@ -439,6 +494,7 @@ Cover(DocRepresentation * doc, int len, QUERYTYPE * query, int *pos, int *p, int
439494ch .doc = f ;
440495ch .len = (doc + lastpos )- f + 1 ;
441496* pos = f - doc + 1 ;
497+ SortAndUniqOperand = GETOPERAND (query );
442498if (TS_execute (GETQUERY (query ),& ch , false,checkcondition_DR ))
443499{
444500/*