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