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