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 * Request to datastore for DHT PUTs (or NULL).
40 static struct GNUNET_DATASTORE_QueueEntry *dht_qe;
43 * Type we will request for the next DHT PUT round from the datastore.
45 static enum GNUNET_BLOCK_Type dht_put_type = GNUNET_BLOCK_TYPE_FS_KBLOCK;
48 * ID of task that collects blocks for DHT PUTs.
50 static GNUNET_SCHEDULER_TaskIdentifier dht_task;
53 * How many entires with zero anonymity do we currently estimate
54 * to have in the database?
56 static unsigned int zero_anonymity_count_estimate;
60 * Task that is run periodically to obtain blocks for DHT PUTs.
62 * @param cls type of blocks to gather
63 * @param tc scheduler context (unused)
66 gather_dht_put_blocks (void *cls,
67 const struct GNUNET_SCHEDULER_TaskContext *tc);
72 * If the DHT PUT gathering task is not currently running, consider
73 * (re)scheduling it with the appropriate delay.
76 consider_dht_put_gathering (void *cls)
78 struct GNUNET_TIME_Relative delay;
84 if (dht_task != GNUNET_SCHEDULER_NO_TASK)
86 if (zero_anonymity_count_estimate > 0)
88 delay = GNUNET_TIME_relative_divide (GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY,
89 zero_anonymity_count_estimate);
90 delay = GNUNET_TIME_relative_min (delay,
95 /* if we have NO zero-anonymity content yet, wait 5 minutes for some to
97 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5);
99 dht_task = GNUNET_SCHEDULER_add_delayed (delay,
100 &gather_dht_put_blocks,
106 * Function called upon completion of the DHT PUT operation.
109 dht_put_continuation (void *cls,
110 const struct GNUNET_SCHEDULER_TaskContext *tc)
112 GNUNET_DATASTORE_get_next (GSF_dsh);
117 * Store content in DHT.
120 * @param key key for the content
121 * @param size number of bytes in data
122 * @param data content stored
123 * @param type type of the content
124 * @param priority priority of the content
125 * @param anonymity anonymity-level for the content
126 * @param expiration expiration time for the content
127 * @param uid unique identifier for the datum;
128 * maybe 0 if no unique identifier is available
131 process_dht_put_content (void *cls,
132 const GNUNET_HashCode * key,
135 enum GNUNET_BLOCK_Type type,
138 struct GNUNET_TIME_Absolute
139 expiration, uint64_t uid)
141 static unsigned int counter;
142 static GNUNET_HashCode last_vhash;
143 static GNUNET_HashCode vhash;
148 consider_dht_put_gathering (cls);
151 /* slightly funky code to estimate the total number of values with zero
152 anonymity from the maximum observed length of a monotonically increasing
153 sequence of hashes over the contents */
154 GNUNET_CRYPTO_hash (data, size, &vhash);
155 if (GNUNET_CRYPTO_hash_cmp (&vhash, &last_vhash) <= 0)
157 if (zero_anonymity_count_estimate > 0)
158 zero_anonymity_count_estimate /= 2;
164 if (zero_anonymity_count_estimate < (1 << counter))
165 zero_anonymity_count_estimate = (1 << counter);
167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
168 "Retrieved block `%s' of type %u for DHT PUT\n",
172 GNUNET_DHT_put (GSF_dht,
174 DEFAULT_PUT_REPLICATION,
180 GNUNET_TIME_UNIT_FOREVER_REL,
181 &dht_put_continuation,
187 * Task that is run periodically to obtain blocks for DHT PUTs.
189 * @param cls type of blocks to gather
190 * @param tc scheduler context (unused)
193 gather_dht_put_blocks (void *cls,
194 const struct GNUNET_SCHEDULER_TaskContext *tc)
196 dht_task = GNUNET_SCHEDULER_NO_TASK;
199 if (dht_put_type == GNUNET_BLOCK_TYPE_FS_ONDEMAND)
200 dht_put_type = GNUNET_BLOCK_TYPE_FS_KBLOCK;
201 dht_qe = GNUNET_DATASTORE_get_zero_anonymity (GSF_dsh,
203 GNUNET_TIME_UNIT_FOREVER_REL,
205 &process_dht_put_content, NULL);
206 GNUNET_assert (dht_qe != NULL);
216 dht_task = GNUNET_SCHEDULER_add_now (&gather_dht_put_blocks, NULL);
221 * Shutdown the module.
226 if (GNUNET_SCHEDULER_NO_TASK != dht_task)
228 GNUNET_SCHEDULER_cancel (dht_task);
229 dht_task = GNUNET_SCHEDULER_NO_TASK;
233 GNUNET_DATASTORE_cancel (dht_qe);
238 /* end of gnunet-service-fs_put.c */