2 This file is part of GNUnet.
3 (C) 2011 Christian Grothoff (and other contributing authors)
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 3, or (at your
8 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 General Public License for more details.
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.
22 * @file fs/gnunet-service-fs_put.c
23 * @brief API to PUT zero-anonymity index data from our datastore into the DHT
24 * @author Christian Grothoff
27 #include "gnunet-service-fs.h"
28 #include "gnunet-service-fs_put.h"
32 * How often do we at most PUT content into the DHT?
34 #define MAX_DHT_PUT_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 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 * ID of task that collects blocks for DHT PUTs.
56 GNUNET_SCHEDULER_TaskIdentifier dht_task;
59 * How many entires with zero anonymity of our type do we currently
60 * estimate to have in the database?
62 uint64_t zero_anonymity_count_estimate;
65 * Current offset when iterating the database.
67 uint64_t current_offset;
72 * ANY-terminated list of our operators (one per type
73 * of block that we're putting into the DHT).
75 static struct PutOperator operators[] =
77 { NULL, GNUNET_BLOCK_TYPE_FS_KBLOCK, 0, 0, 0 },
78 { NULL, GNUNET_BLOCK_TYPE_FS_SBLOCK, 0, 0, 0 },
79 { NULL, GNUNET_BLOCK_TYPE_FS_NBLOCK, 0, 0, 0 },
80 { NULL, GNUNET_BLOCK_TYPE_ANY, 0, 0, 0 }
85 * Task that is run periodically to obtain blocks for DHT PUTs.
87 * @param cls type of blocks to gather
88 * @param tc scheduler context (unused)
91 gather_dht_put_blocks (void *cls,
92 const struct GNUNET_SCHEDULER_TaskContext *tc);
96 * Task that is run periodically to obtain blocks for DHT PUTs.
98 * @param cls type of blocks to gather
99 * @param tc scheduler context (unused)
102 delay_dht_put_blocks (void *cls,
103 const struct GNUNET_SCHEDULER_TaskContext *tc)
105 struct PutOperator *po = cls;
106 struct GNUNET_TIME_Relative delay;
108 po->dht_task = GNUNET_SCHEDULER_NO_TASK;
109 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
111 if (po->zero_anonymity_count_estimate > 0)
113 delay = GNUNET_TIME_relative_divide (GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY,
114 po->zero_anonymity_count_estimate);
115 delay = GNUNET_TIME_relative_min (delay,
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);
124 po->dht_task = GNUNET_SCHEDULER_add_delayed (delay,
125 &gather_dht_put_blocks,
131 * Store content in DHT.
134 * @param key key for the content
135 * @param size number of bytes in data
136 * @param data content stored
137 * @param type type of the content
138 * @param priority priority of the content
139 * @param anonymity anonymity-level for the content
140 * @param expiration expiration time for the content
141 * @param uid unique identifier for the datum;
142 * maybe 0 if no unique identifier is available
145 process_dht_put_content (void *cls,
146 const GNUNET_HashCode * key,
149 enum GNUNET_BLOCK_Type type,
152 struct GNUNET_TIME_Absolute
153 expiration, uint64_t uid)
155 struct PutOperator *po = cls;
160 po->zero_anonymity_count_estimate = po->current_offset - 1;
161 po->current_offset = 0;
162 po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_blocks,
166 po->zero_anonymity_count_estimate = GNUNET_MAX (po->current_offset,
167 po->zero_anonymity_count_estimate);
169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
170 "Retrieved block `%s' of type %u for DHT PUT\n",
174 GNUNET_DHT_put (GSF_dht,
176 DEFAULT_PUT_REPLICATION,
182 GNUNET_TIME_UNIT_FOREVER_REL,
183 &delay_dht_put_blocks,
189 * Task that is run periodically to obtain blocks for DHT PUTs.
191 * @param cls type of blocks to gather
192 * @param tc scheduler context (unused)
195 gather_dht_put_blocks (void *cls,
196 const struct GNUNET_SCHEDULER_TaskContext *tc)
198 struct PutOperator *po = cls;
200 po->dht_task = GNUNET_SCHEDULER_NO_TASK;
201 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
203 po->dht_qe = GNUNET_DATASTORE_get_zero_anonymity (GSF_dsh,
204 po->current_offset++,
206 GNUNET_TIME_UNIT_FOREVER_REL,
208 &process_dht_put_content, po);
209 if (NULL == po->dht_qe)
210 po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_blocks,
224 while (operators[i].dht_put_type != GNUNET_BLOCK_TYPE_ANY)
226 operators[i].dht_task = GNUNET_SCHEDULER_add_now (&gather_dht_put_blocks, &operators[i]);
233 * Shutdown the module.
238 struct PutOperator *po;
242 while ((po = &operators[i])->dht_put_type != GNUNET_BLOCK_TYPE_ANY)
244 if (GNUNET_SCHEDULER_NO_TASK != po->dht_task)
246 GNUNET_SCHEDULER_cancel (po->dht_task);
247 po->dht_task = GNUNET_SCHEDULER_NO_TASK;
249 if (NULL != po->dht_qe)
251 GNUNET_DATASTORE_cancel (po->dht_qe);
258 /* end of gnunet-service-fs_put.c */