dstore.c
来自「GNUnet是一个安全的点对点网络框架」· C语言 代码 · 共 645 行 · 第 1/2 页
C
645 行
if ((SQLITE_OK != sqlite3_bind_blob (stmt, 1, key, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT)) || (SQLITE_OK != sqlite3_bind_blob (stmt, 2, &vhash, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT)) || (SQLITE_OK != sqlite3_bind_int (stmt, 3, type)) || (SQLITE_OK != sqlite3_bind_int (stmt, 4, size))) { GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK, _("`%s' failed at %s:%d with error: %s\n"), "sqlite3_bind_xxx", __FILE__, __LINE__, sqlite3_errmsg (dbh)); sqlite3_finalize (stmt); sqlite3_close (dbh); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } if (SQLITE_DONE != sqlite3_step (stmt)) { GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK, _("`%s' failed at %s:%d with error: %s\n"), "sqlite3_step", __FILE__, __LINE__, sqlite3_errmsg (dbh)); sqlite3_finalize (stmt); sqlite3_close (dbh); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } ret = sqlite3_changes (dbh); sqlite3_finalize (stmt); if (ret > 0) { sqlite3_close (dbh); GNUNET_mutex_unlock (lock); return GNUNET_OK; } if (GNUNET_OK != checkQuota (dbh)) { sqlite3_close (dbh); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } if (sq_prepare (dbh, "INSERT INTO ds080 " "(size, type, puttime, expire, key, vhash, value) " "VALUES (?, ?, ?, ?, ?, ?, ?)", &stmt) != SQLITE_OK) { GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK, _("`%s' failed at %s:%d with error: %s\n"), "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (dbh)); sqlite3_close (dbh); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } if ((SQLITE_OK == sqlite3_bind_int (stmt, 1, size)) && (SQLITE_OK == sqlite3_bind_int (stmt, 2, type)) && (SQLITE_OK == sqlite3_bind_int64 (stmt, 3, GNUNET_get_time ())) && (SQLITE_OK == sqlite3_bind_int64 (stmt, 4, discard_time)) && (SQLITE_OK == sqlite3_bind_blob (stmt, 5, key, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT)) && (SQLITE_OK == sqlite3_bind_blob (stmt, 6, &vhash, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT)) && (SQLITE_OK == sqlite3_bind_blob (stmt, 7, data, size, SQLITE_TRANSIENT))) { if (SQLITE_DONE != sqlite3_step (stmt)) { LOG_SQLITE (dbh, GNUNET_GE_ERROR | GNUNET_GE_DEVELOPER | GNUNET_GE_ADMIN | GNUNET_GE_BULK, "sqlite3_step"); } else { payload += size + OVERHEAD; if (bloom != NULL) GNUNET_bloomfilter_add (bloom, key); } if (SQLITE_OK != sqlite3_finalize (stmt)) LOG_SQLITE (dbh, GNUNET_GE_ERROR | GNUNET_GE_DEVELOPER | GNUNET_GE_ADMIN | GNUNET_GE_BULK, "sqlite3_finalize"); } else { LOG_SQLITE (dbh, GNUNET_GE_ERROR | GNUNET_GE_DEVELOPER | GNUNET_GE_ADMIN | GNUNET_GE_BULK, "sqlite3_bind_xxx"); }#if DEBUG_DSTORE GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_DEVELOPER, "Storing %u bytes increases DStore payload to %llu out of %llu\n", size, payload, quota);#endif checkQuota (dbh); sqlite3_close (dbh); GNUNET_mutex_unlock (lock); if (stats != NULL) stats->set (stat_dstore_size, payload); return GNUNET_OK;}/** * Iterate over the results for a particular key * in the datastore. * * @param key * @param type entries of which type are relevant? * @param iter maybe NULL (to just count) * @return the number of results, GNUNET_SYSERR if the * iter is non-NULL and aborted the iteration */static intd_get (const GNUNET_HashCode * key, unsigned int type, GNUNET_ResultProcessor handler, void *closure){ sqlite3 *dbh; sqlite3_stmt *stmt; GNUNET_CronTime now; unsigned int size; const char *dat; unsigned int cnt; unsigned int off; unsigned int total; char scratch[256]; GNUNET_mutex_lock (lock); if ((bloom != NULL) && (GNUNET_NO == GNUNET_bloomfilter_test (bloom, key))) { GNUNET_mutex_unlock (lock); return 0; } if ((fn == NULL) || (SQLITE_OK != sqlite3_open (fn, &dbh))) { db_reset (dbh); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; }#if DEBUG_DSTORE GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_DEVELOPER, "dstore processes get\n");#endif now = GNUNET_get_time (); if (sq_prepare (dbh, "SELECT count(*) FROM ds080 WHERE key=? AND type=? AND expire >= ?", &stmt) != SQLITE_OK) { GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK, _("`%s' failed at %s:%d with error: %s\n"), "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (dbh)); sqlite3_close (dbh); db_reset (dbh); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } sqlite3_bind_blob (stmt, 1, key, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT); sqlite3_bind_int (stmt, 2, type); sqlite3_bind_int (stmt, 3, now); if (SQLITE_ROW != sqlite3_step (stmt)) { LOG_SQLITE (dbh, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "sqlite_step"); sqlite3_reset (stmt); sqlite3_finalize (stmt); db_reset (dbh); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } total = sqlite3_column_int (stmt, 0); sqlite3_reset (stmt); sqlite3_finalize (stmt); if ((total == 0) || (handler == NULL)) { sqlite3_close (dbh); GNUNET_mutex_unlock (lock); return total; } cnt = 0; off = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, total); while (cnt < total) { off = (off + 1) % total; GNUNET_snprintf (scratch, 256, "SELECT size, value FROM ds080 WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET %u", off); if (sq_prepare (dbh, scratch, &stmt) != SQLITE_OK) { GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK, _("`%s' failed at %s:%d with error: %s\n"), "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (dbh)); sqlite3_close (dbh); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } sqlite3_bind_blob (stmt, 1, key, sizeof (GNUNET_HashCode), SQLITE_TRANSIENT); sqlite3_bind_int (stmt, 2, type); sqlite3_bind_int (stmt, 3, now); if (sqlite3_step (stmt) != SQLITE_ROW) break; size = sqlite3_column_int (stmt, 0); if (size != sqlite3_column_bytes (stmt, 1)) { GNUNET_GE_BREAK (NULL, 0); sqlite3_finalize (stmt); continue; } dat = sqlite3_column_blob (stmt, 1); cnt++;#if DEBUG_DSTORE GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_DEVELOPER, "dstore found result for get: `%.*s\n", size, dat);#endif if ((handler != NULL) && (GNUNET_OK != handler (key, type, size, dat, closure))) { sqlite3_finalize (stmt); break; } sqlite3_finalize (stmt); } sqlite3_close (dbh); GNUNET_mutex_unlock (lock); return cnt;}GNUNET_Dstore_ServiceAPI *provide_module_dstore_sqlite (GNUNET_CoreAPIForPlugins * capi){ static GNUNET_Dstore_ServiceAPI api; int fd;#if DEBUG_SQLITE GNUNET_GE_LOG (capi->ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "SQLite Dstore: initializing database\n");#endif coreAPI = capi; if (GNUNET_OK != db_reset ()) { GNUNET_GE_BREAK (capi->ectx, 0); return NULL; } lock = GNUNET_mutex_create (GNUNET_NO); api.get = &d_get; api.put = &d_put; GNUNET_GC_get_configuration_value_number (coreAPI->cfg, "DSTORE", "QUOTA", 1, 1024, 1, "a); if (quota == 0) /* error */ quota = 1; quota *= 1024 * 1024; bloom_name = GNUNET_strdup ("/tmp/dbloomXXXXXX"); fd = mkstemp (bloom_name); if (fd != -1) { bloom = GNUNET_bloomfilter_load (coreAPI->ectx, bloom_name, quota / (OVERHEAD + 1024), /* 8 bit per entry in DB, expect 1k entries */ 5); CLOSE (fd); } stats = capi->service_request ("stats"); if (stats != NULL) { stat_dstore_size = stats->create (gettext_noop ("# bytes in dstore")); stat_dstore_quota = stats->create (gettext_noop ("# max bytes allowed in dstore")); stats->set (stat_dstore_quota, quota); } return &api;}/** * Shutdown the module. */voidrelease_module_dstore_sqlite (){ UNLINK (fn); GNUNET_free (fn); fn = NULL; if (bloom != NULL) { GNUNET_bloomfilter_free (bloom); bloom = NULL; } UNLINK (bloom_name); GNUNET_free (bloom_name); bloom_name = NULL; if (stats != NULL) { coreAPI->service_release (stats); stats = NULL; }#if DEBUG_SQLITE GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "SQLite Dstore: database shutdown\n");#endif GNUNET_mutex_destroy (lock); coreAPI = NULL;}/* end of dstore.c */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?