travelhacking
[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  * @return number of bytes used on disk
116  */
117 typedef unsigned long long (*PluginGetSize) (void *cls);
118
119
120 /**
121  * Store an item in the datastore.  If the item is already present,
122  * the priorities are summed up and the higher expiration time and
123  * lower anonymity level is used.
124  *
125  * @param cls closure
126  * @param key key for the item
127  * @param size number of bytes in data
128  * @param data content stored
129  * @param type type of the content
130  * @param priority priority of the content
131  * @param anonymity anonymity-level for the content
132  * @param expiration expiration time for the content
133  * @param msg set to an error message (on failure)
134  * @return GNUNET_OK on success, GNUNET_NO if the content
135  *         was already present (and may have been updated);
136  *         GNUNET_SYSERR on failure
137  */
138 typedef int (*PluginPut) (void *cls,
139                           const GNUNET_HashCode * key,
140                           uint32_t size,
141                           const void *data,
142                           uint32_t type,
143                           uint32_t priority,
144                           uint32_t anonymity,
145                           struct GNUNET_TIME_Absolute expiration,
146                            char **msg);
147
148
149 /**
150  * Iterate over the results for a particular key
151  * in the datastore.
152  *
153  * @param cls closure
154  * @param key maybe NULL (to match all entries)
155  * @param vhash hash of the value, maybe NULL (to
156  *        match all values that have the right key).
157  *        Note that for DBlocks there is no difference
158  *        betwen key and vhash, but for other blocks
159  *        there may be!
160  * @param type entries of which type are relevant?
161  *     Use 0 for any type.
162  * @param iter function to call on each matching value; however,
163  *        after the first call to "iter", the plugin must wait
164  *        until "NextRequest" was called before giving the iterator
165  *        the next item; finally, the "iter" should be called once
166  *        once with a NULL value at the end ("next_cls" should be NULL
167  *        for that last call)
168  * @param iter_cls closure for iter
169  */
170 typedef void (*PluginGet) (void *cls,
171                            const GNUNET_HashCode * key,
172                            const GNUNET_HashCode * vhash,
173                            uint32_t type,
174                            PluginIterator iter, void *iter_cls);
175
176
177 /**
178  * Update the priority for a particular key in the datastore.  If
179  * the expiration time in value is different than the time found in
180  * the datastore, the higher value should be kept.  For the
181  * anonymity level, the lower value is to be used.  The specified
182  * priority should be added to the existing priority, ignoring the
183  * priority in value.
184  *
185  * Note that it is possible for multiple values to match this put.
186  * In that case, all of the respective values are updated.
187  *
188  * @param uid unique identifier of the datum
189  * @param delta by how much should the priority
190  *     change?  If priority + delta < 0 the
191  *     priority should be set to 0 (never go
192  *     negative).
193  * @param expire new expiration time should be the
194  *     MAX of any existing expiration time and
195  *     this value
196  * @param msg set to an error message (on error)
197  * @return GNUNET_OK on success
198  */
199 typedef int (*PluginUpdate) (void *cls,
200                              uint64_t uid,
201                              int delta, struct GNUNET_TIME_Absolute expire,
202                              char **msg);
203
204
205 /**
206  * Select a subset of the items in the datastore and call
207  * the given iterator for each of them.
208  *
209  * @param type entries of which type should be considered?
210  *        Use 0 for any type.
211  * @param iter function to call on each matching value; however,
212  *        after the first call to "iter", the plugin must wait
213  *        until "NextRequest" was called before giving the iterator
214  *        the next item; finally, the "iter" should be called once
215  *        once with a NULL value at the end ("next_cls" should be NULL
216  *        for that last call)
217  * @param iter_cls closure for iter
218  */
219 typedef void (*PluginSelector) (void *cls,
220                                 uint32_t type,
221                                 PluginIterator iter,
222                                 void *iter_cls);
223
224 /**
225  * Drop database.
226  */
227 typedef void (*PluginDrop) (void *cls);
228
229
230
231 /**
232  * Each plugin is required to return a pointer to a struct of this
233  * type as the return value from its entry point.
234  */
235 struct GNUNET_DATASTORE_PluginFunctions
236 {
237
238   /**
239    * Closure to use for all of the following callbacks
240    * (except "next_request").
241    */
242   void *cls;
243
244   /**
245    * Get the current on-disk size of the SQ store.  Estimates are
246    * fine, if that's the only thing available.
247    */
248   PluginGetSize get_size;
249
250   /**
251    * Function to store an item in the datastore.
252    */
253   PluginPut put;
254
255   /**
256    * Function called by iterators whenever they want the next value;
257    * note that unlike all of the other callbacks, this one does get a
258    * the "next_cls" closure which is usually different from the "cls"
259    * member of this struct!
260    */
261   PluginNextRequest next_request;
262
263   /**
264    * Function to iterate over the results for a particular key
265    * in the datastore.
266    */
267   PluginGet get;
268
269   /**
270    * Update the priority for a particular key in the datastore.  If
271    * the expiration time in value is different than the time found in
272    * the datastore, the higher value should be kept.  For the
273    * anonymity level, the lower value is to be used.  The specified
274    * priority should be added to the existing priority, ignoring the
275    * priority in value.
276    */
277   PluginUpdate update;
278
279   /**
280    * Iterate over the items in the datastore in ascending
281    * order of priority.
282    */
283   PluginSelector iter_low_priority;
284
285   /**
286    * Iterate over content with anonymity zero.
287    */
288   PluginSelector iter_zero_anonymity;
289
290   /**
291    * Iterate over the items in the datastore in ascending order of
292    * expiration time. 
293    */
294   PluginSelector iter_ascending_expiration;
295
296   /**
297    * Iterate over the items in the datastore in migration
298    * order.  Call the given function on the next item only
299    * (and then signal 'end' with a second call).  This is
300    * a significant difference from all the other iterators!
301    */
302   PluginSelector iter_migration_order;
303
304   /**
305    * Iterate over all the items in the datastore
306    * as fast as possible in a single transaction
307    * (can lock datastore while this happens, focus
308    * is on doing it fast).
309    */
310   PluginSelector iter_all_now;
311
312   /**
313    * Delete the database.  The next operation is
314    * guaranteed to be unloading of the module.
315    */
316   PluginDrop drop;
317
318 };
319
320
321 #endif