📄 datastore.c
字号:
GNUNET_free (nvalue); if (ok == GNUNET_YES) { makeAvailable (key); available -= ntohl (value->size); } GNUNET_mutex_unlock (lock); return ok;}/** * @return *closure if we are below quota, * GNUNET_SYSERR if we have deleted all of the expired content * (or if we should briefly stop doing this to give * other work a chance to progress) * GNUNET_OK if we deleted expired content and are above quota */static intfreeSpaceExpired (const GNUNET_HashCode * key, const GNUNET_DatastoreValue * value, void *closure, unsigned long long uid){ GNUNET_CronTime * start = closure; GNUNET_CronTime now; now = GNUNET_get_time(); if ( (now - *start > MAINTENANCE_FREQUENCY / 2) || (GNUNET_get_time () < GNUNET_ntohll (value->expiration_time)) ) return GNUNET_SYSERR; /* not expired */ available += ntohl (value->size); minPriority = 0; return GNUNET_NO;}static intfreeSpaceLow (const GNUNET_HashCode * key, const GNUNET_DatastoreValue * value, void *closure, unsigned long long uid){ if ((available > 0) && (available >= MIN_GNUNET_free)) return GNUNET_SYSERR; if (ntohl (value->priority) > minPriority) minPriority = ntohl (value->priority); available += ntohl (value->size); return GNUNET_NO;}/** * Cron-job that deletes low-priority/expired content * if we are about to run out of space. * * Also updates available and minPriority. */static voidcronMaintenance (void *unused){ GNUNET_CronTime now = GNUNET_get_time(); available = quota - sq->getSize (); sq->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY, &freeSpaceExpired, &now); if ((available < 0) || (available < MIN_GNUNET_free)) sq->iterateLowPriority (GNUNET_ECRS_BLOCKTYPE_ANY, &freeSpaceLow, NULL);}/** * Initialize the manager-module. */GNUNET_Datastore_ServiceAPI *provide_module_datastore (GNUNET_CoreAPIForPlugins * capi){ static GNUNET_Datastore_ServiceAPI api; unsigned long long lquota; unsigned long long sqot; GNUNET_State_ServiceAPI *state; struct stat sbuf; char *fsdir; if (-1 == GNUNET_GC_get_configuration_value_number (capi->cfg, "FS", "QUOTA", 0, ((unsigned long long) -1) / 1024 / 1024, 1024, &lquota)) { GNUNET_GE_BREAK (capi->ectx, 0); return NULL; /* OOPS */ } quota = lquota * 1024 * 1024; /* MB to bytes */ stats = capi->service_request ("stats"); if (stats != NULL) { stat_filtered = stats->create (gettext_noop ("# requests filtered by bloom filter")); stat_filter_failed = stats->create (gettext_noop ("# bloom filter false positives")); stats->set (stats-> create (gettext_noop ("# bytes allowed in datastore")), quota); } state = capi->service_request ("state"); if (state != NULL) { sqot = GNUNET_htonll (lquota); state->write (capi->ectx, "FS-LAST-QUOTA", sizeof (unsigned long long), &sqot); capi->service_release (state); } else { GNUNET_GE_LOG (capi->ectx, GNUNET_GE_USER | GNUNET_GE_ADMIN | GNUNET_GE_ERROR | GNUNET_GE_BULK, _ ("Failed to load state service. Trying to do without.\n")); } sq = capi->service_request ("sqstore"); if (sq == NULL) { if (stats != NULL) { capi->service_release (stats); stats = NULL; } GNUNET_GE_BREAK (capi->ectx, 0); return NULL; } coreAPI = capi; initPrefetch (capi->ectx, capi->cfg, sq); if (GNUNET_OK != initFilters (capi->ectx, capi->cfg)) { GNUNET_GE_BREAK (capi->ectx, 0); donePrefetch (); capi->service_release (sq); if (stats != NULL) { capi->service_release (stats); stats = NULL; } return NULL; } lock = GNUNET_mutex_create (GNUNET_NO); fsdir = NULL; GNUNET_GC_get_configuration_value_filename (capi->cfg, "FS", "DIR", GNUNET_DEFAULT_DAEMON_VAR_DIRECTORY "/data/fs/", &fsdir); /* just in case dir does not exist ... */ GNUNET_disk_directory_create (NULL, fsdir); if (0 == STAT (fsdir, &sbuf)) db_creation_time = sbuf.st_ctime; GNUNET_free (fsdir); available = quota - sq->getSize (); cron = GNUNET_cron_create (capi->ectx); GNUNET_cron_add_job (cron, &cronMaintenance, MAINTENANCE_FREQUENCY, MAINTENANCE_FREQUENCY, NULL); GNUNET_cron_start (cron); api.getSize = &getSize; api.fast_get = &testAvailable; api.putUpdate = &putUpdate; api.get = &get; api.getRandom = &getRandom; /* in prefetch.c */ api.del = &del; return &api;}/** * Shutdown the manager module. */voidrelease_module_datastore (){ GNUNET_cron_stop (cron); GNUNET_cron_del_job (cron, &cronMaintenance, MAINTENANCE_FREQUENCY, NULL); GNUNET_cron_destroy (cron); cron = NULL; donePrefetch (); doneFilters (); coreAPI->service_release (sq); if (stats != NULL) { coreAPI->service_release (stats); stats = NULL; } GNUNET_mutex_destroy (lock); sq = NULL; coreAPI = NULL;}struct FAAProgressInfo{ unsigned long long pos; unsigned long long total; GNUNET_CronTime start;};/** * Callback that adds all element of the SQStore to the * bloomfilter. */static intfilterAddAll (const GNUNET_HashCode * key, const GNUNET_DatastoreValue * value, void *closure, unsigned long long uid){ struct FAAProgressInfo *pi = closure; unsigned int pct_old; unsigned int pct; makeAvailable (key); pct_old = (100 * pi->pos) / pi->total; pi->pos += ntohl (value->size); pct = (100 * pi->pos) / pi->total; if (pct != pct_old) { fprintf (stdout, _("Datastore conversion at approximately %u%%\n"), pct); } return GNUNET_OK;}/** * Update Datastore. Currently only re-builds the bloomfilter. * At some point we'll want to add code to convert data between * different sqstore's here, too. */voidupdate_module_datastore (GNUNET_UpdateAPI * uapi){ unsigned long long quota; unsigned long long lastQuota; unsigned long long *lq; GNUNET_State_ServiceAPI *state; struct FAAProgressInfo pi; if (-1 == GNUNET_GC_get_configuration_value_number (uapi->cfg, "FS", "QUOTA", 0, ((unsigned long long) -1) / 1024 / 1024, 1024, "a)) return; /* OOPS */ state = uapi->service_request ("state"); lq = NULL; if ((state != NULL) && (sizeof (unsigned long long) == state->read (uapi->ectx, "FS-LAST-QUOTA", (void **) &lq)) && (GNUNET_ntohll (*lq) == quota)) { uapi->service_release (state); GNUNET_free (lq); return; /* no change */ } /* ok, need to convert! */ deleteFilter (uapi->ectx, uapi->cfg); initFilters (uapi->ectx, uapi->cfg); sq = uapi->service_request ("sqstore"); if (sq != NULL) { fprintf (stdout, _("Starting datastore conversion (this may take a while).\n")); pi.start = GNUNET_get_time (); pi.pos = 0; pi.total = (lq != NULL) ? GNUNET_ntohll (*lq) : 0; if (pi.total == 0) pi.total = 1; sq->iterateAllNow (&filterAddAll, &pi); uapi->service_release (sq); fprintf (stdout, _("Completed datastore conversion.\n")); } else { GNUNET_GE_LOG (uapi->ectx, GNUNET_GE_USER | GNUNET_GE_ADMIN | GNUNET_GE_ERROR | GNUNET_GE_BULK, _ ("Failed to load sqstore service. Check your configuration!\n")); } GNUNET_free_non_null (lq); sq = NULL; doneFilters (); if (state != NULL) { lastQuota = GNUNET_htonll (quota); state->write (uapi->ectx, "FS-LAST-QUOTA", sizeof (unsigned long long), &lastQuota); uapi->service_release (state); }}/* end of datastore.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -