2 * Copyright (C) 1994-1998, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.13 1998-02-10 12:03:06 adam
10 * Revision 1.12 1997/09/25 14:57:36 adam
13 * Revision 1.11 1996/12/23 15:30:46 adam
15 * Bug fix: result sets weren't deleted after server shut down.
17 * Revision 1.10 1995/10/30 15:08:08 adam
20 * Revision 1.9 1995/10/17 18:02:14 adam
21 * New feature: databases. Implemented as prefix to words in dictionary.
23 * Revision 1.8 1995/10/10 13:59:25 adam
24 * Function rset_open changed its wflag parameter to general flags.
26 * Revision 1.7 1995/10/06 14:38:01 adam
27 * New result set method: r_score.
28 * Local no (sysno) and score is transferred to retrieveCtrl.
30 * Revision 1.6 1995/09/28 09:19:49 adam
31 * xfree/xmalloc used everywhere.
32 * Extract/retrieve method seems to work for text records.
34 * Revision 1.5 1995/09/27 16:17:32 adam
35 * More work on retrieve.
37 * Revision 1.4 1995/09/07 13:58:36 adam
38 * New parameter: result-set file descriptor (RSFD) to support multiple
39 * positions within the same result-set.
40 * Boolean operators: and, or, not implemented.
41 * Result-set references.
43 * Revision 1.3 1995/09/06 16:11:19 adam
44 * Option: only one word key per file.
46 * Revision 1.2 1995/09/06 10:33:04 adam
47 * More work on present. Some log messages removed.
49 * Revision 1.1 1995/09/05 15:28:40 adam
50 * More work on search engine.
64 #define SORT_IDX_ENTRYSIZE 64
65 #define ZSET_SORT_MAX_LEVEL 3
67 struct zset_sort_entry {
69 char buf[ZSET_SORT_MAX_LEVEL][SORT_IDX_ENTRYSIZE];
72 struct zset_sort_info {
75 struct zset_sort_entry **entries;
78 void resultSetSortReset (struct zset_sort_info **si)
83 for (i = 0; i<(*si)->num_entries; i++)
84 xfree ((*si)->entries[i]);
85 xfree ((*si)->entries);
90 ZServerSet *resultSetAdd (ZServerInfo *zi, const char *name, int ov, RSET rset)
94 for (s = zi->sets; s; s = s->next)
95 if (!strcmp (s->name, name))
97 logf (LOG_DEBUG, "updating result set %s", name);
100 resultSetSortReset (&s->sort_info);
101 rset_delete (s->rset);
105 logf (LOG_DEBUG, "adding result set %s", name);
106 s = xmalloc (sizeof(*s));
109 s->name = xmalloc (strlen(name)+1);
110 strcpy (s->name, name);
116 ZServerSet *resultSetGet (ZServerInfo *zi, const char *name)
120 for (s = zi->sets; s; s = s->next)
121 if (!strcmp (s->name, name))
127 void resultSetDestroy (ZServerInfo *zi)
131 for (s = zi->sets; s; s = s1)
134 resultSetSortReset (&s->sort_info);
135 rset_delete (s->rset);
142 ZServerSetSysno *resultSetSysnoGet (ZServerInfo *zi, const char *name,
143 int num, int *positions)
149 struct zset_sort_info *sort_info;
151 if (!(sset = resultSetGet (zi, name)))
153 if (!(rset = sset->rset))
155 sr = xmalloc (sizeof(*sr) * num);
156 for (i = 0; i<num; i++)
161 sort_info = sset->sort_info;
166 for (i = 0; i<num; i++)
168 position = positions[i];
169 if (position <= sort_info->num_entries)
171 logf (LOG_DEBUG, "got pos=%d (sorted)", position);
172 sr[i].sysno = sort_info->entries[position-1]->sysno;
176 /* did we really get all entries using sort ? */
177 for (i = 0; i<num; i++)
182 if (i < num) /* nope, get the rest, unsorted - sorry */
191 position = sort_info->num_entries;
192 while (num_i < num && positions[num_i] < position)
194 rfd = rset_open (rset, RSETF_READ|RSETF_SORT_RANK);
195 while (num_i < num && rset_read (rset, rfd, &key))
197 if (key.sysno != psysno)
202 /* determine we alreay have this in our set */
203 for (i = sort_info->num_entries; --i >= 0; )
204 if (psysno == sort_info->entries[i]->sysno)
210 assert (num_i < num);
211 if (position == positions[num_i])
213 sr[num_i].sysno = psysno;
214 logf (LOG_DEBUG, "got pos=%d (unsorted)", position);
215 rset_score (rset, rfd, &sr[num_i].score);
220 rset_close (rset, rfd);
225 void resultSetSysnoDel (ZServerInfo *zi, ZServerSetSysno *records, int num)
235 void resultSetInsertSort (ZServerInfo *zi, ZServerSet *sset,
236 struct sortKey *criteria, int num_criteria,
239 struct zset_sort_entry this_entry;
240 struct zset_sort_entry *new_entry = NULL;
241 struct zset_sort_info *sort_info = sset->sort_info;
244 sortIdx_sysno (zi->sortIdx, sysno);
245 for (i = 0; i<num_criteria; i++)
247 sortIdx_type (zi->sortIdx, criteria[i].attrUse);
248 sortIdx_read (zi->sortIdx, this_entry.buf[i]);
250 i = sort_info->num_entries;
254 for (j = 0; j<num_criteria; j++)
256 rel = memcmp (this_entry.buf[j], sort_info->entries[i]->buf[j],
263 if (criteria[j].relation == 'D')
266 if (criteria[j].relation == 'A')
271 j = sort_info->max_entries-1;
275 new_entry = sort_info->entries[j];
278 sort_info->entries[j] = sort_info->entries[j-1];
281 sort_info->entries[j] = new_entry;
283 if (sort_info->num_entries != sort_info->max_entries)
284 (sort_info->num_entries)++;
285 for (i = 0; i<num_criteria; i++)
286 memcpy (new_entry->buf[i], this_entry.buf[i], SORT_IDX_ENTRYSIZE);
287 new_entry->sysno = sysno;
290 int resultSetSort (ZServerInfo *zi, bend_sort_rr *rr)
296 struct sortKey sort_criteria[3];
300 if (rr->num_input_setnames == 0)
305 if (rr->num_input_setnames > 1)
310 sset = resultSetGet (zi, rr->input_setnames[0]);
314 rr->errstring = rr->input_setnames[0];
317 if (!(rset = sset->rset))
320 rr->errstring = rr->input_setnames[0];
323 num_criteria = rr->sort_sequence->num_specs;
324 if (num_criteria > 3)
326 for (i = 0; i < num_criteria; i++)
328 Z_SortKeySpec *sks = rr->sort_sequence->specs[i];
331 if (*sks->sortRelation == Z_SortRelation_ascending)
332 sort_criteria[i].relation = 'A';
333 else if (*sks->sortRelation == Z_SortRelation_descending)
334 sort_criteria[i].relation = 'D';
340 if (sks->sortElement->which == Z_SortElement_databaseSpecific)
345 else if (sks->sortElement->which != Z_SortElement_generic)
350 sk = sks->sortElement->u.generic;
353 case Z_SortKey_sortField:
354 logf (LOG_DEBUG, "Sort: key %d is of type sortField", i+1);
357 case Z_SortKey_elementSpec:
358 logf (LOG_DEBUG, "Sort: key %d is of type elementSpec", i+1);
360 case Z_SortKey_sortAttributes:
361 logf (LOG_DEBUG, "Sort: key %d is of type sortAttributes", i+1);
362 sort_criteria[i].attrUse =
363 zebra_maps_sort (zi->zebra_maps, sk->u.sortAttributes);
364 logf (LOG_DEBUG, "use value = %d", sort_criteria[i].attrUse);
365 if (sort_criteria[i].attrUse == -1)
370 if (sortIdx_type (zi->sortIdx, sort_criteria[i].attrUse))
378 if (strcmp (rr->output_setname, rr->input_setnames[0]))
380 rset = rset_dup (rset);
381 sset = resultSetAdd (zi, rr->output_setname, 1, rset);
383 resultSetSortReset (&sset->sort_info);
385 sset->sort_info = xmalloc (sizeof(*sset->sort_info));
386 sset->sort_info->max_entries = 10;
387 sset->sort_info->num_entries = 0;
388 sset->sort_info->entries = xmalloc (sizeof(*sset->sort_info->entries) *
389 sset->sort_info->max_entries);
390 for (i = 0; i<sset->sort_info->max_entries; i++)
391 sset->sort_info->entries[i] =
392 xmalloc (sizeof(*sset->sort_info->entries[i]));
395 rfd = rset_open (rset, RSETF_READ|RSETF_SORT_SYSNO);
396 while (rset_read (rset, rfd, &key))
398 if (key.sysno != psysno)
401 resultSetInsertSort (zi, sset,
402 sort_criteria, num_criteria, psysno);
405 rset_close (rset, rfd);
408 rr->sort_status = Z_SortStatus_success;