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