diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-07-21 23:20:36 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-07-21 23:20:36 +0000 |
commit | c8a0595aee76d863605801d76589e83926693ca7 (patch) | |
tree | 63640c2a03601ce8b1fb5797b23f55e99bc32aeb /src/datastore/gnunet-service-datastore.c | |
parent | 050ce82c79ef540b308a2bcee7514dd563fc5795 (diff) | |
download | gnunet-c8a0595aee76d863605801d76589e83926693ca7.tar.gz gnunet-c8a0595aee76d863605801d76589e83926693ca7.zip |
reservations
Diffstat (limited to 'src/datastore/gnunet-service-datastore.c')
-rw-r--r-- | src/datastore/gnunet-service-datastore.c | 68 |
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 | */ |
135 | static unsigned long long quota; | 134 | static unsigned long long quota; |
136 | 135 | ||
136 | /** | ||
137 | * How much space have we currently reserved? | ||
138 | */ | ||
139 | static 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 | */ |
421 | static void | 425 | static void |
422 | handle_reserve (void *cls, | 426 | handle_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), |