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