-do warn
[oweals/gnunet.git] / src / datastore / gnunet-service-datastore.c
index 5474bc101d1eba6461a4a5344fdd3d7f9b1714d7..1d7e8cd2beb68e185c8820c0d929f8df4fe54f72 100644 (file)
@@ -198,6 +198,13 @@ static GNUNET_SCHEDULER_TaskIdentifier expired_kill_task;
  */
 const struct GNUNET_CONFIGURATION_Handle *cfg;
 
+/**
+ * Minimum time that content should have to not be discarded instantly
+ * (time stamp of any content that we've been discarding recently to
+ * stay below the quota).  FOREVER if we had to expire content with
+ * non-zero priority.
+ */
+static struct GNUNET_TIME_Absolute min_expiration;
 
 /**
  * Handle for reporting statistics.
@@ -319,7 +326,9 @@ expired_processor (void *cls, const GNUNET_HashCode * key, uint32_t size,
   if (key == NULL)
   {
     expired_kill_task =
-        GNUNET_SCHEDULER_add_delayed (MAX_EXPIRE_DELAY, &delete_expired, NULL);
+        GNUNET_SCHEDULER_add_delayed_with_priority (MAX_EXPIRE_DELAY,
+                                                   GNUNET_SCHEDULER_PRIORITY_IDLE,
+                                                   &delete_expired, NULL);
     return GNUNET_SYSERR;
   }
   now = GNUNET_TIME_absolute_get ();
@@ -327,7 +336,9 @@ expired_processor (void *cls, const GNUNET_HashCode * key, uint32_t size,
   {
     /* finished processing */
     expired_kill_task =
-        GNUNET_SCHEDULER_add_delayed (MAX_EXPIRE_DELAY, &delete_expired, NULL);
+        GNUNET_SCHEDULER_add_delayed_with_priority (MAX_EXPIRE_DELAY,
+                                                   GNUNET_SCHEDULER_PRIORITY_IDLE,
+                                                   &delete_expired, NULL);
     return GNUNET_SYSERR;
   }
 #if DEBUG_DATASTORE
@@ -336,11 +347,14 @@ expired_processor (void *cls, const GNUNET_HashCode * key, uint32_t size,
               GNUNET_h2s (key), type,
               (unsigned long long) (now.abs_value - expiration.abs_value));
 #endif
+  min_expiration = now;
   GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes expired"), size,
                             GNUNET_YES);
   GNUNET_CONTAINER_bloomfilter_remove (filter, key);
   expired_kill_task =
-      GNUNET_SCHEDULER_add_delayed (MIN_EXPIRE_DELAY, &delete_expired, NULL);
+      GNUNET_SCHEDULER_add_delayed_with_priority (MIN_EXPIRE_DELAY,
+                                                 GNUNET_SCHEDULER_PRIORITY_IDLE,
+                                                 &delete_expired, NULL);
   return GNUNET_NO;
 }
 
@@ -393,14 +407,21 @@ quota_processor (void *cls, const GNUNET_HashCode * key, uint32_t size,
     return GNUNET_SYSERR;
 #if DEBUG_DATASTORE
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Deleting %llu bytes of low-priority content `%s' of type %u (still trying to free another %llu bytes)\n",
+              "Deleting %llu bytes of low-priority (%u) content `%s' of type %u at %llu ms prior to expiration (still trying to free another %llu bytes)\n",
               (unsigned long long) (size + GNUNET_DATASTORE_ENTRY_OVERHEAD),
-              GNUNET_h2s (key), type, *need);
+             (unsigned int) priority,
+              GNUNET_h2s (key), type, 
+             (unsigned long long) GNUNET_TIME_absolute_get_remaining (expiration).rel_value,
+             *need);
 #endif
   if (size + GNUNET_DATASTORE_ENTRY_OVERHEAD > *need)
     *need = 0;
   else
     *need -= size + GNUNET_DATASTORE_ENTRY_OVERHEAD;
+  if (priority > 0)
+    min_expiration = GNUNET_TIME_UNIT_FOREVER_ABS;
+  else
+    min_expiration = expiration;
   GNUNET_STATISTICS_update (stats,
                             gettext_noop ("# bytes purged (low-priority)"),
                             size, GNUNET_YES);
@@ -543,6 +564,7 @@ transmit_status (struct GNUNET_SERVER_Client *client, int code, const char *msg)
   sm->header.size = htons (sizeof (struct StatusMessage) + slen);
   sm->header.type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_STATUS);
   sm->status = htonl (code);
+  sm->min_expiration = GNUNET_TIME_absolute_hton (min_expiration);
   if (slen > 0)
     memcpy (&sm[1], msg, slen);
   transmit (client, &sm->header);
@@ -1544,7 +1566,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
   }
   if (fn != NULL)
   {
-    GNUNET_asprintf (&pfn, "%s.%s\n", fn, plugin_name);
+    GNUNET_asprintf (&pfn, "%s.%s", fn, plugin_name);
     if (GNUNET_YES == GNUNET_DISK_file_test (pfn))
     {
       filter = GNUNET_CONTAINER_bloomfilter_load (pfn, bf_size, 5);        /* approx. 3% false positives at max use */