+void zebraPosSetDestroy (ZebraHandle zh, ZebraPosSet records, int num)
+{
+ assert(zh); /* compiler shut up about unused arg */
+ xfree (records);
+}
+
+struct sortKeyInfo {
+ int relation;
+ int attrUse;
+ int numerical;
+};
+
+void resultSetInsertSort (ZebraHandle zh, ZebraSet sset,
+ struct sortKeyInfo *criteria, int num_criteria,
+ zint 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->reg->sortIdx, sysno);
+ for (i = 0; i<num_criteria; i++)
+ {
+ sortIdx_type (zh->reg->sortIdx, criteria[i].attrUse);
+ sortIdx_read (zh->reg->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,
+ zint sysno, int score, int relation)
+{
+ struct zset_sort_entry *new_entry = NULL;
+ int i, j;
+ assert(zh); /* compiler shut up about unused arg */
+
+ i = sort_info->num_entries;
+ while (--i >= 0)
+ {
+ int rel = 0;
+
+ rel = score - sort_info->entries[i]->score;
+
+ if (relation == 'D')
+ {
+ if (rel >= 0)
+ break;
+ }
+ else if (relation == 'A')
+ {
+ 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);
+ new_entry->sysno = sysno;
+ new_entry->score = score;
+}
+
+void resultSetSort (ZebraHandle zh, NMEM nmem,
+ int num_input_setnames, const char **input_setnames,
+ const char *output_setname,
+ Z_SortKeySpecList *sort_sequence, int *sort_status)
+{
+ ZebraSet sset;
+ RSET rset;
+
+ if (num_input_setnames == 0)
+ {
+ zh->errCode = 208;
+ return ;
+ }
+ if (num_input_setnames > 1)
+ {
+ zh->errCode = 230;
+ return;
+ }
+ yaz_log (LOG_DEBUG, "result set sort input=%s output=%s",
+ *input_setnames, output_setname);
+ sset = resultSetGet (zh, input_setnames[0]);
+ if (!sset)
+ {
+ zh->errCode = 30;
+ zh->errString = nmem_strdup (nmem, input_setnames[0]);
+ return;
+ }
+ if (!(rset = sset->rset))
+ {
+ zh->errCode = 30;
+ zh->errString = nmem_strdup (nmem, input_setnames[0]);
+ return;
+ }
+ if (strcmp (output_setname, input_setnames[0]))
+ {
+ rset = rset_dup (rset);
+ sset = resultSetAdd (zh, output_setname, 1);
+ sset->rset = rset;
+ }
+ resultSetSortSingle (zh, nmem, sset, rset, sort_sequence, sort_status);
+}
+
+void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
+ ZebraSet sset, RSET rset,
+ Z_SortKeySpecList *sort_sequence, int *sort_status)