fix quota calculations
[oweals/gnunet.git] / src / datastore / plugin_datastore.h
index b4dc87f9d29c64f709dc1dee4073e029607fcd10..e8f43367179c679b99a020e7f44e0fe87a4236b8 100644 (file)
 #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
@@ -44,7 +54,7 @@ struct GNUNET_DATASTORE_PluginEnvironment
   /**
    * Configuration to use.
    */
-  struct GNUNET_CONFIGURATION_Handle *cfg;
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
 
   /**
    * Scheduler to use.
@@ -54,16 +64,67 @@ struct GNUNET_DATASTORE_PluginEnvironment
 };
 
 
+/**
+ * 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
@@ -73,16 +134,20 @@ typedef unsigned long long (*GNUNET_DATASTORE_GetSize) (void *cls);
  * @param priority priority of the content
  * @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_NO if the content
+ *         was already present (and may have been updated);
+ *         GNUNET_SYSERR on failure
  */
-typedef void
-  (*GNUNET_DATASTORE_Put) (void *cls,
-                           const GNUNET_HashCode * key,
-                           uint32_t size,
-                           const void *data,
-                           unit32_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);
 
 
 /**
@@ -98,16 +163,19 @@ typedef void
  *        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);
 
 
 /**
@@ -121,6 +189,7 @@ typedef void
  * 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
@@ -129,33 +198,41 @@ typedef void
  * @param expire new expiration time should be the
  *     MAX of any existing expiration time and
  *     this value
+ * @param msg set to an error message (on error)
+ * @return GNUNET_OK on success
  */
-typedef void
-  (*GNUNET_DATASTORE_Update) (void *cls,
-                              unsigned long long uid,
-                              int delta, struct GNUNET_TIME_Absolute expire);
+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);
 
 
 
@@ -167,7 +244,8 @@ struct GNUNET_DATASTORE_PluginFunctions
 {
 
   /**
-   * Closure to use for all of the following callbacks.
+   * Closure to use for all of the following callbacks
+   * (except "next_request").
    */
   void *cls;
 
@@ -175,18 +253,26 @@ struct GNUNET_DATASTORE_PluginFunctions
    * Get the current on-disk size of the SQ store.  Estimates are
    * fine, if that's the only thing available.
    */
-  GNUNET_DATASTORE_GetSize 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
@@ -196,30 +282,32 @@ struct GNUNET_DATASTORE_PluginFunctions
    * 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.
+   * Iterate over the items in the datastore in ascending order of
+   * expiration time. 
    */
-  GNUNET_DATSTORE_Selector iter_ascending_expiration;
+  PluginSelector iter_ascending_expiration;
 
   /**
    * Iterate over the items in the datastore in migration
-   * order.
+   * order.  Call the given function on the next item only
+   * (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
@@ -227,13 +315,13 @@ struct GNUNET_DATASTORE_PluginFunctions
    * (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;
 
 };