2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
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 Affero General Public License for more details.
17 * @file fs/gnunet-service-fs_put.c
18 * @brief API to PUT zero-anonymity index data from our datastore into the DHT
19 * @author Christian Grothoff
22 #include "gnunet-service-fs.h"
23 #include "gnunet-service-fs_put.h"
27 * How often do we at most PUT content into the DHT?
29 #define MAX_DHT_PUT_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
32 * How many replicas do we try to create per PUT?
34 #define DEFAULT_PUT_REPLICATION 5
38 * Context for each zero-anonymity iterator.
44 * Request to datastore for DHT PUTs (or NULL).
46 struct GNUNET_DATASTORE_QueueEntry *dht_qe;
49 * Type we request from the datastore.
51 enum GNUNET_BLOCK_Type dht_put_type;
54 * Handle to PUT operation.
56 struct GNUNET_DHT_PutHandle *dht_put;
59 * ID of task that collects blocks for DHT PUTs.
61 struct GNUNET_SCHEDULER_Task * dht_task;
64 * How many entires with zero anonymity of our type do we currently
65 * estimate to have in the database?
67 uint64_t zero_anonymity_count_estimate;
70 * Count of results received from the database.
72 uint64_t result_count;
75 * Next UID to request when iterating the database.
82 * ANY-terminated list of our operators (one per type
83 * of block that we're putting into the DHT).
85 static struct PutOperator operators[] = {
86 {NULL, GNUNET_BLOCK_TYPE_FS_UBLOCK, 0, 0, 0},
87 {NULL, GNUNET_BLOCK_TYPE_ANY, 0, 0, 0}
92 * Task that is run periodically to obtain blocks for DHT PUTs.
94 * @param cls type of blocks to gather
95 * @param tc scheduler context (unused)
98 gather_dht_put_blocks (void *cls);
102 * Calculate when to run the next PUT operation and schedule it.
104 * @param po put operator to schedule
107 schedule_next_put (struct PutOperator *po)
109 struct GNUNET_TIME_Relative delay;
111 if (po->zero_anonymity_count_estimate > 0)
114 GNUNET_TIME_relative_divide (GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY,
115 po->zero_anonymity_count_estimate);
116 delay = GNUNET_TIME_relative_min (delay, MAX_DHT_PUT_FREQ);
120 /* if we have NO zero-anonymity content yet, wait 5 minutes for some to
121 * (hopefully) appear */
122 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5);
125 GNUNET_SCHEDULER_add_delayed (delay, &gather_dht_put_blocks, po);
130 * Continuation called after DHT PUT operation has finished.
132 * @param cls type of blocks to gather
135 delay_dht_put_blocks (void *cls)
137 struct PutOperator *po = cls;
140 schedule_next_put (po);
145 * Task that is run periodically to obtain blocks for DHT PUTs.
147 * @param cls type of blocks to gather
150 delay_dht_put_task (void *cls)
152 struct PutOperator *po = cls;
155 schedule_next_put (po);
160 * Store content in DHT.
163 * @param key key for the content
164 * @param size number of bytes in data
165 * @param data content stored
166 * @param type type of the content
167 * @param priority priority of the content
168 * @param anonymity anonymity-level for the content
169 * @param replication replication-level for the content
170 * @param expiration expiration time for the content
171 * @param uid unique identifier for the datum;
172 * maybe 0 if no unique identifier is available
175 process_dht_put_content (void *cls,
176 const struct GNUNET_HashCode * key,
179 enum GNUNET_BLOCK_Type type,
182 uint32_t replication,
183 struct GNUNET_TIME_Absolute expiration,
186 struct PutOperator *po = cls;
191 po->zero_anonymity_count_estimate = po->result_count;
192 po->result_count = 0;
194 po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po);
198 po->next_uid = uid + 1;
199 po->zero_anonymity_count_estimate =
200 GNUNET_MAX (po->result_count, po->zero_anonymity_count_estimate);
201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
202 "Retrieved block `%s' of type %u for DHT PUT\n", GNUNET_h2s (key),
204 po->dht_put = GNUNET_DHT_put (GSF_dht,
206 DEFAULT_PUT_REPLICATION,
207 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
212 &delay_dht_put_blocks,
218 * Task that is run periodically to obtain blocks for DHT PUTs.
220 * @param cls type of blocks to gather
223 gather_dht_put_blocks (void *cls)
225 struct PutOperator *po = cls;
229 GNUNET_DATASTORE_get_zero_anonymity (GSF_dsh,
234 &process_dht_put_content,
236 if (NULL == po->dht_qe)
237 po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po);
250 while (operators[i].dht_put_type != GNUNET_BLOCK_TYPE_ANY)
252 operators[i].dht_task =
253 GNUNET_SCHEDULER_add_now (&gather_dht_put_blocks, &operators[i]);
260 * Shutdown the module.
265 struct PutOperator *po;
269 while ((po = &operators[i])->dht_put_type != GNUNET_BLOCK_TYPE_ANY)
271 if (NULL != po->dht_task)
273 GNUNET_SCHEDULER_cancel (po->dht_task);
276 if (NULL != po->dht_put)
278 GNUNET_DHT_put_cancel (po->dht_put);
281 if (NULL != po->dht_qe)
283 GNUNET_DATASTORE_cancel (po->dht_qe);
290 /* end of gnunet-service-fs_put.c */