More work on index add/del/update.
[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.1  1995-09-04 09:10:40  adam
8  * More work on index add/del/update.
9  * Merge sort implemented.
10  * Initial work on z39 server.
11  *
12  */
13 #include <stdio.h>
14 #include <assert.h>
15 #include <unistd.h>
16
17 #include <util.h>
18 #include <dict.h>
19 #include <isam.h>
20 #include <rsisam.h>
21 #include <rstemp.h>
22
23 #include <proto.h>
24
25 #include "index.h"
26
27 static Dict dict;
28 static ISAM isam;
29
30 static RSET rpn_search_APT (Z_AttributesPlusTerm *zapt)
31 {
32     struct rset_isam_parms parms;
33     const char *info;
34     Z_Term *term = zapt->term;
35
36     if (term->which != Z_Term_general)
37         return NULL; 
38     if (!(info = dict_lookup (dict, term->u.general->buf)))
39         return NULL;
40     assert (*info == sizeof(parms.pos));
41     memcpy (&parms.pos, info+1, sizeof(parms.pos));
42     parms.is = isam;
43     return rset_create (rset_kind_isam, &parms);
44 }
45
46 static RSET rpn_search_and (RSET r_l, RSET r_r)
47 {
48     struct it_key k1, k2;
49     RSET r_dst;
50     int i1, i2;
51     rset_open (r_l, 0);
52     rset_open (r_r, 0);
53     r_dst = rset_create (rset_kind_temp, NULL);
54     rset_open (r_dst, 1);
55     
56     i1 = rset_read (r_l, &k1);
57     i2 = rset_read (r_r, &k2);
58     while (i1 && i2)
59     {
60         if (k1.sysno > k2.sysno)
61             i2 = rset_read (r_r, &k2);
62         else if (k1.sysno < k2.sysno)
63             i1 = rset_read (r_l, &k1);
64         else if (!(i1 = key_compare_x (&k1, &k2)))
65         {
66             rset_write (r_dst, &k1);
67             i1 = rset_read (r_l, &k1);
68             i2 = rset_read (r_r, &k2);
69         }
70         else if (i1 > 0)
71         {
72             rset_write (r_dst, &k2);
73             i2 = rset_read (r_r, &k2);
74         }
75         else
76         {
77             rset_write (r_dst, &k1);
78             i1 = rset_read (r_l, &k1);
79         }
80     } 
81     rset_close (r_dst);
82     return r_dst;
83 }
84
85 static RSET rpn_search_or (RSET r_l, RSET r_r)
86 {
87     return r_l;
88 }
89
90 static RSET rpn_search_not (RSET r_l, RSET r_r)
91 {
92     return r_l;
93 }
94
95 static RSET rpn_search_ref (Z_ResultSetId *resultSetId)
96 {
97     return NULL;
98 }
99
100 static RSET rpn_search_structure (Z_RPNStructure *zs)
101 {
102     RSET r;
103     if (zs->which == Z_RPNStructure_complex)
104     {
105         RSET r_l, r_r;
106
107         r_l = rpn_search_structure (zs->u.complex->s1);
108         r_r = rpn_search_structure (zs->u.complex->s2);
109
110         switch (zs->u.complex->operator->which)
111         {
112         case Z_Operator_and:
113             r = rpn_search_and (r_l, r_r);
114             break;
115         case Z_Operator_or:
116             r = rpn_search_or (r_l, r_r);
117             break;
118         case Z_Operator_and_not:
119             r = rpn_search_not (r_l, r_r);
120             break;
121         default:
122             assert (0);
123         }
124         rset_delete (r_l);
125         rset_delete (r_r);
126     }
127     else if (zs->which == Z_RPNStructure_simple)
128     {
129         if (zs->u.simple->which == Z_Operand_APT)
130             r = rpn_search_APT (zs->u.simple->u.attributesPlusTerm);
131         else if (zs->u.simple->which == Z_Operand_resultSetId)
132             r = rpn_search_ref (zs->u.simple->u.resultSetId);
133         else
134         {
135             assert (0);
136         }
137     }
138     else
139     {
140         assert (0);
141     }
142     return r;
143 }