aboutsummaryrefslogtreecommitdiff
path: root/src/datastore/gnunet-service-datastore.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-07-21 23:20:36 +0000
committerChristian Grothoff <christian@grothoff.org>2009-07-21 23:20:36 +0000
commitc8a0595aee76d863605801d76589e83926693ca7 (patch)
tree63640c2a03601ce8b1fb5797b23f55e99bc32aeb /src/datastore/gnunet-service-datastore.c
parent050ce82c79ef540b308a2bcee7514dd563fc5795 (diff)
downloadgnunet-c8a0595aee76d863605801d76589e83926693ca7.tar.gz
gnunet-c8a0595aee76d863605801d76589e83926693ca7.zip
reservations
Diffstat (limited to 'src/datastore/gnunet-service-datastore.c')
-rw-r--r--src/datastore/gnunet-service-datastore.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index f491d2453..89c5d6af8 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -26,7 +26,6 @@
26 * TODO: 26 * TODO:
27 * quota management code: 27 * quota management code:
28 * - track storage use 28 * - track storage use
29 * - track reservations
30 * - refuse above-quota 29 * - refuse above-quota
31 * - content expiration job 30 * - content expiration job
32 * - near-quota low-priority content discard job 31 * - near-quota low-priority content discard job
@@ -134,6 +133,11 @@ static int reservation_gen;
134 */ 133 */
135static unsigned long long quota; 134static unsigned long long quota;
136 135
136/**
137 * How much space have we currently reserved?
138 */
139static unsigned long long reserved;
140
137 141
138/** 142/**
139 * Function called once the transmit operation has 143 * Function called once the transmit operation has
@@ -420,24 +424,44 @@ transmit_item (void *cls,
420 */ 424 */
421static void 425static void
422handle_reserve (void *cls, 426handle_reserve (void *cls,
423 struct GNUNET_SERVER_Client *client, 427 struct GNUNET_SERVER_Client *client,
424 const struct GNUNET_MessageHeader *message) 428 const struct GNUNET_MessageHeader *message)
425{ 429{
426 const struct ReserveMessage *msg = (const struct ReserveMessage*) message; 430 const struct ReserveMessage *msg = (const struct ReserveMessage*) message;
427 struct ReservationList *e; 431 struct ReservationList *e;
432 unsigned long long used;
433 unsigned long long req;
434 uint64_t amount;
435 uint64_t entries;
428 436
429#if DEBUG_DATASTORE 437#if DEBUG_DATASTORE
430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 438 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
431 "Processing `%s' request\n", 439 "Processing `%s' request\n",
432 "RESERVE"); 440 "RESERVE");
433#endif 441#endif
434 /* FIXME: check if we have that much space... */ 442 amount = ntohl(msg->amount);
443 entries = GNUNET_ntohll(msg->entries);
444 used = plugin->api->get_size (plugin->api->cls) + reserved;
445 req = amount + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * entries;
446 if (used + req > quota)
447 {
448 if (quota < used)
449 used = quota; /* cheat a bit */
450 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
451 _("Insufficient space (%llu bytes are available) to satisfy `%s' request for %llu bytes\n"),
452 quota - used,
453 "RESERVE",
454 req);
455 transmit_status (client, 0, gettext_noop ("Insufficient space to satisfy request"));
456 return;
457 }
458 reserved += req;
435 e = GNUNET_malloc (sizeof(struct ReservationList)); 459 e = GNUNET_malloc (sizeof(struct ReservationList));
436 e->next = reservations; 460 e->next = reservations;
437 reservations = e; 461 reservations = e;
438 e->client = client; 462 e->client = client;
439 e->amount = GNUNET_ntohll(msg->amount); 463 e->amount = amount;
440 e->entries = GNUNET_ntohll(msg->entries); 464 e->entries = entries;
441 e->rid = ++reservation_gen; 465 e->rid = ++reservation_gen;
442 if (reservation_gen < 0) 466 if (reservation_gen < 0)
443 reservation_gen = 0; /* wrap around */ 467 reservation_gen = 0; /* wrap around */
@@ -462,6 +486,7 @@ handle_release_reserve (void *cls,
462 struct ReservationList *prev; 486 struct ReservationList *prev;
463 struct ReservationList *next; 487 struct ReservationList *next;
464 int rid = ntohl(msg->rid); 488 int rid = ntohl(msg->rid);
489 unsigned long long rem;
465 490
466#if DEBUG_DATASTORE 491#if DEBUG_DATASTORE
467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 492 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -479,7 +504,14 @@ handle_release_reserve (void *cls,
479 reservations = next; 504 reservations = next;
480 else 505 else
481 prev->next = next; 506 prev->next = next;
482 /* FIXME: released remaining reserved space! */ 507 rem = pos->amount + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * pos->entries;
508 GNUNET_assert (reserved >= rem);
509 reserved -= rem;
510#if DEBUG_DATASTORE
511 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
512 "Returning %llu remaining reserved bytes to storage pool\n",
513 rem);
514#endif
483 GNUNET_free (pos); 515 GNUNET_free (pos);
484 transmit_status (client, GNUNET_OK, NULL); 516 transmit_status (client, GNUNET_OK, NULL);
485 return; 517 return;
@@ -487,7 +519,8 @@ handle_release_reserve (void *cls,
487 prev = pos; 519 prev = pos;
488 pos = next; 520 pos = next;
489 } 521 }
490 transmit_status (client, GNUNET_SYSERR, "Could not find matching reservation"); 522 GNUNET_break (0);
523 transmit_status (client, GNUNET_SYSERR, gettext_noop ("Could not find matching reservation"));
491} 524}
492 525
493 526
@@ -536,6 +569,8 @@ handle_put (void *cls,
536 char *msg; 569 char *msg;
537 int ret; 570 int ret;
538 int rid; 571 int rid;
572 struct ReservationList *pos;
573 uint32_t size;
539 574
540#if DEBUG_DATASTORE 575#if DEBUG_DATASTORE
541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 576 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -554,14 +589,27 @@ handle_put (void *cls,
554 return; 589 return;
555 } 590 }
556 rid = ntohl(dm->rid); 591 rid = ntohl(dm->rid);
592 size = ntohl(dm->size);
557 if (rid > 0) 593 if (rid > 0)
558 { 594 {
559 /* FIXME: find reservation, update remaining! */ 595 pos = reservations;
596 while ( (NULL != pos) &&
597 (rid != pos->rid) )
598 pos = pos->next;
599 GNUNET_break (pos != NULL);
600 if (NULL != pos)
601 {
602 GNUNET_break (pos->entries > 0);
603 GNUNET_break (pos->amount > size);
604 pos->entries--;
605 pos->amount -= size;
606 reserved -= (size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
607 }
560 } 608 }
561 msg = NULL; 609 msg = NULL;
562 ret = plugin->api->put (plugin->api->cls, 610 ret = plugin->api->put (plugin->api->cls,
563 &dm->key, 611 &dm->key,
564 ntohl(dm->size), 612 size,
565 &dm[1], 613 &dm[1],
566 ntohl(dm->type), 614 ntohl(dm->type),
567 ntohl(dm->priority), 615 ntohl(dm->priority),