2 * Copyright (C) 1994-1998, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.14 1998-02-10 16:39:15 adam
10 * Revision 1.13 1998/02/10 12:03:06 adam
13 * Revision 1.12 1997/09/25 14:57:36 adam
16 * Revision 1.11 1996/12/23 15:30:46 adam
18 * Bug fix: result sets weren't deleted after server shut down.
20 * Revision 1.10 1995/10/30 15:08:08 adam
23 * Revision 1.9 1995/10/17 18:02:14 adam
24 * New feature: databases. Implemented as prefix to words in dictionary.
26 * Revision 1.8 1995/10/10 13:59:25 adam
27 * Function rset_open changed its wflag parameter to general flags.
29 * Revision 1.7 1995/10/06 14:38:01 adam
30 * New result set method: r_score.
31 * Local no (sysno) and score is transferred to retrieveCtrl.
33 * Revision 1.6 1995/09/28 09:19:49 adam
34 * xfree/xmalloc used everywhere.
35 * Extract/retrieve method seems to work for text records.
37 * Revision 1.5 1995/09/27 16:17:32 adam
38 * More work on retrieve.
40 * Revision 1.4 1995/09/07 13:58:36 adam
41 * New parameter: result-set file descriptor (RSFD) to support multiple
42 * positions within the same result-set.
43 * Boolean operators: and, or, not implemented.
44 * Result-set references.
46 * Revision 1.3 1995/09/06 16:11:19 adam
47 * Option: only one word key per file.
49 * Revision 1.2 1995/09/06 10:33:04 adam
50 * More work on present. Some log messages removed.
52 * Revision 1.1 1995/09/05 15:28:40 adam
53 * More work on search engine.
67 #define SORT_IDX_ENTRYSIZE 64
68 #define ZSET_SORT_MAX_LEVEL 3
70 struct zset_sort_entry {
72 char buf[ZSET_SORT_MAX_LEVEL][SORT_IDX_ENTRYSIZE];
75 struct zset_sort_info {
78 struct zset_sort_entry **entries;
81 void resultSetSortReset (struct zset_sort_info **si)
86 for (i = 0; i<(*si)->num_entries; i++)
87 xfree ((*si)->entries[i]);
88 xfree ((*si)->entries);
93 ZServerSet *resultSetAdd (ZServerInfo *zi, const char *name, int ov, RSET rset)
97 for (s = zi->sets; s; s = s->next)
98 if (!strcmp (s->name, name))
100 logf (LOG_DEBUG, "updating result set %s", name);
103 resultSetSortReset (&s->sort_info);
104 rset_delete (s->rset);
108 logf (LOG_DEBUG, "adding result set %s", name);
109 s = xmalloc (sizeof(*s));
112 s->name = xmalloc (strlen(name)+1);
113 strcpy (s->name, name);
119 ZServerSet *resultSetGet (ZServerInfo *zi, const char *name)
123 for (s = zi->sets; s; s = s->next)
124 if (!strcmp (s->name, name))
130 void resultSetDestroy (ZServerInfo *zi)
134 for (s = zi->sets; s; s = s1)
137 resultSetSortReset (&s->sort_info);
138 rset_delete (s->rset);
145 ZServerSetSysno *resultSetSysnoGet (ZServerInfo *zi, const char *name,
146 int num, int *positions)
152 struct zset_sort_info *sort_info;
154 if (!(sset = resultSetGet (zi, name)))
156 if (!(rset = sset->rset))
158 sr = xmalloc (sizeof(*sr) * num);
159 for (i = 0; i<num; i++)
164 sort_info = sset->sort_info;
169 for (i = 0; i<num; i++)
171 position = positions[i];
172 if (position <= sort_info->num_entries)
174 logf (LOG_DEBUG, "got pos=%d (sorted)", position);
175 sr[i].sysno = sort_info->entries[position-1]->sysno;
179 /* did we really get all entries using sort ? */
180 for (i = 0; i<num; i++)
185 if (i < num) /* nope, get the rest, unsorted - sorry */
194 position = sort_info->num_entries;
195 while (num_i < num && positions[num_i] < position)
197 rfd = rset_open (rset, RSETF_READ|RSETF_SORT_RANK);
198 while (num_i < num && rset_read (rset, rfd, &key))
200 if (key.sysno != psysno)
205 /* determine we alreay have this in our set */
206 for (i = sort_info->num_entries; --i >= 0; )
207 if (psysno == sort_info->entries[i]->sysno)
213 assert (num_i < num);
214 if (position == positions[num_i])
216 sr[num_i].sysno = psysno;
217 logf (LOG_DEBUG, "got pos=%d (unsorted)", position);
218 rset_score (rset, rfd, &sr[num_i].score);
223 rset_close (rset, rfd);
228 void resultSetSysnoDel (ZServerInfo *zi, ZServerSetSysno *records, int num)
238 void resultSetInsertSort (ZServerInfo *zi, ZServerSet *sset,
239 struct sortKey *criteria, int num_criteria,
242 struct zset_sort_entry this_entry;
243 struct zset_sort_entry *new_entry = NULL;
244 struct zset_sort_info *sort_info = sset->sort_info;
247 sortIdx_sysno (zi->sortIdx, sysno);
248 for (i = 0; i<num_criteria; i++)
250 sortIdx_type (zi->sortIdx, criteria[i].attrUse);
251 sortIdx_read (zi->sortIdx, this_entry.buf[i]);
253 i = sort_info->num_entries;
257 for (j = 0; j<num_criteria; j++)
259 rel = memcmp (this_entry.buf[j], sort_info->entries[i]->buf[j],
266 if (criteria[j].relation == 'D')
269 if (criteria[j].relation == 'A')
274 j = sort_info->max_entries-1;
278 new_entry = sort_info->entries[j];
281 sort_info->entries[j] = sort_info->entries[j-1];
284 sort_info->entries[j] = new_entry;
286 if (sort_info->num_entries != sort_info->max_entries)
287 (sort_info->num_entries)++;
288 for (i = 0; i<num_criteria; i++)
289 memcpy (new_entry->buf[i], this_entry.buf[i], SORT_IDX_ENTRYSIZE);
290 new_entry->sysno = sysno;
293 int resultSetSort (ZServerInfo *zi, bend_sort_rr *rr)
299 struct sortKey sort_criteria[3];
303 if (rr->num_input_setnames == 0)
308 if (rr->num_input_setnames > 1)
313 sset = resultSetGet (zi, rr->input_setnames[0]);
317 rr->errstring = rr->input_setnames[0];
320 if (!(rset = sset->rset))
323 rr->errstring = rr->input_setnames[0];
326 num_criteria = rr->sort_sequence->num_specs;
327 if (num_criteria > 3)
329 for (i = 0; i < num_criteria; i++)
331 Z_SortKeySpec *sks = rr->sort_sequence->specs[i];
334 if (*sks->sortRelation == Z_SortRelation_ascending)
335 sort_criteria[i].relation = 'A';
336 else if (*sks->sortRelation == Z_SortRelation_descending)
337 sort_criteria[i].relation = 'D';
343 if (sks->sortElement->which == Z_SortElement_databaseSpecific)
348 else if (sks->sortElement->which != Z_SortElement_generic)
353 sk = sks->sortElement->u.generic;
356 case Z_SortKey_sortField:
357 logf (LOG_DEBUG, "Sort: key %d is of type sortField", i+1);
360 case Z_SortKey_elementSpec:
361 logf (LOG_DEBUG, "Sort: key %d is of type elementSpec", i+1);
363 case Z_SortKey_sortAttributes:
364 logf (LOG_DEBUG, "Sort: key %d is of type sortAttributes", i+1);
365 sort_criteria[i].attrUse =
366 zebra_maps_sort (zi->zebra_maps, sk->u.sortAttributes);
367 logf (LOG_DEBUG, "use value = %d", sort_criteria[i].attrUse);
368 if (sort_criteria[i].attrUse == -1)
373 if (sortIdx_type (zi->sortIdx, sort_criteria[i].attrUse))
381 if (strcmp (rr->output_setname, rr->input_setnames[0]))
383 rset = rset_dup (rset);
384 sset = resultSetAdd (zi, rr->output_setname, 1, rset);
386 resultSetSortReset (&sset->sort_info);
388 sset->sort_info = xmalloc (sizeof(*sset->sort_info));
389 sset->sort_info->max_entries = 100;
390 sset->sort_info->num_entries = 0;
391 sset->sort_info->entries = xmalloc (sizeof(*sset->sort_info->entries) *
392 sset->sort_info->max_entries);
393 for (i = 0; i<sset->sort_info->max_entries; i++)
394 sset->sort_info->entries[i] =
395 xmalloc (sizeof(*sset->sort_info->entries[i]));
398 rfd = rset_open (rset, RSETF_READ|RSETF_SORT_SYSNO);
399 while (rset_read (rset, rfd, &key))
401 if (key.sysno != psysno)
404 resultSetInsertSort (zi, sset,
405 sort_criteria, num_criteria, psysno);
408 rset_close (rset, rfd);
411 rr->sort_status = Z_SortStatus_success;