#ifndef PLUGIN_DATASTORE_H
#define PLUGIN_DATASTORE_H
+#include "gnunet_block_lib.h"
#include "gnunet_configuration_lib.h"
-#include "gnunet_scheduler_lib.h"
#include "gnunet_datastore_service.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_scheduler_lib.h"
+
+
+/**
+ * How many bytes of overhead will we assume per entry
+ * in the SQlite DB?
+ */
+#define GNUNET_DATASTORE_ENTRY_OVERHEAD 256
+
/**
* The datastore service will pass a pointer to a struct
/**
* Configuration to use.
*/
- struct GNUNET_CONFIGURATION_Handle *cfg;
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
* Scheduler to use.
};
+/**
+ * Function invoked on behalf of a "PluginIterator"
+ * asking the database plugin to call the iterator
+ * with the next item.
+ *
+ * @param next_cls whatever argument was given
+ * to the PluginIterator as "next_cls".
+ * @param end_it set to GNUNET_YES if we
+ * should terminate the iteration early
+ * (iterator should be still called once more
+ * to signal the end of the iteration).
+ */
+typedef void (*PluginNextRequest)(void *next_cls,
+ int end_it);
+
+
+/**
+ * An iterator over a set of items stored in the datastore.
+ *
+ * @param cls closure
+ * @param next_cls closure to pass to the "next" function.
+ * @param key key for the content
+ * @param size number of bytes in data
+ * @param data content stored
+ * @param type type of the content
+ * @param priority priority of the content
+ * @param anonymity anonymity-level for the content
+ * @param expiration expiration time for the content
+ * @param uid unique identifier for the datum;
+ * maybe 0 if no unique identifier is available
+ *
+ * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue
+ * (continue on call to "next", of course),
+ * GNUNET_NO to delete the item and continue (if supported)
+ */
+typedef int (*PluginIterator) (void *cls,
+ void *next_cls,
+ const GNUNET_HashCode * key,
+ uint32_t size,
+ const void *data,
+ enum GNUNET_BLOCK_Type type,
+ uint32_t priority,
+ uint32_t anonymity,
+ struct GNUNET_TIME_Absolute
+ expiration,
+ uint64_t uid);
+
/**
* Get an estimate of how much space the database is
* currently using.
+ *
+ * @param cls closure
* @return number of bytes used on disk
*/
-typedef unsigned long long (*GNUNET_DATASTORE_GetSize) (void *cls);
+typedef unsigned long long (*PluginGetSize) (void *cls);
/**
- * Store an item in the datastore.
+ * Store an item in the datastore. If the item is already present,
+ * the priorities are summed up and the higher expiration time and
+ * lower anonymity level is used.
*
* @param cls closure
* @param key key for the item
* @param anonymity anonymity-level for the content
* @param expiration expiration time for the content
* @param msg set to an error message (on failure)
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ * @return GNUNET_OK on success, GNUNET_NO if the content
+ * was already present (and may have been updated);
+ * GNUNET_SYSERR on failure
*/
-typedef int
- (*GNUNET_DATASTORE_Put) (void *cls,
- const GNUNET_HashCode * key,
- uint32_t size,
- const void *data,
- uint32_t type,
- uint32_t priority,
- uint32_t anonymity,
- struct GNUNET_TIME_Absolute expiration,
+typedef int (*PluginPut) (void *cls,
+ const GNUNET_HashCode * key,
+ uint32_t size,
+ const void *data,
+ enum GNUNET_BLOCK_Type type,
+ uint32_t priority,
+ uint32_t anonymity,
+ struct GNUNET_TIME_Absolute expiration,
char **msg);
* there may be!
* @param type entries of which type are relevant?
* Use 0 for any type.
- * @param iter function to call on each matching value;
- * will be called once with a NULL value at the end
+ * @param iter function to call on each matching value; however,
+ * after the first call to "iter", the plugin must wait
+ * until "NextRequest" was called before giving the iterator
+ * the next item; finally, the "iter" should be called once
+ * once with a NULL value at the end ("next_cls" should be NULL
+ * for that last call)
* @param iter_cls closure for iter
*/
-typedef void
- (*GNUNET_DATASTORE_Get) (void *cls,
- const GNUNET_HashCode * key,
- const GNUNET_HashCode * vhash,
- uint32_t type,
- GNUNET_DATASTORE_Iterator iter, void *iter_cls);
+typedef void (*PluginGet) (void *cls,
+ const GNUNET_HashCode * key,
+ const GNUNET_HashCode * vhash,
+ enum GNUNET_BLOCK_Type type,
+ PluginIterator iter, void *iter_cls);
/**
* Note that it is possible for multiple values to match this put.
* In that case, all of the respective values are updated.
*
+ * @param cls closure
* @param uid unique identifier of the datum
* @param delta by how much should the priority
* change? If priority + delta < 0 the
* @param msg set to an error message (on error)
* @return GNUNET_OK on success
*/
-typedef int
- (*GNUNET_DATASTORE_Update) (void *cls,
- unsigned long long uid,
- int delta, struct GNUNET_TIME_Absolute expire,
- char **msg);
+typedef int (*PluginUpdate) (void *cls,
+ uint64_t uid,
+ int delta, struct GNUNET_TIME_Absolute expire,
+ char **msg);
/**
* Select a subset of the items in the datastore and call
* the given iterator for each of them.
*
+ * @param cls closure
* @param type entries of which type should be considered?
* Use 0 for any type.
- * @param iter function to call on each matching value;
- * will be called once with a NULL value at the end
+ * @param iter function to call on each matching value; however,
+ * after the first call to "iter", the plugin must wait
+ * until "NextRequest" was called before giving the iterator
+ * the next item; finally, the "iter" should be called once
+ * once with a NULL value at the end ("next_cls" should be NULL
+ * for that last call)
* @param iter_cls closure for iter
*/
-typedef void
- (*GNUNET_DATASTORE_Selector) (void *cls,
- uint32_t type,
- GNUNET_DATASTORE_Iterator iter,
+typedef void (*PluginSelector) (void *cls,
+ enum GNUNET_BLOCK_Type type,
+ PluginIterator iter,
void *iter_cls);
/**
* Drop database.
+ *
+ * @param cls closure
*/
-typedef void (*GNUNET_DATASTORE_Drop) (void *cls);
+typedef void (*PluginDrop) (void *cls);
{
/**
- * Closure to use for all of the following callbacks.
+ * Closure to use for all of the following callbacks
+ * (except "next_request").
*/
void *cls;
* Get the current on-disk size of the SQ store. Estimates are
* fine, if that's the only thing available.
*/
- GNUNET_DATASTORE_GetSize get_size;
+ PluginGetSize get_size;
/**
* Function to store an item in the datastore.
*/
- GNUNET_DATASTORE_Put put;
+ PluginPut put;
+
+ /**
+ * Function called by iterators whenever they want the next value;
+ * note that unlike all of the other callbacks, this one does get a
+ * the "next_cls" closure which is usually different from the "cls"
+ * member of this struct!
+ */
+ PluginNextRequest next_request;
/**
* Function to iterate over the results for a particular key
* in the datastore.
*/
- GNUNET_DATASTORE_Get get;
+ PluginGet get;
/**
* Update the priority for a particular key in the datastore. If
* priority should be added to the existing priority, ignoring the
* priority in value.
*/
- GNUNET_DATASTORE_Update update;
+ PluginUpdate update;
/**
* Iterate over the items in the datastore in ascending
* order of priority.
*/
- GNUNET_DATASTORE_Selector iter_low_priority;
+ PluginSelector iter_low_priority;
/**
* Iterate over content with anonymity zero.
*/
- GNUNET_DATASTORE_Selector iter_zero_anonymity;
+ PluginSelector iter_zero_anonymity;
/**
* Iterate over the items in the datastore in ascending order of
* expiration time.
*/
- GNUNET_DATASTORE_Selector iter_ascending_expiration;
+ PluginSelector iter_ascending_expiration;
/**
* Iterate over the items in the datastore in migration
* (and then signal 'end' with a second call). This is
* a significant difference from all the other iterators!
*/
- GNUNET_DATASTORE_Selector iter_migration_order;
+ PluginSelector iter_migration_order;
/**
* Iterate over all the items in the datastore
* (can lock datastore while this happens, focus
* is on doing it fast).
*/
- GNUNET_DATASTORE_Selector iter_all_now;
+ PluginSelector iter_all_now;
/**
* Delete the database. The next operation is
* guaranteed to be unloading of the module.
*/
- GNUNET_DATASTORE_Drop drop;
+ PluginDrop drop;
};