Updated footer comment
[idzebra-moved-to-github.git] / include / idzebra / isam.h
1 /* This file is part of the Zebra server.
2    Copyright (C) 1994-2009 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20 /**
21 isam.h - a generalized interface to the isam systems
22
23 The isam system consists of a number of isam lists. Physically it is 
24 stored in a file, or a group of related files. It is typically used 
25 for storing all the occurrences of a given word, storing the document 
26 number and position for each occurrence. 
27
28 An isam list is indentified by an isam_position. This is a number (zint).
29 It can be seen as a mapping from an isam_position to an ordered list of isam_
30 entries.
31
32 An isam list consists of one or more isam entries. We do not know the 
33 structure of those entries, but we know the (maximum) size of such, and
34 that they can be memcpy'ed around.
35
36 The entries can be seen to consist of a key and a value, although we 
37 have no idea of their internal structure. We know that we have a compare
38 function that can look at a part (or whole) of the isam entry (the 'key'). 
39 The part not looked at (if any) will count as 'value' or 'payload'. 
40
41 The entries are stored in increasing order (as defined by the compare
42 function), and no duplicates are allowed.
43
44 There is an effective mass-insert routine that takes a stream of values, 
45 each accompanied by an insert/delete flag.
46
47 For reading we have cursors, that can read through an isam list in order. 
48 They have a fast-forward function to skip values we are not interested in.
49  
50 */
51
52
53 #ifndef ISAM_H
54 #define ISAM_H
55
56 #include <idzebra/bfile.h>
57
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61
62
63 /**
64  * key_control contains all there is to know about the keys (entries) stored
65  * in an isam, (and therefore operated by the rsets). Other than this info,
66  * all we assume is that all keys are the same size, and they can be
67  * memcpy'd around. 
68  */
69 struct key_control {
70     /** (max) size of a key */
71     int key_size;
72
73     /** Default for what level we operate on (book/chapter/verse). 
74      * for typical zebra, this is always 2 (sysno/seqno). Not used in 
75      * isam context, but the rsets make use of this. */
76     int scope; 
77
78     /** Compare function, returning -1,0,1, if p1 is less/equal/greater 
79      * than p2 */
80     int (*cmp) (const void *p1, const void *p2);
81
82     /** Debug function to write a key in the log, with a message */
83     void (*key_logdump_txt) (int logmask, const void *p, const char *txt);
84
85     /** Return the sequence number of a key, to see if we are on the same 
86      * record. FIXME - this makes less sense with higher-scope keys. */
87     zint (*getseq)(const void *p);
88
89     /** Codec to pack key values into a disk page (delta-compression etc) */
90     ISAM_CODEC *codec;
91 };
92
93 typedef struct key_control KEY_CONTROL;
94
95 const KEY_CONTROL *default_key_control();
96   /* FIXME - in zrpn.c, time being. Needs to be moved out */
97
98
99 /** isam_data_stream is a callback function for the mass-insert (merge) 
100  * it provides another item to insert/delete, in proper order */
101 struct isam_data_stream {
102     int (*read_item)(void *clientData, char **dst, int *insertMode);
103     void *clientData;
104 };
105
106 typedef struct isam_data_stram ISAM_DATA_STREAM;
107
108
109 /** ISAM_POS is a number the ISAM translates from */
110 typedef zint ISAM_POS;
111
112 /** ISAM is a translation from POS to a set of values */
113 typedef struct ISAM_s *ISAM;
114
115 /** ISAM_CUR is a pointer into an ISAM */
116 typedef struct ISAM_CUR_s *ISAM_CUR;
117
118 /** isam_control is the interface to the operations an ISAM supports */
119 struct isam_conrol {
120     /** text description of the type, for debugging */
121     char *desc;
122     /** default filename, if none given to isam_open */
123     const char *def_filename; 
124
125     /* there is an isam_open function, but it is not part of this */
126     /* dynamic table, as it is what provides this table */
127
128     /** close the isam system */
129     void (*f_close)(ISAM i);
130
131     /** Insert an entry into the isam identified by pos. If pos==0, 
132      * create a new isam list */
133     ISAM_POS (*f_put)(ISAM is, ISAM_POS pos, const void *buf);
134
135     /** Locate and delete an entry from an isam list. If not there
136      * do nothing, and return 0*/
137     int (*f_del)(ISAM is, ISAM_POS pos, const void *buf);
138
139     /** Find an entry in the isam list. return 0 if not found. buf must 
140      * contain enough to identify the item, and will be overwritten by it */
141     int (*f_get)(ISAM is, ISAM_POS pos, void *buf );
142
143     /** Mass-insert data from incoming stream into the isam */
144     ISAM_POS (*f_merge)(ISAM is, ISAM_POS pos, ISAM_DATA_STREAM *data); 
145
146     /** Open a cursor to the isam list identified by pos */
147     ISAM_CUR (*f_cur_open)(ISAM is, ISAM_POS pos); 
148
149     /** Read an item at the cursor (and forward to next). return 0 at eof */
150     int (*f_read)(ISAM_CUR cur, void *buf);
151
152     /** Forward until item >= untilbuf, and read that item. Skips effectively*/
153     int (*f_forward)(ISAM_CUR cur, void *buf, const void *untilbuf);
154
155     /** Get (an estimate of) the current position and total size of the entry*/
156     void (*f_pos)(ISAM_CUR cur, double *current, double *total);
157
158     /** Close a cursor */
159     void (*f_cur_close)(ISAM_CUR cur);
160
161     /** Delete the isam list from the isam system.*/
162     int (*f_unlink)(ISAM is, ISAM_POS pos);
163     
164 };
165
166 /** ISAM_s is the generic isam structure */
167 struct ISAM_s {
168     const struct isam_control *ictrl;  /* the functions */
169     const KEY_CONTROL *kctrl; /* all about the keys stored in the isam */
170     BFiles bfs;  /* The underlying block file system */
171     void *priv; /* various types of ISAMs hand their private parts here */
172 };
173
174 /** ISAM_CUR is a cursor to an ISAM, used for reading the next value, etc. */
175 struct ISAM_CUR {
176     ISAM is;
177     void *priv;
178 };
179
180
181
182 /** Open the isam system */
183 ISAM isam_open (BFiles bfs, 
184                 const char *isamtype, /* usually "b" */
185                 const char *filename,  /* optional, use default from control ?? */
186                 int flags, /* FIXME - define read/write, and some special ones */
187                 const KEY_CONTROL *key_control);
188
189
190 /** Shortcut defines to access the functions through the key_control block */
191
192 #define isam_close(is) (*(is)->ictrl->f_close)(is)
193
194 #define isam_puf(is,pos,buf) (*(is)->ictrl->f_put)((is),(pos)(buf))
195
196 #define isam_del(is,pos,buf) (*(is)->ictrl->f_del)((is),(pos)(buf))
197
198 #define isam_get(is,pos,buf) (*(is)->ictrl->f_get)((is),(pos)(buf))
199
200 #define isam_merge(is,pos,data) (*(is)->ictrl->f_merge)((is),(pos)(data))
201
202 #define isam_cur_open(is,pos) (*(is)->ictrl->f_cur_open)((is),(pos))
203
204 #define isam_read(cur,buf) (*(is)->ictrl->f_read)((cur),(buf))
205
206 #define isam_forward(cur,buf,untilbuf) (*(is)->ictrl->f_forward)((cur),(buf)(untilbuf))
207
208 #define isam_pos(cur,current,total) (*(is)->ictrl->f_pos)((cur),(current),(total))
209
210 #define isam_cur_close(cur) (*(is)->ictrl->f_cur_close)(cur)
211
212 #define isam_unlink(is,pos) (*(is)->ictrl->f_unlink)((is),(pos))
213
214
215 #ifdef __cplusplus
216 }
217 #endif
218
219 #endif  /* ISAM_H */
220 /*
221  * Local variables:
222  * c-basic-offset: 4
223  * c-file-style: "Stroustrup"
224  * indent-tabs-mode: nil
225  * End:
226  * vim: shiftwidth=4 tabstop=8 expandtab
227  */
228