gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r33521 - in gnunet/src: include peerstore


From: gnunet
Subject: [GNUnet-SVN] r33521 - in gnunet/src: include peerstore
Date: Wed, 4 Jun 2014 18:03:17 +0200

Author: otarabai
Date: 2014-06-04 18:03:17 +0200 (Wed, 04 Jun 2014)
New Revision: 33521

Modified:
   gnunet/src/include/gnunet_peerstore_plugin.h
   gnunet/src/include/gnunet_peerstore_service.h
   gnunet/src/peerstore/gnunet-service-peerstore.c
   gnunet/src/peerstore/peerstore.h
   gnunet/src/peerstore/peerstore_api.c
   gnunet/src/peerstore/peerstore_common.c
   gnunet/src/peerstore/peerstore_common.h
   gnunet/src/peerstore/plugin_peerstore_sqlite.c
   gnunet/src/peerstore/test_peerstore_api.c
Log:
peerstore: added 'replace' option and other fixes


Modified: gnunet/src/include/gnunet_peerstore_plugin.h
===================================================================
--- gnunet/src/include/gnunet_peerstore_plugin.h        2014-06-04 14:18:34 UTC 
(rev 33520)
+++ gnunet/src/include/gnunet_peerstore_plugin.h        2014-06-04 16:03:17 UTC 
(rev 33521)
@@ -68,7 +68,8 @@
       const char *key,
       const void *value,
       size_t size,
-      struct GNUNET_TIME_Absolute expiry);
+      struct GNUNET_TIME_Absolute expiry,
+      enum GNUNET_PEERSTORE_StoreOption options);
 
   /**
    * Iterate over the records given an optional peer id

Modified: gnunet/src/include/gnunet_peerstore_service.h
===================================================================
--- gnunet/src/include/gnunet_peerstore_service.h       2014-06-04 14:18:34 UTC 
(rev 33520)
+++ gnunet/src/include/gnunet_peerstore_service.h       2014-06-04 16:03:17 UTC 
(rev 33521)
@@ -38,6 +38,25 @@
 #endif
 
 /**
+ * Options for storing values in PEERSTORE
+ */
+enum GNUNET_PEERSTORE_StoreOption
+{
+
+  /**
+   * Possibly store multiple values under given key.
+   */
+  GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
+
+  /**
+   * Delete any previous values for the given key before
+   * storing the given value.
+   */
+  GNUNET_PEERSTORE_STOREOPTION_REPLACE,
+
+};
+
+/**
  * Handle to the peerstore service.
  */
 struct GNUNET_PEERSTORE_Handle;
@@ -130,7 +149,8 @@
  * @param key entry key
  * @param value entry value BLOB
  * @param size size of 'value'
- * @param lifetime relative time after which the entry is (possibly) deleted
+ * @param expiry absolute time after which the entry is (possibly) deleted
+ * @param options store operation option
  * @param cont Continuation function after the store request is processed
  * @param cont_cls Closure for 'cont'
  */
@@ -142,6 +162,7 @@
     const void *value,
     size_t size,
     struct GNUNET_TIME_Absolute expiry,
+    enum GNUNET_PEERSTORE_StoreOption options,
     GNUNET_PEERSTORE_Continuation cont,
     void *cont_cls);
 

Modified: gnunet/src/peerstore/gnunet-service-peerstore.c
===================================================================
--- gnunet/src/peerstore/gnunet-service-peerstore.c     2014-06-04 14:18:34 UTC 
(rev 33520)
+++ gnunet/src/peerstore/gnunet-service-peerstore.c     2014-06-04 16:03:17 UTC 
(rev 33521)
@@ -30,24 +30,6 @@
 #include "peerstore_common.h"
 
 /**
- * Context of a PEERSTORE watch
- */
-struct WatchContext
-{
-
-  /**
-   * Hash of key of watched record
-   */
-  struct GNUNET_HashCode keyhash;
-
-  /**
-   * Client requested the watch
-   */
-  struct GNUNET_SERVER_Client *client;
-
-};
-
-/**
  * Interval for expired records cleanup (in seconds)
  */
 #define CLEANUP_INTERVAL 300 /* 5mins */
@@ -95,6 +77,7 @@
   }
   GNUNET_SERVER_notification_context_destroy(nc);
   GNUNET_CONTAINER_multihashmap_destroy(watchers);
+  watchers = NULL;
   GNUNET_SCHEDULER_shutdown();
 }
 
@@ -123,7 +106,7 @@
  * @param cls closuer, a 'struct GNUNET_PEERSTORE_Record *'
  * @param key hash of record key
  * @param value the watcher client, a 'struct GNUNET_SERVER_Client *'
- * @return #GNUNET_YES to continue iterating
+ * @return #GNUNET_OK to continue iterating
  */
 int client_disconnect_it(void *cls,
     const struct GNUNET_HashCode *key,
@@ -131,7 +114,7 @@
 {
   if(cls == value)
     GNUNET_CONTAINER_multihashmap_remove(watchers, key, value);
-  return GNUNET_YES;
+  return GNUNET_OK;
 }
 
 /**
@@ -146,8 +129,9 @@
                          * client)
 {
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "A client was disconnected, cleaning 
up.\n");
-  GNUNET_CONTAINER_multihashmap_iterate(watchers,
-      &client_disconnect_it, client);
+  if(NULL != watchers)
+    GNUNET_CONTAINER_multihashmap_iterate(watchers,
+        &client_disconnect_it, client);
 }
 
 /**
@@ -196,12 +180,6 @@
   struct StoreRecordMessage *srm;
 
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Found a watcher to update.\n");
-  if(NULL == client)
-  {
-    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Removing a dead client.\n");
-    GNUNET_CONTAINER_multihashmap_remove(watchers, key, client);
-    return GNUNET_YES;
-  }
   srm = PEERSTORE_create_record_message(record->sub_system,
       record->peer,
       record->key,
@@ -335,6 +313,7 @@
     const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_PEERSTORE_Record *record;
+  struct StoreRecordMessage *srm;
 
   record = PEERSTORE_parse_record_message(message);
   if(NULL == record)
@@ -343,6 +322,7 @@
     GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
     return;
   }
+  srm = (struct StoreRecordMessage *)message;
   if(NULL == record->sub_system
       || NULL == record->peer
       || NULL == record->key)
@@ -363,7 +343,8 @@
       record->key,
       record->value,
       record->value_size,
-      *record->expiry))
+      *record->expiry,
+      srm->options))
   {
     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to store requested value, 
sqlite database error.");
     PEERSTORE_destroy_record(record);

Modified: gnunet/src/peerstore/peerstore.h
===================================================================
--- gnunet/src/peerstore/peerstore.h    2014-06-04 14:18:34 UTC (rev 33520)
+++ gnunet/src/peerstore/peerstore.h    2014-06-04 16:03:17 UTC (rev 33521)
@@ -75,6 +75,12 @@
    */
   struct GNUNET_TIME_Absolute expiry;
 
+  /**
+   * Options, needed only in case of a
+   * store operation
+   */
+  enum GNUNET_PEERSTORE_StoreOption options;
+
 };
 
 /**

Modified: gnunet/src/peerstore/peerstore_api.c
===================================================================
--- gnunet/src/peerstore/peerstore_api.c        2014-06-04 14:18:34 UTC (rev 
33520)
+++ gnunet/src/peerstore/peerstore_api.c        2014-06-04 16:03:17 UTC (rev 
33521)
@@ -419,6 +419,7 @@
     const void *value,
     size_t size,
     struct GNUNET_TIME_Absolute expiry,
+    enum GNUNET_PEERSTORE_StoreOption options,
     GNUNET_PEERSTORE_Continuation cont,
     void *cont_cls)
 {
@@ -434,6 +435,7 @@
       value,
       size,
       &expiry,
+      options,
       GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
   sc = GNUNET_new(struct GNUNET_PEERSTORE_StoreContext);
   sc->ev = ev;
@@ -595,6 +597,7 @@
       NULL,
       0,
       NULL,
+      0,
       GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE);
   ic = GNUNET_new(struct GNUNET_PEERSTORE_IterateContext);
   ic->callback = callback;

Modified: gnunet/src/peerstore/peerstore_common.c
===================================================================
--- gnunet/src/peerstore/peerstore_common.c     2014-06-04 14:18:34 UTC (rev 
33520)
+++ gnunet/src/peerstore/peerstore_common.c     2014-06-04 16:03:17 UTC (rev 
33521)
@@ -137,6 +137,7 @@
     const void *value,
     size_t value_size,
     struct GNUNET_TIME_Absolute *expiry,
+    enum GNUNET_PEERSTORE_StoreOption options,
     uint16_t msg_type)
 {
   struct StoreRecordMessage *srm;
@@ -168,6 +169,7 @@
   }
   srm->sub_system_size = htons(ss_size);
   srm->value_size = htons(value_size);
+  srm->options = options;
   dummy = &srm[1];
   memcpy(dummy, sub_system, ss_size);
   dummy += ss_size;

Modified: gnunet/src/peerstore/peerstore_common.h
===================================================================
--- gnunet/src/peerstore/peerstore_common.h     2014-06-04 14:18:34 UTC (rev 
33520)
+++ gnunet/src/peerstore/peerstore_common.h     2014-06-04 16:03:17 UTC (rev 
33521)
@@ -76,6 +76,7 @@
     const void *value,
     size_t value_size,
     struct GNUNET_TIME_Absolute *expiry,
+    enum GNUNET_PEERSTORE_StoreOption options,
     uint16_t msg_type);
 
 /**

Modified: gnunet/src/peerstore/plugin_peerstore_sqlite.c
===================================================================
--- gnunet/src/peerstore/plugin_peerstore_sqlite.c      2014-06-04 14:18:34 UTC 
(rev 33520)
+++ gnunet/src/peerstore/plugin_peerstore_sqlite.c      2014-06-04 16:03:17 UTC 
(rev 33521)
@@ -100,13 +100,58 @@
   sqlite3_stmt *select_peerstoredata_by_all;
 
   /**
-   * Precompiled SQL for deleting expired records from peerstoredata
+   * Precompiled SQL for deleting expired
+   * records from peerstoredata
    */
   sqlite3_stmt *expire_peerstoredata;
 
+  /**
+   * Precompiled SQL for deleting records
+   * with given key
+   */
+  sqlite3_stmt *delete_peerstoredata;
+
 };
 
 /**
+ * Delete records with the given key
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param sub_system name of sub system
+ * @param peer Peer identity (can be NULL)
+ * @param key entry key string (can be NULL)
+ * @return number of deleted records
+ */
+static int
+peerstore_sqlite_delete_records(void *cls,
+    const char *sub_system,
+    const struct GNUNET_PeerIdentity *peer,
+    const char *key)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->delete_peerstoredata;
+
+  if((SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 
1, SQLITE_STATIC))
+      || (SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct 
GNUNET_PeerIdentity), SQLITE_STATIC))
+      || (SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, 
SQLITE_STATIC)))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 
"sqlite3_bind");
+  }
+  else if (SQLITE_DONE != sqlite3_step (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "sqlite3_step");
+  }
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "sqlite3_reset");
+    return 0;
+  }
+  return sqlite3_changes(plugin->dbh);
+}
+
+/**
  * Delete expired records (expiry < now)
  *
  * @param cls closure (internal context for the plugin)
@@ -120,7 +165,7 @@
   struct Plugin *plugin = cls;
   sqlite3_stmt *stmt = plugin->expire_peerstoredata;
 
-  if(SQLITE_OK != sqlite3_bind_int64(stmt, 1, (sqlite3_int64)now.abs_value_us))
+  if(SQLITE_OK != sqlite3_bind_int64(stmt, 1, 
(sqlite3_uint64)now.abs_value_us))
   {
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 
"sqlite3_bind");
   }
@@ -254,16 +299,21 @@
     const char *key,
     const void *value,
     size_t size,
-    struct GNUNET_TIME_Absolute expiry)
+    struct GNUNET_TIME_Absolute expiry,
+    enum GNUNET_PEERSTORE_StoreOption options)
 {
   struct Plugin *plugin = cls;
   sqlite3_stmt *stmt = plugin->insert_peerstoredata;
 
+  if(GNUNET_PEERSTORE_STOREOPTION_REPLACE == options)
+  {
+    peerstore_sqlite_delete_records(cls, sub_system, peer, key);
+  }
   if(SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 
1, SQLITE_STATIC)
       || SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct 
GNUNET_PeerIdentity), SQLITE_STATIC)
       || SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, 
SQLITE_STATIC)
       || SQLITE_OK != sqlite3_bind_blob(stmt, 4, value, size, SQLITE_STATIC)
-      || SQLITE_OK != sqlite3_bind_int64(stmt, 5, 
(sqlite3_int64)expiry.abs_value_us))
+      || SQLITE_OK != sqlite3_bind_int64(stmt, 5, 
(sqlite3_uint64)expiry.abs_value_us))
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                     "sqlite3_bind");
   else if (SQLITE_DONE != sqlite3_step (stmt))
@@ -330,6 +380,21 @@
 }
 
 /**
+ * sqlite3 custom function for comparison of uint64_t values
+ * since it is not supported by default
+ */
+void sqlite3_lessthan(sqlite3_context* ctx, int dummy,
+    sqlite3_value** values)
+{
+  uint64_t v1;
+  uint64_t v2;
+
+  v1 = (uint64_t)sqlite3_value_int64(values[0]);
+  v2 = (uint64_t)sqlite3_value_int64(values[1]);
+  sqlite3_result_int(ctx, v1 < v2);
+}
+
+/**
  * Initialize the database connections and associated
  * data structures (create tables and indices
  * as needed as well).
@@ -389,9 +454,11 @@
       "  peer_id BLOB NOT NULL,\n"
       "  key TEXT NOT NULL,\n"
       "  value BLOB NULL,\n"
-      "  expiry INTEGER NOT NULL"
+      "  expiry sqlite3_uint64 NOT NULL"
       ");");
 
+  sqlite3_create_function(plugin->dbh, "UINT64_LT", 2, SQLITE_UTF8, NULL, 
&sqlite3_lessthan, NULL, NULL);
+
   /* Prepare statements */
 
   sql_prepare (plugin->dbh,
@@ -419,8 +486,14 @@
       &plugin->select_peerstoredata_by_all);
   sql_prepare(plugin->dbh,
       "DELETE FROM peerstoredata"
-      " WHERE expiry < ?",
+      " WHERE UINT64_LT(expiry, ?)",
       &plugin->expire_peerstoredata);
+  sql_prepare(plugin->dbh,
+      "DELETE FROM peerstoredata"
+      " WHERE sub_system = ?"
+      " AND peer_id = ?"
+      " AND key = ?",
+      &plugin->delete_peerstoredata);
 
   return GNUNET_OK;
 }

Modified: gnunet/src/peerstore/test_peerstore_api.c
===================================================================
--- gnunet/src/peerstore/test_peerstore_api.c   2014-06-04 14:18:34 UTC (rev 
33520)
+++ gnunet/src/peerstore/test_peerstore_api.c   2014-06-04 16:03:17 UTC (rev 
33521)
@@ -125,6 +125,7 @@
       val,
       val_size,
       expiry,
+      GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
       &store_cont,
       NULL);
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]