+static RSET rpn_proximity (ZServerInfo *zi, RSET rset1, RSET rset2,
+ int ordered,
+ int exclusion, int relation, int distance)
+{
+ int i;
+ RSFD rsfd1, rsfd2;
+ int more1, more2;
+ struct it_key buf1, buf2;
+ RSFD rsfd_result;
+ RSET result;
+ rset_temp_parms parms;
+
+ rsfd1 = rset_open (rset1, RSETF_READ|RSETF_SORT_SYSNO);
+ more1 = rset_read (rset1, rsfd1, &buf1);
+
+ rsfd2 = rset_open (rset2, RSETF_READ|RSETF_SORT_SYSNO);
+ more2 = rset_read (rset2, rsfd2, &buf2);
+
+ parms.key_size = sizeof (struct it_key);
+ parms.temp_path = res_get (zi->res, "setTmpDir");
+ result = rset_create (rset_kind_temp, &parms);
+ rsfd_result = rset_open (result, RSETF_WRITE|RSETF_SORT_SYSNO);
+
+ logf (LOG_DEBUG, "rpn_proximity excl=%d ord=%d rel=%d dis=%d",
+ exclusion, ordered, relation, distance);
+ while (more1 && more2)
+ {
+ int cmp = key_compare_it (&buf1, &buf2);
+ if (cmp < -1)
+ more1 = rset_read (rset1, rsfd1, &buf1);
+ else if (cmp > 1)
+ more2 = rset_read (rset2, rsfd2, &buf2);
+ else
+ {
+ int sysno = buf1.sysno;
+ int seqno[500];
+ int n = 0;
+
+ seqno[n++] = buf1.seqno;
+ while ((more1 = rset_read (rset1, rsfd1, &buf1)) &&
+ sysno == buf1.sysno)
+ if (n < 500)
+ seqno[n++] = buf1.seqno;
+ do
+ {
+ for (i = 0; i<n; i++)
+ {
+ int diff = buf2.seqno - seqno[i];
+ int excl = exclusion;
+ if (!ordered && diff < 0)
+ diff = -diff;
+ switch (relation)
+ {
+ case 1: /* < */
+ if (diff < distance)
+ excl = !excl;
+ break;
+ case 2: /* <= */
+ if (diff <= distance)
+ excl = !excl;
+ break;
+ case 3: /* == */
+ if (diff == distance)
+ excl = !excl;
+ break;
+ case 4: /* >= */
+ if (diff >= distance)
+ excl = !excl;
+ break;
+ case 5: /* > */
+ if (diff > distance)
+ excl = !excl;
+ break;
+ case 6: /* != */
+ if (diff != distance)
+ excl = !excl;
+ break;
+ }
+ if (excl)
+ rset_write (result, rsfd_result, &buf2);
+ }
+ } while ((more2 = rset_read (rset2, rsfd2, &buf2)) &&
+ sysno == buf2.sysno);
+ }
+ }
+ rset_close (result, rsfd_result);
+ rset_close (rset1, rsfd1);
+ rset_close (rset2, rsfd2);
+ return result;
+}
+
+static RSET rpn_prox (ZServerInfo *zi, RSET *rset, int rset_no)