- *prox_term = '\0';
- for (i = 0; i<rset_no; i++)
- {
- int j;
- for (j = 0; j<rset[i]->no_rset_terms; j++)
- {
- const char *nflags = rset[i]->rset_terms[j]->flags;
- char *term = rset[i]->rset_terms[j]->name;
- int lterm = strlen(term);
- if (lterm + length_prox_term < sizeof(prox_term)-1)
- {
- if (length_prox_term)
- prox_term[length_prox_term++] = ' ';
- strcpy (prox_term + length_prox_term, term);
- length_prox_term += lterm;
- }
- if (min_nn > rset[i]->rset_terms[j]->nn)
- min_nn = rset[i]->rset_terms[j]->nn;
- flags = nflags;
- }
- }
- for (i = 0; i<rset_no; i++)
- {
- buf[i] = 0;
- rsfd[i] = 0;
- }
- for (i = 0; i<rset_no; i++)
- {
- buf[i] = (struct it_key *) xmalloc (sizeof(**buf));
- rsfd[i] = rset_open (rset[i], RSETF_READ);
- if (!(more[i] = rset_read (rset[i], rsfd[i], buf[i], &term_index)))
- break;
- }
- if (i != rset_no)
- {
- /* at least one is empty ... return null set */
- rset_null_parms parms;
-
- parms.rset_term = rset_term_create (prox_term, length_prox_term,
- flags);
- parms.rset_term->nn = 0;
- result = rset_create (rset_kind_null, &parms);
- }
- else if (ordered && relation == 3 && exclusion == 0 && distance == 1)
- {
- /* special proximity case = phrase search ... */
- rset_temp_parms parms;
- RSFD rsfd_result;
-
- parms.rset_term = rset_term_create (prox_term, length_prox_term,
- flags);
- parms.rset_term->nn = min_nn;
- parms.cmp = key_compare_it;
- parms.key_size = sizeof (struct it_key);
- parms.temp_path = res_get (zh->res, "setTmpDir");
- result = rset_create (rset_kind_temp, &parms);
- rsfd_result = rset_open (result, RSETF_WRITE);
-
- while (*more)
- {
- for (i = 1; i<rset_no; i++)
- {
- int cmp;
-
- if (!more[i])
- {
- *more = 0;
- break;
- }
- cmp = key_compare_it (buf[i], buf[i-1]);
- if (cmp > 1)
- {
- more[i-1] = rset_read (rset[i-1], rsfd[i-1],
- buf[i-1], &term_index);
- break;
- }
- else if (cmp == 1)
- {
- if (buf[i-1]->seqno+1 != buf[i]->seqno)
- {
- more[i-1] = rset_read (rset[i-1], rsfd[i-1],
- buf[i-1], &term_index);
- break;
- }
- }
- else
- {
- more[i] = rset_read (rset[i], rsfd[i], buf[i],
- &term_index);
- break;
- }
- }
- if (i == rset_no)
- {
- rset_write (result, rsfd_result, buf[0]);
- more[0] = rset_read (*rset, *rsfd, *buf, &term_index);
- }
- }
- rset_close (result, rsfd_result);
- }
- else if (rset_no == 2)
- {
- /* generic proximity case (two input sets only) ... */
- rset_temp_parms parms;
- RSFD rsfd_result;
-
- logf (LOG_LOG, "generic prox, dist = %d, relation = %d, ordered =%d, exclusion=%d",
- distance, relation, ordered, exclusion);
- parms.rset_term = rset_term_create (prox_term, length_prox_term,
- flags);
- parms.rset_term->nn = min_nn;
- parms.cmp = key_compare_it;
- parms.key_size = sizeof (struct it_key);
- parms.temp_path = res_get (zh->res, "setTmpDir");
- result = rset_create (rset_kind_temp, &parms);
- rsfd_result = rset_open (result, RSETF_WRITE);
-
- while (more[0] && more[1])
- {
- int cmp = key_compare_it (buf[0], buf[1]);
- if (cmp < -1)
- more[0] = rset_read (rset[0], rsfd[0], buf[0], &term_index);
- else if (cmp > 1)
- more[1] = rset_read (rset[1], rsfd[1], buf[1], &term_index);
- else
- {
- int sysno = buf[0]->sysno;
- int seqno[500];
- int n = 0;
-
- seqno[n++] = buf[0]->seqno;
- while ((more[0] = rset_read (rset[0], rsfd[0], buf[0],
- &term_index)) &&
- sysno == buf[0]->sysno)
- if (n < 500)
- seqno[n++] = buf[0]->seqno;
- do
- {
- for (i = 0; i<n; i++)
- {
- int diff = buf[1]->seqno - seqno[i];
- int excl = exclusion;
- if (!ordered && diff < 0)
- diff = -diff;
- switch (relation)
- {
- case 1: /* < */
- if (diff < distance && diff >= 0)
- excl = !excl;
- break;
- case 2: /* <= */
- if (diff <= distance && diff >= 0)
- excl = !excl;
- break;
- case 3: /* == */
- if (diff == distance && diff >= 0)
- excl = !excl;
- break;
- case 4: /* >= */
- if (diff >= distance && diff >= 0)
- excl = !excl;
- break;
- case 5: /* > */
- if (diff > distance && diff >= 0)
- excl = !excl;
- break;
- case 6: /* != */
- if (diff != distance && diff >= 0)
- excl = !excl;
- break;
- }
- if (excl)
- {
- rset_write (result, rsfd_result, buf[1]);
- break;
- }
- }
- } while ((more[1] = rset_read (rset[1], rsfd[1], buf[1],
- &term_index)) &&
- sysno == buf[1]->sysno);
- }
- }
- rset_close (result, rsfd_result);
- }