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