Multiple registers (alpha early)
[idzebra-moved-to-github.git] / rset / rsisamc.c
1 /*
2  * Copyright (C) 1994-1999, Index Data
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: rsisamc.c,v $
7  * Revision 1.10  2002-04-04 14:14:13  adam
8  * Multiple registers (alpha early)
9  *
10  * Revision 1.9  2002/03/20 20:24:30  adam
11  * Hits per term. Returned in SearchResult-1
12  *
13  * Revision 1.8  1999/11/30 13:48:04  adam
14  * Improved installation. Updated for inclusion of YAZ header files.
15  *
16  * Revision 1.7  1999/05/26 07:49:14  adam
17  * C++ compilation.
18  *
19  * Revision 1.6  1999/02/02 14:51:35  adam
20  * Updated WIN32 code specific sections. Changed header.
21  *
22  * Revision 1.5  1998/03/05 08:36:28  adam
23  * New result set model.
24  *
25  * Revision 1.4  1997/12/18 10:54:25  adam
26  * New method result set method rs_hits that returns the number of
27  * hits in result-set (if known). The ranked result set returns real
28  * number of hits but only when not combined with other operands.
29  *
30  * Revision 1.3  1997/10/31 12:37:01  adam
31  * Code calls xfree() instead of free().
32  *
33  * Revision 1.2  1996/11/08 11:15:57  adam
34  * Compressed isam fully supported.
35  *
36  * Revision 1.1  1996/10/29 13:41:48  adam
37  * First use of isamc.
38  *
39  */
40
41
42 #include <stdio.h>
43 #include <assert.h>
44 #include <zebrautl.h>
45 #if ZMBOL
46 #include <rsisamc.h>
47
48 static void *r_create(RSET ct, const struct rset_control *sel, void *parms);
49 static RSFD r_open (RSET ct, int flag);
50 static void r_close (RSFD rfd);
51 static void r_delete (RSET ct);
52 static void r_rewind (RSFD rfd);
53 static int r_count (RSET ct);
54 static int r_read (RSFD rfd, void *buf, int *term_index);
55 static int r_write (RSFD rfd, const void *buf);
56
57 static const struct rset_control control = 
58 {
59     "isamc",
60     r_create,
61     r_open,
62     r_close,
63     r_delete,
64     r_rewind,
65     r_count,
66     r_read,
67     r_write,
68 };
69
70 const struct rset_control *rset_kind_isamc = &control;
71
72 struct rset_pp_info {
73     ISAMC_PP pt;
74     struct rset_pp_info *next;
75     struct rset_isamc_info *info;
76     int *countp;
77     void *buf;
78 };
79
80 struct rset_isamc_info {
81     ISAMC   is;
82     ISAMC_P pos;
83     int key_size;
84     int (*cmp)(const void *p1, const void *p2);
85     struct rset_pp_info *ispt_list;
86 };
87
88 static void *r_create(RSET ct, const struct rset_control *sel, void *parms)
89 {
90     rset_isamc_parms *pt = (rset_isamc_parms *) parms;
91     struct rset_isamc_info *info;
92
93     ct->flags |= RSET_FLAG_VOLATILE;
94     info = (struct rset_isamc_info *) xmalloc (sizeof(*info));
95     info->is = pt->is;
96     info->pos = pt->pos;
97     info->key_size = pt->key_size;
98     info->cmp = pt->cmp;
99     info->ispt_list = NULL;
100     ct->no_rset_terms = 1;
101     ct->rset_terms = (RSET_TERM *) xmalloc (sizeof(*ct->rset_terms));
102     ct->rset_terms[0] = pt->rset_term;
103     return info;
104 }
105
106 RSFD r_open (RSET ct, int flag)
107 {
108     struct rset_isamc_info *info = (struct rset_isamc_info *) ct->buf;
109     struct rset_pp_info *ptinfo;
110
111     logf (LOG_DEBUG, "risamc_open");
112     if (flag & RSETF_WRITE)
113     {
114         logf (LOG_FATAL, "ISAMC set type is read-only");
115         return NULL;
116     }
117     ptinfo = (struct rset_pp_info *) xmalloc (sizeof(*ptinfo));
118     ptinfo->next = info->ispt_list;
119     info->ispt_list = ptinfo;
120     ptinfo->pt = isc_pp_open (info->is, info->pos);
121     ptinfo->info = info;
122     if (ct->rset_terms[0]->nn < 0)
123         ct->rset_terms[0]->nn = isc_pp_num (ptinfo->pt);
124     ct->rset_terms[0]->count = 0;
125     ptinfo->countp = &ct->rset_terms[0]->count;
126     ptinfo->buf = xmalloc (info->key_size);
127     return ptinfo;
128 }
129
130 static void r_close (RSFD rfd)
131 {
132     struct rset_isamc_info *info = ((struct rset_pp_info*) rfd)->info;
133     struct rset_pp_info **ptinfop;
134
135     for (ptinfop = &info->ispt_list; *ptinfop; ptinfop = &(*ptinfop)->next)
136         if (*ptinfop == rfd)
137         {
138             xfree ((*ptinfop)->buf);
139             isc_pp_close ((*ptinfop)->pt);
140             *ptinfop = (*ptinfop)->next;
141             xfree (rfd);
142             return;
143         }
144     logf (LOG_FATAL, "r_close but no rfd match!");
145     assert (0);
146 }
147
148 static void r_delete (RSET ct)
149 {
150     struct rset_isamc_info *info = (struct rset_isamc_info *) ct->buf;
151
152     logf (LOG_DEBUG, "rsisamc_delete");
153     assert (info->ispt_list == NULL);
154     rset_term_destroy (ct->rset_terms[0]);
155     xfree (ct->rset_terms);
156     xfree (info);
157 }
158
159 static void r_rewind (RSFD rfd)
160 {   
161     logf (LOG_DEBUG, "rsisamc_rewind");
162     abort ();
163 }
164
165 static int r_count (RSET ct)
166 {
167     return 0;
168 }
169
170 static int r_read (RSFD rfd, void *buf, int *term_index)
171 {
172     struct rset_pp_info *pinfo = (struct rset_pp_info *) rfd;
173     int r;
174     *term_index = 0;
175     r = isc_pp_read(pinfo->pt, buf);
176     if (r > 0)
177     {
178         if (*pinfo->countp == 0 || (*pinfo->info->cmp)(buf, pinfo->buf) > 1)
179         {
180             memcpy (pinfo->buf, buf, pinfo->info->key_size);
181             (*pinfo->countp)++;
182         }
183     }
184     return r;
185 }
186
187 static int r_write (RSFD rfd, const void *buf)
188 {
189     logf (LOG_FATAL, "ISAMC set type is read-only");
190     return -1;
191 }
192 #endif