Option: only one word key per file.
[idzebra-moved-to-github.git] / index / zrpn.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: zrpn.c,v $
7  * Revision 1.6  1995-09-06 16:11:18  adam
8  * Option: only one word key per file.
9  *
10  * Revision 1.5  1995/09/06  10:33:04  adam
11  * More work on present. Some log messages removed.
12  *
13  * Revision 1.4  1995/09/05  15:28:40  adam
14  * More work on search engine.
15  *
16  * Revision 1.3  1995/09/04  15:20:22  adam
17  * Minor changes.
18  *
19  * Revision 1.2  1995/09/04  12:33:43  adam
20  * Various cleanup. YAZ util used instead.
21  *
22  * Revision 1.1  1995/09/04  09:10:40  adam
23  * More work on index add/del/update.
24  * Merge sort implemented.
25  * Initial work on z39 server.
26  *
27  */
28 #include <stdio.h>
29 #include <assert.h>
30 #include <unistd.h>
31
32 #include "zserver.h"
33
34 #include <rsisam.h>
35 #include <rstemp.h>
36 #include <rsnull.h>
37
38 static RSET rpn_search_APT (ZServerInfo *zi, Z_AttributesPlusTerm *zapt)
39 {
40     char termz[256];
41     size_t sizez;
42     struct rset_isam_parms parms;
43     const char *info;
44     Z_Term *term = zapt->term;
45
46     if (term->which != Z_Term_general)
47         return NULL; 
48     sizez = term->u.general->len;
49     if (sizez > 255)
50         sizez = 255;
51     memcpy (termz, term->u.general->buf, sizez);
52     termz[sizez] = '\0';
53     logf (LOG_DEBUG, "dict_lookup: %s", termz);
54     if (!(info = dict_lookup (zi->wordDict, termz)))
55         return rset_create (rset_kind_null, NULL);
56     assert (*info == sizeof(parms.pos));
57     memcpy (&parms.pos, info+1, sizeof(parms.pos));
58     parms.is = zi->wordIsam;
59     logf (LOG_DEBUG, "rset_create isam");
60     return rset_create (rset_kind_isam, &parms);
61 }
62
63 static RSET rpn_search_and (ZServerInfo *zi, RSET r_l, RSET r_r)
64 {
65     struct it_key k1, k2;
66     RSET r_dst;
67     int i1, i2;
68     rset_open (r_l, 0);
69     rset_open (r_r, 0);
70     r_dst = rset_create (rset_kind_temp, NULL);
71     rset_open (r_dst, 1);
72     
73     i1 = rset_read (r_l, &k1);
74     i2 = rset_read (r_r, &k2);
75     while (i1 && i2)
76     {
77         if (k1.sysno > k2.sysno)
78             i2 = rset_read (r_r, &k2);
79         else if (k1.sysno < k2.sysno)
80             i1 = rset_read (r_l, &k1);
81         else if (!(i1 = key_compare_x (&k1, &k2)))
82         {
83             rset_write (r_dst, &k1);
84             i1 = rset_read (r_l, &k1);
85             i2 = rset_read (r_r, &k2);
86         }
87         else if (i1 > 0)
88         {
89             rset_write (r_dst, &k2);
90             i2 = rset_read (r_r, &k2);
91         }
92         else
93         {
94             rset_write (r_dst, &k1);
95             i1 = rset_read (r_l, &k1);
96         }
97     } 
98     rset_close (r_dst);
99     return r_dst;
100 }
101
102 static RSET rpn_search_or (ZServerInfo *zi, RSET r_l, RSET r_r)
103 {
104     return r_l;
105 }
106
107 static RSET rpn_search_not (ZServerInfo *zi, RSET r_l, RSET r_r)
108 {
109     return r_l;
110 }
111
112 static RSET rpn_search_ref (ZServerInfo *zi, Z_ResultSetId *resultSetId)
113 {
114     return NULL;
115 }
116
117 static RSET rpn_search_structure (ZServerInfo *zi, Z_RPNStructure *zs)
118 {
119     RSET r;
120     if (zs->which == Z_RPNStructure_complex)
121     {
122         RSET r_l, r_r;
123
124         r_l = rpn_search_structure (zi, zs->u.complex->s1);
125         r_r = rpn_search_structure (zi, zs->u.complex->s2);
126
127         switch (zs->u.complex->operator->which)
128         {
129         case Z_Operator_and:
130             rset_delete (r_r);
131             break;
132         case Z_Operator_or:
133             rset_delete (r_r);
134             break;
135         case Z_Operator_and_not:
136             rset_delete (r_r);
137             break;
138         default:
139             assert (0);
140         }
141         r = r_l;
142     }
143     else if (zs->which == Z_RPNStructure_simple)
144     {
145         if (zs->u.simple->which == Z_Operand_APT)
146         {
147             logf (LOG_DEBUG, "rpn_search_APT");
148             r = rpn_search_APT (zi, zs->u.simple->u.attributesPlusTerm);
149         }
150         else if (zs->u.simple->which == Z_Operand_resultSetId)
151         {
152             logf (LOG_DEBUG, "rpn_search_ref");
153             r = rpn_search_ref (zi, zs->u.simple->u.resultSetId);
154         }
155         else
156         {
157             assert (0);
158         }
159     }
160     else
161     {
162         assert (0);
163     }
164     return r;
165 }
166
167 static RSET rpn_save_set (RSET r, int *count)
168 {
169 #if 0
170     RSET d;
171     rset_temp_parms parms;
172 #endif
173     int psysno = 0;
174     struct it_key key;
175
176     logf (LOG_DEBUG, "rpn_save_set");
177     *count = 0;
178 #if 0
179     parms.key_size = sizeof(struct it_key);
180     d = rset_create (rset_kind_temp, &parms);
181     rset_open (d, 1);
182 #endif
183
184     rset_open (r, 0);
185     while (rset_read (r, &key))
186     {
187         if (key.sysno != psysno)
188         {
189             psysno = key.sysno;
190             (*count)++;
191         }
192 #if 0
193         rset_write (d, &key);
194 #endif
195     }
196     rset_close (r);
197 #if 0
198     rset_close (d);
199 #endif
200     logf (LOG_DEBUG, "%d distinct sysnos", *count);
201 #if 0
202     return d;
203 #endif
204 }
205
206 int rpn_search (ZServerInfo *zi,
207                 Z_RPNQuery *rpn, int num_bases, char **basenames, 
208                 const char *setname, int *hits)
209 {
210     RSET rset, result_rset;
211
212     rset = rpn_search_structure (zi, rpn->RPNStructure);
213     if (!rset)
214         return 0;
215     result_rset = rpn_save_set (rset, hits);
216 #if 0
217     rset_delete (result_rset);
218 #endif
219
220     resultSetAdd (zi, setname, 1, rset);
221     return 0;
222 }
223