Zebra with full functionality
[idzebra-moved-to-github.git] / rset / rsisamc.c
1 /*
2  * Copyright (C) 1994-2002, Index Data
3  * All rights reserved.
4  *
5  * $Id: rsisamc.c,v 1.11 2002-04-05 08:46:26 adam Exp $
6  */
7
8
9 #include <stdio.h>
10 #include <assert.h>
11 #include <zebrautl.h>
12 #include <rsisamc.h>
13
14 static void *r_create(RSET ct, const struct rset_control *sel, void *parms);
15 static RSFD r_open (RSET ct, int flag);
16 static void r_close (RSFD rfd);
17 static void r_delete (RSET ct);
18 static void r_rewind (RSFD rfd);
19 static int r_count (RSET ct);
20 static int r_read (RSFD rfd, void *buf, int *term_index);
21 static int r_write (RSFD rfd, const void *buf);
22
23 static const struct rset_control control = 
24 {
25     "isamc",
26     r_create,
27     r_open,
28     r_close,
29     r_delete,
30     r_rewind,
31     r_count,
32     r_read,
33     r_write,
34 };
35
36 const struct rset_control *rset_kind_isamc = &control;
37
38 struct rset_pp_info {
39     ISAMC_PP pt;
40     struct rset_pp_info *next;
41     struct rset_isamc_info *info;
42     int *countp;
43     void *buf;
44 };
45
46 struct rset_isamc_info {
47     ISAMC   is;
48     ISAMC_P pos;
49     int key_size;
50     int (*cmp)(const void *p1, const void *p2);
51     struct rset_pp_info *ispt_list;
52 };
53
54 static void *r_create(RSET ct, const struct rset_control *sel, void *parms)
55 {
56     rset_isamc_parms *pt = (rset_isamc_parms *) parms;
57     struct rset_isamc_info *info;
58
59     ct->flags |= RSET_FLAG_VOLATILE;
60     info = (struct rset_isamc_info *) xmalloc (sizeof(*info));
61     info->is = pt->is;
62     info->pos = pt->pos;
63     info->key_size = pt->key_size;
64     info->cmp = pt->cmp;
65     info->ispt_list = NULL;
66     ct->no_rset_terms = 1;
67     ct->rset_terms = (RSET_TERM *) xmalloc (sizeof(*ct->rset_terms));
68     ct->rset_terms[0] = pt->rset_term;
69     return info;
70 }
71
72 RSFD r_open (RSET ct, int flag)
73 {
74     struct rset_isamc_info *info = (struct rset_isamc_info *) ct->buf;
75     struct rset_pp_info *ptinfo;
76
77     logf (LOG_DEBUG, "risamc_open");
78     if (flag & RSETF_WRITE)
79     {
80         logf (LOG_FATAL, "ISAMC set type is read-only");
81         return NULL;
82     }
83     ptinfo = (struct rset_pp_info *) xmalloc (sizeof(*ptinfo));
84     ptinfo->next = info->ispt_list;
85     info->ispt_list = ptinfo;
86     ptinfo->pt = isc_pp_open (info->is, info->pos);
87     ptinfo->info = info;
88     if (ct->rset_terms[0]->nn < 0)
89         ct->rset_terms[0]->nn = isc_pp_num (ptinfo->pt);
90     ct->rset_terms[0]->count = 0;
91     ptinfo->countp = &ct->rset_terms[0]->count;
92     ptinfo->buf = xmalloc (info->key_size);
93     return ptinfo;
94 }
95
96 static void r_close (RSFD rfd)
97 {
98     struct rset_isamc_info *info = ((struct rset_pp_info*) rfd)->info;
99     struct rset_pp_info **ptinfop;
100
101     for (ptinfop = &info->ispt_list; *ptinfop; ptinfop = &(*ptinfop)->next)
102         if (*ptinfop == rfd)
103         {
104             xfree ((*ptinfop)->buf);
105             isc_pp_close ((*ptinfop)->pt);
106             *ptinfop = (*ptinfop)->next;
107             xfree (rfd);
108             return;
109         }
110     logf (LOG_FATAL, "r_close but no rfd match!");
111     assert (0);
112 }
113
114 static void r_delete (RSET ct)
115 {
116     struct rset_isamc_info *info = (struct rset_isamc_info *) ct->buf;
117
118     logf (LOG_DEBUG, "rsisamc_delete");
119     assert (info->ispt_list == NULL);
120     rset_term_destroy (ct->rset_terms[0]);
121     xfree (ct->rset_terms);
122     xfree (info);
123 }
124
125 static void r_rewind (RSFD rfd)
126 {   
127     logf (LOG_DEBUG, "rsisamc_rewind");
128     abort ();
129 }
130
131 static int r_count (RSET ct)
132 {
133     return 0;
134 }
135
136 static int r_read (RSFD rfd, void *buf, int *term_index)
137 {
138     struct rset_pp_info *pinfo = (struct rset_pp_info *) rfd;
139     int r;
140     *term_index = 0;
141     r = isc_pp_read(pinfo->pt, buf);
142     if (r > 0)
143     {
144         if (*pinfo->countp == 0 || (*pinfo->info->cmp)(buf, pinfo->buf) > 1)
145         {
146             memcpy (pinfo->buf, buf, pinfo->info->key_size);
147             (*pinfo->countp)++;
148         }
149     }
150     return r;
151 }
152
153 static int r_write (RSFD rfd, const void *buf)
154 {
155     logf (LOG_FATAL, "ISAMC set type is read-only");
156     return -1;
157 }