Work on relevance feedback.
[idzebra-moved-to-github.git] / rset / rsrel.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: rsrel.c,v $
7  * Revision 1.1  1995-09-08 14:52:42  adam
8  * Work on relevance feedback.
9  *
10  */
11
12 #include <stdio.h>
13 #include <assert.h>
14
15 #include <isam.h>
16 #include <rsrel.h>
17 #include <alexutil.h>
18
19 static rset_control *r_create(const struct rset_control *sel, void *parms);
20 static RSFD r_open (rset_control *ct, int wflag);
21 static void r_close (RSFD rfd);
22 static void r_delete (rset_control *ct);
23 static void r_rewind (RSFD rfd);
24 static int r_count (rset_control *ct);
25 static int r_read (RSFD rfd, void *buf);
26 static int r_write (RSFD rfd, const void *buf);
27
28 static const rset_control control = 
29 {
30     "relevance set type",
31     0,
32     r_create,
33     r_open,
34     r_close,
35     r_delete,
36     r_rewind,
37     r_count,
38     r_read,
39     r_write
40 };
41
42 const rset_control *rset_kind_relevance = &control;
43
44 struct rset_rel_info {
45     int     key_size;
46     int     max_rec;
47     int     no_rec;
48     int     (*cmp)(const void *p1, const void *p2);
49     void    *key_buf;
50     int     *score_buf;
51
52     struct rset_rel_rfd *rfd_list;
53 };
54
55 struct rset_rel_rfd {
56     int     position;
57     struct rset_rel_rfd *next;
58     struct rset_rel_info *info;
59 };
60
61 static void relevance (struct rset_rel_info *info, rset_relevance_parms *parms)
62 {
63     char *isam_buf;
64     int  *isam_r;
65     ISPT *isam_pt;
66     int i;
67
68     isam_buf = xmalloc (info->key_size * parms->no_isam_positions);
69     isam_r = xmalloc (sizeof (*isam_r) * parms->no_isam_positions);
70     isam_pt = xmalloc (sizeof (*isam_pt) * parms->no_isam_positions);
71
72     for (i = 0; i<parms->no_isam_positions; i++)
73     {
74         isam_pt[i] = is_position (parms->is, parms->isam_positions[i]);
75         isam_r[i] = is_readkey (isam_pt[i], isam_buf + i*info->key_size);
76     }
77
78     for (i = 0; i<parms->no_isam_positions; i++)
79         is_pt_free (isam_pt[i]);
80     xfree (isam_buf);
81     xfree (isam_r);
82     xfree (isam_pt);
83 }
84
85 static rset_control *r_create (const struct rset_control *sel, void *parms)
86 {
87     rset_control *newct;
88     rset_relevance_parms *r_parms = parms;
89     struct rset_rel_info *info;
90
91     newct = xmalloc(sizeof(*newct));
92     memcpy(newct, sel, sizeof(*sel));
93     newct->buf = xmalloc (sizeof(struct rset_rel_info));
94
95     info = newct->buf;
96     info->key_size = r_parms->key_size;
97     assert (info->key_size > 1);
98     info->max_rec = r_parms->max_rec;
99     assert (info->max_rec > 1);
100     info->cmp = r_parms->cmp;
101
102     info->key_buf = xmalloc (info->key_size * info->max_rec);
103     info->score_buf = xmalloc (sizeof(*info->score_buf) * info->max_rec);
104     info->no_rec = 0;
105     info->rfd_list = NULL;
106
107     relevance (info, r_parms);
108     return newct;
109 }
110
111 static RSFD r_open (rset_control *ct, int wflag)
112 {
113     struct rset_rel_rfd *rfd;
114     struct rset_rel_info *info = ct->buf;
115
116     if (wflag)
117     {
118         logf (LOG_FATAL, "relevance set type is read-only");
119         return NULL;
120     }
121     rfd = xmalloc (sizeof(*rfd));
122     rfd->next = info->rfd_list;
123     info->rfd_list = rfd;
124     rfd->position = 0;
125     rfd->info = info;
126     return rfd;
127 }
128
129 static void r_close (RSFD rfd)
130 {
131     struct rset_rel_info *info = ((struct rset_rel_rfd*)rfd)->info;
132     struct rset_rel_rfd **rfdp;
133     
134     for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
135         if (*rfdp == rfd)
136         {
137             *rfdp = (*rfdp)->next;
138             free (rfd);
139             return;
140         }
141     logf (LOG_FATAL, "r_close but no rfd match!");
142     assert (0);
143 }
144
145 static void r_delete (rset_control *ct)
146 {
147     struct rset_rel_info *info = ct->buf;
148
149     assert (info->rfd_list == NULL);
150     xfree (info->key_buf);
151     xfree (info->score_buf);
152     xfree (info);
153     xfree (ct);
154 }
155
156 static void r_rewind (RSFD rfd)
157 {
158     ((struct rset_rel_rfd*) rfd)->position = 0;
159 }
160
161 static int r_count (rset_control *ct)
162 {
163     struct rset_rel_info *info = ct->buf;
164
165     return info->no_rec;
166 }
167
168 static int r_read (RSFD rfd, void *buf)
169 {
170     struct rset_rel_rfd *p = rfd;
171     struct rset_rel_info *info = p->info;
172
173     if (p->position >= info->max_rec)
174         return 0;
175     memcpy ((char*) buf + sizeof(*info->score_buf),
176             (char*) info->key_buf + info->key_size * p->position,
177             info->key_size);
178     memcpy ((char*) buf,
179             info->score_buf + p->position, sizeof(*info->score_buf));
180     ++(p->position);
181     return 1;
182 }
183
184 static int r_write (RSFD rfd, const void *buf)
185 {
186     logf (LOG_FATAL, "relevance set type is read-only");
187     return -1;
188 }