aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-06-16 20:32:40 +0000
committerChristian Grothoff <christian@grothoff.org>2009-06-16 20:32:40 +0000
commitadb7f45adb8eff27515519f05042fc6ec616b38e (patch)
tree46e25c1b0659d125a2efae82fdcd5404c70ce2ef /src
parentdc6e9887c24209d0e3dfb6cfb30fbde6ae3b47e9 (diff)
downloadgnunet-adb7f45adb8eff27515519f05042fc6ec616b38e.tar.gz
gnunet-adb7f45adb8eff27515519f05042fc6ec616b38e.zip
improving datastore API
Diffstat (limited to 'src')
-rw-r--r--src/datastore/datastore.h90
-rw-r--r--src/datastore/datastore_api.c110
-rw-r--r--src/datastore/gnunet-service-datastore.c136
-rw-r--r--src/datastore/plugin_datastore.h14
-rw-r--r--src/datastore/plugin_datastore_sqlite.c31
-rw-r--r--src/datastore/plugin_datastore_template.c20
-rw-r--r--src/include/gnunet_datastore_service.h139
-rw-r--r--src/include/gnunet_protocols.h33
8 files changed, 454 insertions, 119 deletions
diff --git a/src/datastore/datastore.h b/src/datastore/datastore.h
index 9165c8af8..92a2889d8 100644
--- a/src/datastore/datastore.h
+++ b/src/datastore/datastore.h
@@ -33,10 +33,10 @@
33 * Message from datastore service informing client about 33 * Message from datastore service informing client about
34 * the current size of the datastore. 34 * the current size of the datastore.
35 */ 35 */
36struct SizeMessage 36struct ReserveMessage
37{ 37{
38 /** 38 /**
39 * Type is GNUNET_MESSAGE_TYPE_DATASTORE_SIZE. 39 * Type is GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE.
40 */ 40 */
41 struct GNUNET_MessageHeader header; 41 struct GNUNET_MessageHeader header;
42 42
@@ -46,9 +46,55 @@ struct SizeMessage
46 uint32_t reserved GNUNET_PACKED; 46 uint32_t reserved GNUNET_PACKED;
47 47
48 /** 48 /**
49 * Size of the datastore in bytes. 49 * Number of bytes to reserve.
50 */ 50 */
51 uint64_t size GNUNET_PACKED; 51 uint64_t size GNUNET_PACKED;
52
53 /**
54 * Number of items to reserve.
55 */
56 uint64_t items GNUNET_PACKED;
57};
58
59
60/**
61 * Message from datastore service informing client about
62 * the success or failure of a requested operation.
63 * This header is optionally followed by a variable-size,
64 * 0-terminated error message.
65 */
66struct StatusMessage
67{
68 /**
69 * Type is GNUNET_MESSAGE_TYPE_DATASTORE_STATUS.
70 */
71 struct GNUNET_MessageHeader header;
72
73 /**
74 * Status code.
75 */
76 int32_t status GNUNET_PACKED;
77
78};
79
80
81/**
82 * Message from datastore client informing service that
83 * the remainder of the reserved bytes can now be released
84 * for other requests.
85 */
86struct ReleaseReserveMessage
87{
88 /**
89 * Type is GNUNET_MESSAGE_TYPE_DATASTORE_RELEASE_RESERVE.
90 */
91 struct GNUNET_MessageHeader header;
92
93 /**
94 * Reservation id.
95 */
96 int32_t rid GNUNET_PACKED;
97
52}; 98};
53 99
54 100
@@ -80,6 +126,35 @@ struct GetMessage
80 126
81 127
82/** 128/**
129 * Message to the datastore service requesting an update
130 * to the priority or expiration for some content.
131 */
132struct UpdateMessage
133{
134 /**
135 * Type is GNUNET_MESSAGE_TYPE_DATASTORE_UPDATE.
136 */
137 struct GNUNET_MessageHeader header;
138
139 /**
140 * Desired priority increase.
141 */
142 int32_t priority GNUNET_PACKED;
143
144 /**
145 * Desired new expiration time.
146 */
147 struct GNUNET_TIME_AbsoluteNBO expiration;
148
149 /**
150 * Unique ID for the content.
151 */
152 uint64_t uid;
153
154};
155
156
157/**
83 * Message transmitting content from or to the datastore 158 * Message transmitting content from or to the datastore
84 * service. 159 * service.
85 */ 160 */
@@ -94,9 +169,9 @@ struct DataMessage
94 struct GNUNET_MessageHeader header; 169 struct GNUNET_MessageHeader header;
95 170
96 /** 171 /**
97 * Always zero. 172 * Reservation ID to use; use zero for none.
98 */ 173 */
99 uint32_t reserved GNUNET_PACKED; 174 uint32_t rid GNUNET_PACKED;
100 175
101 /** 176 /**
102 * Number of bytes in the item (NBO). 177 * Number of bytes in the item (NBO).
@@ -117,6 +192,11 @@ struct DataMessage
117 * Desired anonymity level (NBO), zero for remove. 192 * Desired anonymity level (NBO), zero for remove.
118 */ 193 */
119 uint32_t anonymity GNUNET_PACKED; 194 uint32_t anonymity GNUNET_PACKED;
195
196 /**
197 * Unique ID for the content (can be used for UPDATE).
198 */
199 uint64_t uid;
120 200
121 /** 201 /**
122 * Expiration time (NBO); zero for remove. 202 * Expiration time (NBO); zero for remove.
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c
index 95ae25f03..960d7d34e 100644
--- a/src/datastore/datastore_api.c
+++ b/src/datastore/datastore_api.c
@@ -26,7 +26,6 @@
26 * TODO: 26 * TODO:
27 * 1) clarify API (wrt. efficient UPDATE of priority/expiration after GET) 27 * 1) clarify API (wrt. efficient UPDATE of priority/expiration after GET)
28 * 2) implement INIT 28 * 2) implement INIT
29 * 3) implement SIZE handling (=> API impact?)
30 * 4) implement DROP 29 * 4) implement DROP
31 * 5) implement PUT 30 * 5) implement PUT
32 * 6) implement GET 31 * 6) implement GET
@@ -93,17 +92,6 @@ struct GNUNET_DATASTORE_Handle
93 */ 92 */
94 void *response_proc_cls; 93 void *response_proc_cls;
95 94
96 /**
97 * Current size of the datastore (cached).
98 */
99 unsigned long long size;
100
101 /**
102 * Set to GNUNET_YES if we have received the size
103 * from the datastore.
104 */
105 int ready;
106
107}; 95};
108 96
109 97
@@ -129,7 +117,6 @@ struct GNUNET_DATASTORE_Handle *GNUNET_DATASTORE_connect (struct
129 return NULL; /* oops */ 117 return NULL; /* oops */
130 h = GNUNET_malloc (sizeof(struct GNUNET_DATASTORE_Handle)); 118 h = GNUNET_malloc (sizeof(struct GNUNET_DATASTORE_Handle));
131 h->client = c; 119 h->client = c;
132 /* FIXME: send 'join' request */
133 return h; 120 return h;
134} 121}
135 122
@@ -154,19 +141,6 @@ void GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h,
154 141
155 142
156/** 143/**
157 * Get the current on-disk size of the datastore.
158 * @param h handle to the datastore
159 * @return size estimate, -1 if datastore is not available (yet)
160 */
161unsigned long long GNUNET_DATASTORE_size (struct GNUNET_DATASTORE_Handle *h)
162{
163 if (GNUNET_YES != h->ready)
164 return (unsigned long long) -1LL;
165 return h->size;
166}
167
168
169/**
170 * Store an item in the datastore. If the item is already present, 144 * Store an item in the datastore. If the item is already present,
171 * the priorities are summed up and the higher expiration time and 145 * the priorities are summed up and the higher expiration time and
172 * lower anonymity level is used. 146 * lower anonymity level is used.
@@ -179,17 +153,89 @@ unsigned long long GNUNET_DATASTORE_size (struct GNUNET_DATASTORE_Handle *h)
179 * @param priority priority of the content 153 * @param priority priority of the content
180 * @param anonymity anonymity-level for the content 154 * @param anonymity anonymity-level for the content
181 * @param expiration expiration time for the content 155 * @param expiration expiration time for the content
156 * @param cont continuation to call when done
157 * @param cont_cls closure for cont
182 */ 158 */
183void 159void
184GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, 160GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h,
161 int rid,
185 const GNUNET_HashCode * key, 162 const GNUNET_HashCode * key,
186 uint32_t size, 163 uint32_t size,
187 const void *data, 164 const void *data,
188 uint32_t type, 165 uint32_t type,
189 uint32_t priority, 166 uint32_t priority,
190 uint32_t anonymity, 167 uint32_t anonymity,
191 struct GNUNET_TIME_Absolute expiration) 168 struct GNUNET_TIME_Absolute expiration,
169 GNUNET_DATASTORE_ContinuationWithStatus cont,
170 void *cont_cls)
171{
172 cont (cont_cls, GNUNET_SYSERR, "not implemented");
173}
174
175
176/**
177 * Reserve space in the datastore. This function should be used
178 * to avoid "out of space" failures during a longer sequence of "put"
179 * operations (for example, when a file is being inserted).
180 *
181 * @param h handle to the datastore
182 * @param amount how much space (in bytes) should be reserved (for content only)
183 * @param entries how many entries will be created (to calculate per-entry overhead)
184 * @param cont continuation to call when done; "success" will be set to
185 * a positive reservation value if space could be reserved.
186 * @param cont_cls closure for cont
187 */
188void
189GNUNET_DATASTORE_reserve (struct GNUNET_DATASTORE_Handle *h,
190 uint64_t amount,
191 uint64_t entries,
192 GNUNET_DATASTORE_ContinuationWithStatus cont,
193 void *cont_cls)
192{ 194{
195 cont (cont_cls, GNUNET_SYSERR, "not implemented");
196}
197
198
199/**
200 * Signal that all of the data for which a reservation was made has
201 * been stored and that whatever excess space might have been reserved
202 * can now be released.
203 *
204 * @param h handle to the datastore
205 * @param rid reservation ID (value of "success" in original continuation
206 * from the "reserve" function).
207 * @param cont continuation to call when done
208 * @param cont_cls closure for cont
209 */
210void
211GNUNET_DATASTORE_release_reserve (struct GNUNET_DATASTORE_Handle *h,
212 int rid,
213 GNUNET_DATASTORE_ContinuationWithStatus cont,
214 void *cont_cls)
215{
216 cont (cont_cls, GNUNET_OK, NULL);
217}
218
219
220/**
221 * Update a value in the datastore.
222 *
223 * @param h handle to the datastore
224 * @param uid identifier for the value
225 * @param priority how much to increase the priority of the value
226 * @param expiration new expiration value should be MAX of existing and this argument
227 * @param cont continuation to call when done
228 * @param cont_cls closure for cont
229 */
230void
231GNUNET_DATASTORE_update (struct GNUNET_DATASTORE_Handle *h,
232 unsigned long long uid,
233 uint32_t priority,
234 struct GNUNET_TIME_Absolute expiration,
235 GNUNET_DATASTORE_ContinuationWithStatus cont,
236 void *cont_cls)
237{
238 cont (cont_cls, GNUNET_SYSERR, "not implemented");
193} 239}
194 240
195 241
@@ -210,6 +256,9 @@ GNUNET_DATASTORE_get (struct GNUNET_DATASTORE_Handle *h,
210 uint32_t type, 256 uint32_t type,
211 GNUNET_DATASTORE_Iterator iter, void *iter_cls) 257 GNUNET_DATASTORE_Iterator iter, void *iter_cls)
212{ 258{
259 static struct GNUNET_TIME_Absolute zero;
260 iter (iter_cls,
261 NULL, 0, NULL, 0, 0, 0, zero, 0);
213} 262}
214 263
215 264
@@ -240,12 +289,17 @@ GNUNET_DATASTORE_get_random (struct GNUNET_DATASTORE_Handle *h,
240 * @param key key for the value 289 * @param key key for the value
241 * @param size number of bytes in data 290 * @param size number of bytes in data
242 * @param data content stored 291 * @param data content stored
292 * @param cont continuation to call when done
293 * @param cont_cls closure for cont
243 */ 294 */
244void 295void
245GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h, 296GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h,
246 const GNUNET_HashCode * key, 297 const GNUNET_HashCode * key,
247 uint32_t size, const void *data) 298 uint32_t size, const void *data,
299 GNUNET_DATASTORE_ContinuationWithStatus cont,
300 void *cont_cls)
248{ 301{
302 cont (cont_cls, GNUNET_SYSERR, "not implemented");
249} 303}
250 304
251 305
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index fe7987632..db3524557 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -92,18 +92,28 @@ transmit (struct GNUNET_SERVER_Client *client,
92 92
93 93
94/** 94/**
95 * Transmit the size of the current datastore to the client. 95 * Transmit a status code to the client.
96 *
97 * @param client receiver of the response
98 * @param code status code
99 * @param msg optional error message (can be NULL)
96 */ 100 */
97static void 101static void
98transmit_size (struct GNUNET_SERVER_Client *client) 102transmit_status (struct GNUNET_SERVER_Client *client,
103 int code,
104 const char *msg)
99{ 105{
100 struct SizeMessage sm; 106 struct StatusMessage *sm;
101 107 size_t slen;
102 sm.header.size = htons(sizeof(struct SizeMessage)); 108
103 sm.header.type = htons(GNUNET_MESSAGE_TYPE_DATASTORE_SIZE); 109 slen = (msg == NULL) ? 0 : strlen(msg) + 1;
104 sm.reserved = htonl(0); 110 sm = GNUNET_malloc (sizeof(struct StatusMessage) + slen);
105 sm.size = GNUNET_htonll(plugin->api->get_size (plugin->api->cls)); 111 sm->header.size = htons(sizeof(struct StatusMessage) + slen);
106 transmit (client, &sm.header); 112 sm->header.type = htons(GNUNET_MESSAGE_TYPE_DATASTORE_STATUS);
113 sm->status = htonl(code);
114 memcpy (&sm[1], msg, slen);
115 transmit (client, &sm->header);
116 GNUNET_free (sm);
107} 117}
108 118
109 119
@@ -148,16 +158,16 @@ transmit_item (void *cls,
148 transmit (client, &end); 158 transmit (client, &end);
149 return GNUNET_OK; 159 return GNUNET_OK;
150 } 160 }
151 /* FIXME: make use of 'uid' for efficient priority/expiration update! */
152 dm = GNUNET_malloc (sizeof(struct DataMessage) + size); 161 dm = GNUNET_malloc (sizeof(struct DataMessage) + size);
153 dm->header.size = htons(sizeof(struct DataMessage) + size); 162 dm->header.size = htons(sizeof(struct DataMessage) + size);
154 dm->header.type = htons(GNUNET_MESSAGE_TYPE_DATASTORE_DATA); 163 dm->header.type = htons(GNUNET_MESSAGE_TYPE_DATASTORE_DATA);
155 dm->reserved = htonl(0); 164 dm->rid = htonl(0);
156 dm->size = htonl(size); 165 dm->size = htonl(size);
157 dm->type = htonl(type); 166 dm->type = htonl(type);
158 dm->priority = htonl(priority); 167 dm->priority = htonl(priority);
159 dm->anonymity = htonl(anonymity); 168 dm->anonymity = htonl(anonymity);
160 dm->expiration = GNUNET_TIME_absolute_hton(expiration); 169 dm->expiration = GNUNET_TIME_absolute_hton(expiration);
170 dm->uid = GNUNET_htonll(uid);
161 dm->key = *key; 171 dm->key = *key;
162 memcpy (&dm[1], data, size); 172 memcpy (&dm[1], data, size);
163 transmit (client, &dm->header); 173 transmit (client, &dm->header);
@@ -167,18 +177,35 @@ transmit_item (void *cls,
167 177
168 178
169/** 179/**
170 * Handle INIT-message. 180 * Handle RESERVE-message.
171 * 181 *
172 * @param cls closure 182 * @param cls closure
173 * @param client identification of the client 183 * @param client identification of the client
174 * @param message the actual message 184 * @param message the actual message
175 */ 185 */
176static void 186static void
177handle_init (void *cls, 187handle_reserve (void *cls,
178 struct GNUNET_SERVER_Client *client, 188 struct GNUNET_SERVER_Client *client,
179 const struct GNUNET_MessageHeader *message) 189 const struct GNUNET_MessageHeader *message)
180{ 190{
181 transmit_size (client); 191 transmit_status (client, GNUNET_SYSERR, "not implemented");
192 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
193}
194
195
196/**
197 * Handle RELEASE_RESERVE-message.
198 *
199 * @param cls closure
200 * @param client identification of the client
201 * @param message the actual message
202 */
203static void
204handle_release_reserve (void *cls,
205 struct GNUNET_SERVER_Client *client,
206 const struct GNUNET_MessageHeader *message)
207{
208 transmit_status (client, GNUNET_SYSERR, "not implemented");
182 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 209 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
183} 210}
184 211
@@ -208,8 +235,7 @@ check_data (const struct GNUNET_MessageHeader *message)
208 GNUNET_break (0); 235 GNUNET_break (0);
209 return NULL; 236 return NULL;
210 } 237 }
211 if ( (ntohl(dm->type) == 0) || 238 if (ntohl(dm->type) == 0)
212 (ntohl(dm->reserved) != 0) )
213 { 239 {
214 GNUNET_break (0); 240 GNUNET_break (0);
215 return NULL; 241 return NULL;
@@ -231,21 +257,33 @@ handle_put (void *cls,
231 const struct GNUNET_MessageHeader *message) 257 const struct GNUNET_MessageHeader *message)
232{ 258{
233 const struct DataMessage *dm = check_data (message); 259 const struct DataMessage *dm = check_data (message);
260 char *msg;
261 int ret;
262 int rid;
263
234 if (dm == NULL) 264 if (dm == NULL)
235 { 265 {
236 GNUNET_break (0); 266 GNUNET_break (0);
237 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 267 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
238 return; 268 return;
239 } 269 }
240 plugin->api->put (plugin->api->cls, 270 rid = ntohl(dm->rid);
241 &dm->key, 271 if (rid > 0)
242 ntohl(dm->size), 272 {
243 &dm[1], 273 /* FIXME: find reservation, update remaining! */
244 ntohl(dm->type), 274 }
245 ntohl(dm->priority), 275 msg = NULL;
246 ntohl(dm->anonymity), 276 ret = plugin->api->put (plugin->api->cls,
247 GNUNET_TIME_absolute_ntoh(dm->expiration)); 277 &dm->key,
248 transmit_size (client); 278 ntohl(dm->size),
279 &dm[1],
280 ntohl(dm->type),
281 ntohl(dm->priority),
282 ntohl(dm->anonymity),
283 GNUNET_TIME_absolute_ntoh(dm->expiration),
284 &msg);
285 transmit_status (client, ret, msg);
286 GNUNET_free_non_null (msg);
249 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 287 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
250} 288}
251 289
@@ -285,6 +323,35 @@ handle_get (void *cls,
285 323
286 324
287/** 325/**
326 * Handle UPDATE-message.
327 *
328 * @param cls closure
329 * @param client identification of the client
330 * @param message the actual message
331 */
332static void
333handle_update (void *cls,
334 struct GNUNET_SERVER_Client *client,
335 const struct GNUNET_MessageHeader *message)
336{
337 const struct UpdateMessage *msg;
338 int ret;
339 char *emsg;
340
341 msg = (const struct UpdateMessage*) message;
342 emsg = NULL;
343 ret = plugin->api->update (plugin->api->cls,
344 GNUNET_ntohll(msg->uid),
345 (int32_t) ntohl(msg->priority),
346 GNUNET_TIME_absolute_ntoh(msg->expiration),
347 &emsg);
348 transmit_status (client, ret, emsg);
349 GNUNET_free_non_null (emsg);
350 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
351}
352
353
354/**
288 * Handle GET_RANDOM-message. 355 * Handle GET_RANDOM-message.
289 * 356 *
290 * @param cls closure 357 * @param cls closure
@@ -319,6 +386,8 @@ remove_callback (void *cls,
319 struct GNUNET_TIME_Absolute 386 struct GNUNET_TIME_Absolute
320 expiration, unsigned long long uid) 387 expiration, unsigned long long uid)
321{ 388{
389 int *found = cls;
390 *found = GNUNET_YES;
322 return GNUNET_NO; 391 return GNUNET_NO;
323} 392}
324 393
@@ -337,6 +406,7 @@ handle_remove (void *cls,
337{ 406{
338 const struct DataMessage *dm = check_data (message); 407 const struct DataMessage *dm = check_data (message);
339 GNUNET_HashCode vhash; 408 GNUNET_HashCode vhash;
409 int found;
340 410
341 if (dm == NULL) 411 if (dm == NULL)
342 { 412 {
@@ -344,6 +414,7 @@ handle_remove (void *cls,
344 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 414 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
345 return; 415 return;
346 } 416 }
417 found = GNUNET_NO;
347 GNUNET_CRYPTO_hash (&dm[1], 418 GNUNET_CRYPTO_hash (&dm[1],
348 ntohl(dm->size), 419 ntohl(dm->size),
349 &vhash); 420 &vhash);
@@ -352,8 +423,11 @@ handle_remove (void *cls,
352 &vhash, 423 &vhash,
353 ntohl(dm->type), 424 ntohl(dm->type),
354 &remove_callback, 425 &remove_callback,
355 NULL); 426 &found);
356 transmit_size (client); 427 if (GNUNET_YES == found)
428 transmit_status (client, GNUNET_OK, NULL);
429 else
430 transmit_status (client, GNUNET_SYSERR, _("Content not found"));
357 GNUNET_SERVER_receive_done (client, GNUNET_OK); 431 GNUNET_SERVER_receive_done (client, GNUNET_OK);
358} 432}
359 433
@@ -380,9 +454,13 @@ handle_drop (void *cls,
380 * service. 454 * service.
381 */ 455 */
382static struct GNUNET_SERVER_MessageHandler handlers[] = { 456static struct GNUNET_SERVER_MessageHandler handlers[] = {
383 {&handle_init, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_INIT, 457 {&handle_reserve, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE,
384 sizeof(struct GNUNET_MessageHeader) }, 458 sizeof(struct ReserveMessage) },
459 {&handle_release_reserve, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_RELEASE_RESERVE,
460 sizeof(struct ReleaseReserveMessage) },
385 {&handle_put, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_PUT, 0 }, 461 {&handle_put, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_PUT, 0 },
462 {&handle_update, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_UPDATE,
463 sizeof (struct UpdateMessage) },
386 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_GET, 0 }, 464 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_GET, 0 },
387 {&handle_get_random, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_GET_RANDOM, 465 {&handle_get_random, NULL, GNUNET_MESSAGE_TYPE_DATASTORE_GET_RANDOM,
388 sizeof(struct GNUNET_MessageHeader) }, 466 sizeof(struct GNUNET_MessageHeader) },
diff --git a/src/datastore/plugin_datastore.h b/src/datastore/plugin_datastore.h
index 1c038bf19..cc68f3557 100644
--- a/src/datastore/plugin_datastore.h
+++ b/src/datastore/plugin_datastore.h
@@ -73,8 +73,10 @@ typedef unsigned long long (*GNUNET_DATASTORE_GetSize) (void *cls);
73 * @param priority priority of the content 73 * @param priority priority of the content
74 * @param anonymity anonymity-level for the content 74 * @param anonymity anonymity-level for the content
75 * @param expiration expiration time for the content 75 * @param expiration expiration time for the content
76 * @param msg set to an error message (on failure)
77 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
76 */ 78 */
77typedef void 79typedef int
78 (*GNUNET_DATASTORE_Put) (void *cls, 80 (*GNUNET_DATASTORE_Put) (void *cls,
79 const GNUNET_HashCode * key, 81 const GNUNET_HashCode * key,
80 uint32_t size, 82 uint32_t size,
@@ -82,7 +84,8 @@ typedef void
82 uint32_t type, 84 uint32_t type,
83 uint32_t priority, 85 uint32_t priority,
84 uint32_t anonymity, 86 uint32_t anonymity,
85 struct GNUNET_TIME_Absolute expiration); 87 struct GNUNET_TIME_Absolute expiration,
88 char **msg);
86 89
87 90
88/** 91/**
@@ -129,11 +132,14 @@ typedef void
129 * @param expire new expiration time should be the 132 * @param expire new expiration time should be the
130 * MAX of any existing expiration time and 133 * MAX of any existing expiration time and
131 * this value 134 * this value
135 * @param msg set to an error message (on error)
136 * @return GNUNET_OK on success
132 */ 137 */
133typedef void 138typedef int
134 (*GNUNET_DATASTORE_Update) (void *cls, 139 (*GNUNET_DATASTORE_Update) (void *cls,
135 unsigned long long uid, 140 unsigned long long uid,
136 int delta, struct GNUNET_TIME_Absolute expire); 141 int delta, struct GNUNET_TIME_Absolute expire,
142 char **msg);
137 143
138 144
139/** 145/**
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c
index 486b9b96e..234519079 100644
--- a/src/datastore/plugin_datastore_sqlite.c
+++ b/src/datastore/plugin_datastore_sqlite.c
@@ -62,8 +62,10 @@ static unsigned long long sqlite_plugin_get_size (void *cls)
62 * @param priority priority of the content 62 * @param priority priority of the content
63 * @param anonymity anonymity-level for the content 63 * @param anonymity anonymity-level for the content
64 * @param expiration expiration time for the content 64 * @param expiration expiration time for the content
65 * @param msg set to an error message
66 * @return GNUNET_OK on success
65 */ 67 */
66static void 68static int
67sqlite_plugin_put (void *cls, 69sqlite_plugin_put (void *cls,
68 const GNUNET_HashCode * key, 70 const GNUNET_HashCode * key,
69 uint32_t size, 71 uint32_t size,
@@ -71,8 +73,11 @@ sqlite_plugin_put (void *cls,
71 uint32_t type, 73 uint32_t type,
72 uint32_t priority, 74 uint32_t priority,
73 uint32_t anonymity, 75 uint32_t anonymity,
74 struct GNUNET_TIME_Absolute expiration) 76 struct GNUNET_TIME_Absolute expiration,
77 char ** msg)
75{ 78{
79 *msg = GNUNET_strdup("not implemented");
80 return GNUNET_SYSERR;
76} 81}
77 82
78 83
@@ -100,6 +105,8 @@ sqlite_plugin_get (void *cls,
100 uint32_t type, 105 uint32_t type,
101 GNUNET_DATASTORE_Iterator iter, void *iter_cls) 106 GNUNET_DATASTORE_Iterator iter, void *iter_cls)
102{ 107{
108 static struct GNUNET_TIME_Absolute zero;
109 iter (iter_cls, NULL, 0, NULL, 0, 0, 0, zero, 0);
103} 110}
104 111
105 112
@@ -122,12 +129,17 @@ sqlite_plugin_get (void *cls,
122 * @param expire new expiration time should be the 129 * @param expire new expiration time should be the
123 * MAX of any existing expiration time and 130 * MAX of any existing expiration time and
124 * this value 131 * this value
132 * @param msg set to an error message
133 * @return GNUNET_OK on success
125 */ 134 */
126static void 135static int
127sqlite_plugin_update (void *cls, 136sqlite_plugin_update (void *cls,
128 unsigned long long uid, 137 unsigned long long uid,
129 int delta, struct GNUNET_TIME_Absolute expire) 138 int delta, struct GNUNET_TIME_Absolute expire,
139 char **msg)
130{ 140{
141 *msg = GNUNET_strdup ("not implemented");
142 return GNUNET_SYSERR;
131} 143}
132 144
133 145
@@ -147,10 +159,11 @@ sqlite_plugin_iter_low_priority (void *cls,
147 GNUNET_DATASTORE_Iterator iter, 159 GNUNET_DATASTORE_Iterator iter,
148 void *iter_cls) 160 void *iter_cls)
149{ 161{
162 static struct GNUNET_TIME_Absolute zero;
163 iter (iter_cls, NULL, 0, NULL, 0, 0, 0, zero, 0);
150} 164}
151 165
152 166
153
154/** 167/**
155 * Select a subset of the items in the datastore and call 168 * Select a subset of the items in the datastore and call
156 * the given iterator for each of them. 169 * the given iterator for each of them.
@@ -167,6 +180,8 @@ sqlite_plugin_iter_zero_anonymity (void *cls,
167 GNUNET_DATASTORE_Iterator iter, 180 GNUNET_DATASTORE_Iterator iter,
168 void *iter_cls) 181 void *iter_cls)
169{ 182{
183 static struct GNUNET_TIME_Absolute zero;
184 iter (iter_cls, NULL, 0, NULL, 0, 0, 0, zero, 0);
170} 185}
171 186
172 187
@@ -187,6 +202,8 @@ sqlite_plugin_iter_ascending_expiration (void *cls,
187 GNUNET_DATASTORE_Iterator iter, 202 GNUNET_DATASTORE_Iterator iter,
188 void *iter_cls) 203 void *iter_cls)
189{ 204{
205 static struct GNUNET_TIME_Absolute zero;
206 iter (iter_cls, NULL, 0, NULL, 0, 0, 0, zero, 0);
190} 207}
191 208
192 209
@@ -207,6 +224,8 @@ sqlite_plugin_iter_migration_order (void *cls,
207 GNUNET_DATASTORE_Iterator iter, 224 GNUNET_DATASTORE_Iterator iter,
208 void *iter_cls) 225 void *iter_cls)
209{ 226{
227 static struct GNUNET_TIME_Absolute zero;
228 iter (iter_cls, NULL, 0, NULL, 0, 0, 0, zero, 0);
210} 229}
211 230
212 231
@@ -227,6 +246,8 @@ sqlite_plugin_iter_all_now (void *cls,
227 GNUNET_DATASTORE_Iterator iter, 246 GNUNET_DATASTORE_Iterator iter,
228 void *iter_cls) 247 void *iter_cls)
229{ 248{
249 static struct GNUNET_TIME_Absolute zero;
250 iter (iter_cls, NULL, 0, NULL, 0, 0, 0, zero, 0);
230} 251}
231 252
232 253
diff --git a/src/datastore/plugin_datastore_template.c b/src/datastore/plugin_datastore_template.c
index 70b8c635e..1e3d4343b 100644
--- a/src/datastore/plugin_datastore_template.c
+++ b/src/datastore/plugin_datastore_template.c
@@ -62,8 +62,10 @@ static unsigned long long template_plugin_get_size (void *cls)
62 * @param priority priority of the content 62 * @param priority priority of the content
63 * @param anonymity anonymity-level for the content 63 * @param anonymity anonymity-level for the content
64 * @param expiration expiration time for the content 64 * @param expiration expiration time for the content
65 * @param msg set to error message
66 * @return GNUNET_OK on success
65 */ 67 */
66static void 68static int
67template_plugin_put (void *cls, 69template_plugin_put (void *cls,
68 const GNUNET_HashCode * key, 70 const GNUNET_HashCode * key,
69 uint32_t size, 71 uint32_t size,
@@ -71,8 +73,11 @@ template_plugin_put (void *cls,
71 uint32_t type, 73 uint32_t type,
72 uint32_t priority, 74 uint32_t priority,
73 uint32_t anonymity, 75 uint32_t anonymity,
74 struct GNUNET_TIME_Absolute expiration) 76 struct GNUNET_TIME_Absolute expiration,
77 char **msg)
75{ 78{
79 *msg = GNUNET_strdup ("not implemented");
80 return GNUNET_SYSERR;
76} 81}
77 82
78 83
@@ -122,12 +127,17 @@ template_plugin_get (void *cls,
122 * @param expire new expiration time should be the 127 * @param expire new expiration time should be the
123 * MAX of any existing expiration time and 128 * MAX of any existing expiration time and
124 * this value 129 * this value
130 * @param msg set to error message
131 * @return GNUNET_OK on success
125 */ 132 */
126static void 133static int
127template_plugin_update (void *cls, 134template_plugin_update (void *cls,
128 unsigned long long uid, 135 unsigned long long uid,
129 int delta, struct GNUNET_TIME_Absolute expire) 136 int delta, struct GNUNET_TIME_Absolute expire,
137 char **msg)
130{ 138{
139 *msg = GNUNET_strdup ("not implemented");
140 return GNUNET_SYSERR;
131} 141}
132 142
133 143
diff --git a/src/include/gnunet_datastore_service.h b/src/include/gnunet_datastore_service.h
index 2f7fce6d8..626a5afcc 100644
--- a/src/include/gnunet_datastore_service.h
+++ b/src/include/gnunet_datastore_service.h
@@ -49,33 +49,6 @@ struct GNUNET_DATASTORE_Handle;
49 49
50 50
51/** 51/**
52 * An iterator over a set of items stored in the datastore.
53 *
54 * @param cls closure
55 * @param key key for the content
56 * @param size number of bytes in data
57 * @param data content stored
58 * @param type type of the content
59 * @param priority priority of the content
60 * @param anonymity anonymity-level for the content
61 * @param expiration expiration time for the content
62 * @param uid unique identifier for the datum;
63 * maybe 0 if no unique identifier is available
64 *
65 * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue,
66 * GNUNET_NO to delete the item and continue (if supported)
67 */
68typedef int (*GNUNET_DATASTORE_Iterator) (void *cls,
69 const GNUNET_HashCode * key,
70 uint32_t size,
71 const void *data,
72 uint32_t type,
73 uint32_t priority,
74 uint32_t anonymity,
75 struct GNUNET_TIME_Absolute
76 expiration, unsigned long long uid);
77
78/**
79 * Connect to the datastore service. 52 * Connect to the datastore service.
80 * 53 *
81 * @param cfg configuration to use 54 * @param cfg configuration to use
@@ -102,11 +75,36 @@ void GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h,
102 75
103 76
104/** 77/**
105 * Get the current on-disk size of the datastore. 78 * Continuation called to notify client about result of the
79 * operation.
80 *
81 * @param cls closure
82 * @param success GNUNET_SYSERR on failure
83 * @param msg NULL on success, otherwise an error message
84 */
85typedef void (*GNUNET_DATASTORE_ContinuationWithStatus)(void *cls,
86 int success,
87 const char *msg);
88
89
90/**
91 * Reserve space in the datastore. This function should be used
92 * to avoid "out of space" failures during a longer sequence of "put"
93 * operations (for example, when a file is being inserted).
94 *
106 * @param h handle to the datastore 95 * @param h handle to the datastore
107 * @return size estimate, -1 if datastore is not available (yet) 96 * @param amount how much space (in bytes) should be reserved (for content only)
97 * @param entries how many entries will be created (to calculate per-entry overhead)
98 * @param cont continuation to call when done; "success" will be set to
99 * a positive reservation value if space could be reserved.
100 * @param cont_cls closure for cont
108 */ 101 */
109unsigned long long GNUNET_DATASTORE_size (struct GNUNET_DATASTORE_Handle *h); 102void
103GNUNET_DATASTORE_reserve (struct GNUNET_DATASTORE_Handle *h,
104 uint64_t amount,
105 uint64_t entries,
106 GNUNET_DATASTORE_ContinuationWithStatus cont,
107 void *cont_cls);
110 108
111 109
112/** 110/**
@@ -115,6 +113,8 @@ unsigned long long GNUNET_DATASTORE_size (struct GNUNET_DATASTORE_Handle *h);
115 * lower anonymity level is used. 113 * lower anonymity level is used.
116 * 114 *
117 * @param h handle to the datastore 115 * @param h handle to the datastore
116 * @param rid reservation ID to use (from "reserve"); use 0 if no
117 * prior reservation was made
118 * @param key key for the value 118 * @param key key for the value
119 * @param size number of bytes in data 119 * @param size number of bytes in data
120 * @param data content stored 120 * @param data content stored
@@ -122,16 +122,87 @@ unsigned long long GNUNET_DATASTORE_size (struct GNUNET_DATASTORE_Handle *h);
122 * @param priority priority of the content 122 * @param priority priority of the content
123 * @param anonymity anonymity-level for the content 123 * @param anonymity anonymity-level for the content
124 * @param expiration expiration time for the content 124 * @param expiration expiration time for the content
125 * @param cont continuation to call when done
126 * @param cont_cls closure for cont
125 */ 127 */
126void 128void
127GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, 129GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h,
130 int rid,
128 const GNUNET_HashCode * key, 131 const GNUNET_HashCode * key,
129 uint32_t size, 132 uint32_t size,
130 const void *data, 133 const void *data,
131 uint32_t type, 134 uint32_t type,
132 uint32_t priority, 135 uint32_t priority,
133 uint32_t anonymity, 136 uint32_t anonymity,
134 struct GNUNET_TIME_Absolute expiration); 137 struct GNUNET_TIME_Absolute expiration,
138 GNUNET_DATASTORE_ContinuationWithStatus cont,
139 void *cont_cls);
140
141
142/**
143 * Signal that all of the data for which a reservation was made has
144 * been stored and that whatever excess space might have been reserved
145 * can now be released.
146 *
147 * @param h handle to the datastore
148 * @param rid reservation ID (value of "success" in original continuation
149 * from the "reserve" function).
150 * @param cont continuation to call when done
151 * @param cont_cls closure for cont
152 */
153void
154GNUNET_DATASTORE_release_reserve (struct GNUNET_DATASTORE_Handle *h,
155 int rid,
156 GNUNET_DATASTORE_ContinuationWithStatus cont,
157 void *cont_cls);
158
159
160/**
161 * Update a value in the datastore.
162 *
163 * @param h handle to the datastore
164 * @param uid identifier for the value
165 * @param priority how much to increase the priority of the value
166 * @param expiration new expiration value should be MAX of existing and this argument
167 * @param cont continuation to call when done
168 * @param cont_cls closure for cont
169 */
170void
171GNUNET_DATASTORE_update (struct GNUNET_DATASTORE_Handle *h,
172 unsigned long long uid,
173 uint32_t priority,
174 struct GNUNET_TIME_Absolute expiration,
175 GNUNET_DATASTORE_ContinuationWithStatus cont,
176 void *cont_cls);
177
178
179/**
180 * An iterator over a set of items stored in the datastore.
181 *
182 * @param cls closure
183 * @param key key for the content
184 * @param size number of bytes in data
185 * @param data content stored
186 * @param type type of the content
187 * @param priority priority of the content
188 * @param anonymity anonymity-level for the content
189 * @param expiration expiration time for the content
190 * @param uid unique identifier for the datum;
191 * maybe 0 if no unique identifier is available
192 *
193 * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue,
194 * GNUNET_NO to delete the item and continue (if supported)
195 */
196typedef int (*GNUNET_DATASTORE_Iterator) (void *cls,
197 const GNUNET_HashCode * key,
198 uint32_t size,
199 const void *data,
200 uint32_t type,
201 uint32_t priority,
202 uint32_t anonymity,
203 struct GNUNET_TIME_Absolute
204 expiration, unsigned long long uid);
205
135 206
136/** 207/**
137 * Iterate over the results for a particular key 208 * Iterate over the results for a particular key
@@ -172,11 +243,15 @@ GNUNET_DATASTORE_get_random (struct GNUNET_DATASTORE_Handle *h,
172 * @param key key for the value 243 * @param key key for the value
173 * @param size number of bytes in data 244 * @param size number of bytes in data
174 * @param data content stored 245 * @param data content stored
246 * @param cont continuation to call when done
247 * @param cont_cls closure for cont
175 */ 248 */
176void 249void
177GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h, 250GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h,
178 const GNUNET_HashCode *key, 251 const GNUNET_HashCode *key,
179 uint32_t size, const void *data); 252 uint32_t size, const void *data,
253 GNUNET_DATASTORE_ContinuationWithStatus cont,
254 void *cont_cls);
180 255
181 256
182#if 0 /* keep Emacsens' auto-indent happy */ 257#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 04bfe2a4f..f78464593 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -306,51 +306,62 @@ extern "C"
306/** 306/**
307 * Message sent by datastore client on join. 307 * Message sent by datastore client on join.
308 */ 308 */
309#define GNUNET_MESSAGE_TYPE_DATASTORE_INIT 92 309#define GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE 92
310 310
311/** 311/**
312 * Message sent by datastore to client informing about size. 312 * Message sent by datastore client on join.
313 * (in response to JOIN, PUT and REMOVE requests). 313 */
314#define GNUNET_MESSAGE_TYPE_DATASTORE_RELEASE_RESERVE 93
315
316/**
317 * Message sent by datastore to client informing about status
318 * processing a request
319 * (in response to RESERVE, RELEASE_RESERVE, PUT, UPDATE and REMOVE requests).
314 */ 320 */
315#define GNUNET_MESSAGE_TYPE_DATASTORE_SIZE 93 321#define GNUNET_MESSAGE_TYPE_DATASTORE_STATUS 94
316 322
317/** 323/**
318 * Message sent by datastore client to store data. 324 * Message sent by datastore client to store data.
319 */ 325 */
320#define GNUNET_MESSAGE_TYPE_DATASTORE_PUT 94 326#define GNUNET_MESSAGE_TYPE_DATASTORE_PUT 95
327
328/**
329 * Message sent by datastore client to update data.
330 */
331#define GNUNET_MESSAGE_TYPE_DATASTORE_UPDATE 96
321 332
322/** 333/**
323 * Message sent by datastore client to get data. 334 * Message sent by datastore client to get data.
324 */ 335 */
325#define GNUNET_MESSAGE_TYPE_DATASTORE_GET 95 336#define GNUNET_MESSAGE_TYPE_DATASTORE_GET 97
326 337
327/** 338/**
328 * Message sent by datastore client to get random data. 339 * Message sent by datastore client to get random data.
329 */ 340 */
330#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_RANDOM 96 341#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_RANDOM 98
331 342
332/** 343/**
333 * Message sent by datastore to client providing requested data 344 * Message sent by datastore to client providing requested data
334 * (in response to GET or GET_RANDOM request). 345 * (in response to GET or GET_RANDOM request).
335 */ 346 */
336#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA 97 347#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA 99
337 348
338/** 349/**
339 * Message sent by datastore to client signaling end of matching data. 350 * Message sent by datastore to client signaling end of matching data.
340 * This message will also be sent for "GET_RANDOM", even though 351 * This message will also be sent for "GET_RANDOM", even though
341 * "GET_RANDOM" returns at most one data item. 352 * "GET_RANDOM" returns at most one data item.
342 */ 353 */
343#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END 98 354#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END 100
344 355
345/** 356/**
346 * Message sent by datastore client to remove data. 357 * Message sent by datastore client to remove data.
347 */ 358 */
348#define GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE 99 359#define GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE 101
349 360
350/** 361/**
351 * Message sent by datastore client to drop the database. 362 * Message sent by datastore client to drop the database.
352 */ 363 */
353#define GNUNET_MESSAGE_TYPE_DATASTORE_DROP 100 364#define GNUNET_MESSAGE_TYPE_DATASTORE_DROP 102
354 365
355/* 366/*
356 TODO: 367 TODO: