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,                                            &quota);  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 + -
显示快捷键?