fixes
[oweals/gnunet.git] / src / datastore / plugin_datastore.h
1 /*
2      This file is part of GNUnet
3      (C) 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file datastore/plugin_datastore.h
23  * @brief API for the database backend plugins.
24  * @author Christian Grothoff
25  *
26  * TODO:
27  * - consider defining enumeration or at least typedef
28  *   for the type of "type" (instead of using uint32_t)
29  */
30 #ifndef PLUGIN_DATASTORE_H
31 #define PLUGIN_DATASTORE_H
32
33 #include "gnunet_block_lib.h"
34 #include "gnunet_configuration_lib.h"
35 #include "gnunet_datastore_service.h"
36 #include "gnunet_statistics_service.h"
37 #include "gnunet_scheduler_lib.h"
38
39
40 /**
41  * How many bytes of overhead will we assume per entry
42  * in the SQlite DB?
43  */
44 #define GNUNET_DATASTORE_ENTRY_OVERHEAD 256
45
46
47 /**
48  * The datastore service will pass a pointer to a struct
49  * of this type as the first and only argument to the
50  * entry point of each datastore plugin.
51  */
52 struct GNUNET_DATASTORE_PluginEnvironment
53 {
54   /**
55    * Configuration to use.
56    */
57   const struct GNUNET_CONFIGURATION_Handle *cfg;
58
59   /**
60    * Scheduler to use.
61    */
62   struct GNUNET_SCHEDULER_Handle *sched;
63
64 };
65
66
67 /**
68  * Function invoked on behalf of a "PluginIterator"
69  * asking the database plugin to call the iterator
70  * with the next item.
71  *
72  * @param next_cls whatever argument was given
73  *        to the PluginIterator as "next_cls".
74  * @param end_it set to GNUNET_YES if we
75  *        should terminate the iteration early
76  *        (iterator should be still called once more
77  *         to signal the end of the iteration).
78  */
79 typedef void (*PluginNextRequest)(void *next_cls,
80                                   int end_it);
81
82
83 /**
84  * An iterator over a set of items stored in the datastore.
85  *
86  * @param cls closure
87  * @param next_cls closure to pass to the "next" function.
88  * @param key key for the content
89  * @param size number of bytes in data
90  * @param data content stored
91  * @param type type of the content
92  * @param priority priority of the content
93  * @param anonymity anonymity-level for the content
94  * @param expiration expiration time for the content
95  * @param uid unique identifier for the datum;
96  *        maybe 0 if no unique identifier is available
97  *
98  * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue
99  *         (continue on call to "next", of course),
100  *         GNUNET_NO to delete the item and continue (if supported)
101  */
102 typedef int (*PluginIterator) (void *cls,
103                                void *next_cls,
104                                const GNUNET_HashCode * key,
105                                uint32_t size,
106                                const void *data,
107                                enum GNUNET_BLOCK_Type type,
108                                uint32_t priority,
109                                uint32_t anonymity,
110                                struct GNUNET_TIME_Absolute
111                                expiration, 
112                                uint64_t uid);
113
114 /**
115  * Get an estimate of how much space the database is
116  * currently using.
117  *
118  * @param cls closure
119  * @return number of bytes used on disk
120  */
121 typedef unsigned long long (*PluginGetSize) (void *cls);
122
123
124 /**
125  * Store an item in the datastore.  If the item is already present,
126  * the priorities are summed up and the higher expiration time and
127  * lower anonymity level is used.
128  *
129  * @param cls closure
130  * @param key key for the item
131  * @param size number of bytes in data
132  * @param data content stored
133  * @param type type of the content
134  * @param priority priority of the content
135  * @param anonymity anonymity-level for the content
136  * @param expiration expiration time for the content
137  * @param msg set to an error message (on failure)
138  * @return GNUNET_OK on success, GNUNET_NO if the content
139  *         was already present (and may have been updated);
140  *         GNUNET_SYSERR on failure
141  */
142 typedef int (*PluginPut) (void *cls,
143                           const GNUNET_HashCode * key,
144                           uint32_t size,
145                           const void *data,
146                           enum GNUNET_BLOCK_Type type,
147                           uint32_t priority,
148                           uint32_t anonymity,
149                           struct GNUNET_TIME_Absolute expiration,
150                            char **msg);
151
152
153 /**
154  * Iterate over the results for a particular key
155  * in the datastore.
156  *
157  * @param cls closure
158  * @param key maybe NULL (to match all entries)
159  * @param vhash hash of the value, maybe NULL (to
160  *        match all values that have the right key).
161  *        Note that for DBlocks there is no difference
162  *        betwen key and vhash, but for other blocks
163  *        there may be!
164  * @param type entries of which type are relevant?
165  *     Use 0 for any type.
166  * @param iter function to call on each matching value; however,
167  *        after the first call to "iter", the plugin must wait
168  *        until "NextRequest" was called before giving the iterator
169  *        the next item; finally, the "iter" should be called once
170  *        once with a NULL value at the end ("next_cls" should be NULL
171  *        for that last call)
172  * @param iter_cls closure for iter
173  */
174 typedef void (*PluginGet) (void *cls,
175                            const GNUNET_HashCode * key,
176                            const GNUNET_HashCode * vhash,
177                            enum GNUNET_BLOCK_Type type,
178                            PluginIterator iter, void *iter_cls);
179
180
181 /**
182  * Update the priority for a particular key in the datastore.  If
183  * the expiration time in value is different than the time found in
184  * the datastore, the higher value should be kept.  For the
185  * anonymity level, the lower value is to be used.  The specified
186  * priority should be added to the existing priority, ignoring the
187  * priority in value.
188  *
189  * Note that it is possible for multiple values to match this put.
190  * In that case, all of the respective values are updated.
191  *
192  * @param cls closure
193  * @param uid unique identifier of the datum
194  * @param delta by how much should the priority
195  *     change?  If priority + delta < 0 the
196  *     priority should be set to 0 (never go
197  *     negative).
198  * @param expire new expiration time should be the
199  *     MAX of any existing expiration time and
200  *     this value
201  * @param msg set to an error message (on error)
202  * @return GNUNET_OK on success
203  */
204 typedef int (*PluginUpdate) (void *cls,
205                              uint64_t uid,
206                              int delta, struct GNUNET_TIME_Absolute expire,
207                              char **msg);
208
209
210 /**
211  * Select a subset of the items in the datastore and call
212  * the given iterator for each of them.
213  *
214  * @param cls closure
215  * @param type entries of which type should be considered?
216  *        Use 0 for any type.
217  * @param iter function to call on each matching value; however,
218  *        after the first call to "iter", the plugin must wait
219  *        until "NextRequest" was called before giving the iterator
220  *        the next item; finally, the "iter" should be called once
221  *        once with a NULL value at the end ("next_cls" should be NULL
222  *        for that last call)
223  * @param iter_cls closure for iter
224  */
225 typedef void (*PluginSelector) (void *cls,
226                                 enum GNUNET_BLOCK_Type type,
227                                 PluginIterator iter,
228                                 void *iter_cls);
229
230 /**
231  * Drop database.
232  *
233  * @param cls closure
234  */
235 typedef void (*PluginDrop) (void *cls);
236
237
238
239 /**
240  * Each plugin is required to return a pointer to a struct of this
241  * type as the return value from its entry point.
242  */
243 struct GNUNET_DATASTORE_PluginFunctions
244 {
245
246   /**
247    * Closure to use for all of the following callbacks
248    * (except "next_request").
249    */
250   void *cls;
251
252   /**
253    * Get the current on-disk size of the SQ store.  Estimates are
254    * fine, if that's the only thing available.
255    */
256   PluginGetSize get_size;
257
258   /**
259    * Function to store an item in the datastore.
260    */
261   PluginPut put;
262
263   /**
264    * Function called by iterators whenever they want the next value;
265    * note that unlike all of the other callbacks, this one does get a
266    * the "next_cls" closure which is usually different from the "cls"
267    * member of this struct!
268    */
269   PluginNextRequest next_request;
270
271   /**
272    * Function to iterate over the results for a particular key
273    * in the datastore.
274    */
275   PluginGet get;
276
277   /**
278    * Update the priority for a particular key in the datastore.  If
279    * the expiration time in value is different than the time found in
280    * the datastore, the higher value should be kept.  For the
281    * anonymity level, the lower value is to be used.  The specified
282    * priority should be added to the existing priority, ignoring the
283    * priority in value.
284    */
285   PluginUpdate update;
286
287   /**
288    * Iterate over the items in the datastore in ascending
289    * order of priority.
290    */
291   PluginSelector iter_low_priority;
292
293   /**
294    * Iterate over content with anonymity zero.
295    */
296   PluginSelector iter_zero_anonymity;
297
298   /**
299    * Iterate over the items in the datastore in ascending order of
300    * expiration time. 
301    */
302   PluginSelector iter_ascending_expiration;
303
304   /**
305    * Iterate over the items in the datastore in migration
306    * order.  Call the given function on the next item only
307    * (and then signal 'end' with a second call).  This is
308    * a significant difference from all the other iterators!
309    */
310   PluginSelector iter_migration_order;
311
312   /**
313    * Iterate over all the items in the datastore
314    * as fast as possible in a single transaction
315    * (can lock datastore while this happens, focus
316    * is on doing it fast).
317    */
318   PluginSelector iter_all_now;
319
320   /**
321    * Delete the database.  The next operation is
322    * guaranteed to be unloading of the module.
323    */
324   PluginDrop drop;
325
326 };
327
328
329 #endif