+void resultSetDestroy (ZebraHandle zh, int num, char **names,int *statuses)
+{
+ ZebraSet *ss = &zh->sets;
+ int i;
+
+ if (statuses)
+ for (i = 0; i<num; i++)
+ statuses[i] = Z_DeleteStatus_resultSetDidNotExist;
+ zh->errCode = 0;
+ zh->errString = NULL;
+ while (*ss)
+ {
+ int i = -1;
+ ZebraSet s = *ss;
+ if (num >= 0)
+ {
+ for (i = 0; i<num; i++)
+ if (!strcmp (s->name, names[i]))
+ {
+ if (statuses)
+ statuses[i] = Z_DeleteStatus_success;
+ i = -1;
+ break;
+ }
+ }
+ if (i < 0)
+ {
+ *ss = s->next;
+
+ xfree (s->sort_info->all_entries);
+ xfree (s->sort_info->entries);
+ xfree (s->sort_info);
+
+ if (s->nmem)
+ nmem_destroy (s->nmem);
+ if (s->rset)
+ rset_delete (s->rset);
+ xfree (s->name);
+ xfree (s);
+ }
+ else
+ ss = &s->next;
+ }
+}
+
+ZebraPosSet zebraPosSetCreate (ZebraHandle zh, const char *name,
+ int num, int *positions)
+{
+ ZebraSet sset;
+ ZebraPosSet sr = 0;
+ RSET rset;
+ int i;
+ struct zset_sort_info *sort_info;
+
+ if (!(sset = resultSetGet (zh, name)))
+ return NULL;
+ if (!(rset = sset->rset))
+ {
+ if (!sset->term_entries)
+ return 0;
+ sr = (ZebraPosSet) xmalloc (sizeof(*sr) * num);
+ for (i = 0; i<num; i++)
+ {
+ struct zebra_set_term_entry *entry = sset->term_entries;
+
+ sr[i].sysno = 0;
+ sr[i].score = -1;
+ sr[i].term = 0;
+ sr[i].db = 0;
+
+ if (positions[i] <= sset->term_entries_max)
+ {
+ sr[i].term = sset->term_entries[positions[i]-1].term;
+ sr[i].db = sset->term_entries[positions[i]-1].db;
+ }
+ }
+ }
+ else
+ {
+ sr = (ZebraPosSet) xmalloc (sizeof(*sr) * num);
+ for (i = 0; i<num; i++)
+ {
+ sr[i].sysno = 0;
+ sr[i].score = -1;
+ sr[i].term = 0;
+ sr[i].db = 0;
+ }
+ sort_info = sset->sort_info;
+ if (sort_info)
+ {
+ int position;
+
+ for (i = 0; i<num; i++)
+ {
+ position = positions[i];
+ if (position > 0 && position <= sort_info->num_entries)
+ {
+ logf (LOG_DEBUG, "got pos=%d (sorted)", position);
+ sr[i].sysno = sort_info->entries[position-1]->sysno;
+ sr[i].score = sort_info->entries[position-1]->score;
+ }
+ }
+ }
+ /* did we really get all entries using sort ? */
+ for (i = 0; i<num; i++)
+ {
+ if (!sr[i].sysno)
+ break;
+ }
+ if (i < num) /* nope, get the rest, unsorted - sorry */
+ {
+ int position = 0;
+ int num_i = 0;
+ int psysno = 0;
+ int term_index;
+ RSFD rfd;
+ struct it_key key;
+
+ if (sort_info)
+ position = sort_info->num_entries;
+ while (num_i < num && positions[num_i] < position)
+ num_i++;
+ rfd = rset_open (rset, RSETF_READ);
+ while (num_i < num && rset_read (rset, rfd, &key, &term_index))
+ {
+ if (key.sysno != psysno)
+ {
+ psysno = key.sysno;
+ if (sort_info)
+ {
+ /* determine we alreay have this in our set */
+ for (i = sort_info->num_entries; --i >= 0; )
+ if (psysno == sort_info->entries[i]->sysno)
+ break;
+ if (i >= 0)
+ continue;
+ }
+ position++;
+ assert (num_i < num);
+ if (position == positions[num_i])
+ {
+ sr[num_i].sysno = psysno;
+ logf (LOG_DEBUG, "got pos=%d (unsorted)", position);
+ sr[num_i].score = -1;
+ num_i++;
+ }
+ }
+ }
+ rset_close (rset, rfd);
+ }
+ }
+ return sr;
+}
+
+void zebraPosSetDestroy (ZebraHandle zh, ZebraPosSet records, int num)
+{
+ xfree (records);
+}
+
+struct sortKeyInfo {
+ int relation;
+ int attrUse;
+ int numerical;
+};
+
+void resultSetInsertSort (ZebraHandle zh, ZebraSet sset,
+ struct sortKeyInfo *criteria, int num_criteria,
+ int sysno)
+{
+ struct zset_sort_entry this_entry;
+ struct zset_sort_entry *new_entry = NULL;
+ struct zset_sort_info *sort_info = sset->sort_info;
+ int i, j;
+
+ sortIdx_sysno (zh->service->sortIdx, sysno);
+ for (i = 0; i<num_criteria; i++)
+ {
+ sortIdx_type (zh->service->sortIdx, criteria[i].attrUse);
+ sortIdx_read (zh->service->sortIdx, this_entry.buf[i]);
+ }
+ i = sort_info->num_entries;
+ while (--i >= 0)
+ {
+ int rel = 0;
+ for (j = 0; j<num_criteria; j++)
+ {
+ if (criteria[j].numerical)
+ {
+ double diff = atof(this_entry.buf[j]) -
+ atof(sort_info->entries[i]->buf[j]);
+ rel = 0;
+ if (diff > 0.0)
+ rel = 1;
+ else if (diff < 0.0)
+ rel = -1;
+ }
+ else
+ {
+ rel = memcmp (this_entry.buf[j], sort_info->entries[i]->buf[j],
+ SORT_IDX_ENTRYSIZE);
+ }
+ if (rel)
+ break;
+ }
+ if (!rel)
+ break;
+ if (criteria[j].relation == 'A')
+ {
+ if (rel > 0)
+ break;
+ }
+ else if (criteria[j].relation == 'D')
+ {
+ if (rel < 0)
+ break;
+ }
+ }
+ ++i;
+ j = sort_info->max_entries;
+ if (i == j)
+ return;
+
+ if (sort_info->num_entries == j)
+ --j;
+ else
+ j = (sort_info->num_entries)++;
+ new_entry = sort_info->entries[j];
+ while (j != i)
+ {
+ sort_info->entries[j] = sort_info->entries[j-1];
+ --j;
+ }
+ sort_info->entries[i] = new_entry;
+ assert (new_entry);
+ for (i = 0; i<num_criteria; i++)
+ memcpy (new_entry->buf[i], this_entry.buf[i], SORT_IDX_ENTRYSIZE);
+ new_entry->sysno = sysno;
+ new_entry->score = -1;
+}
+
+void resultSetInsertRank (ZebraHandle zh, struct zset_sort_info *sort_info,
+ int sysno, int score, int relation)