[tracker/tracker-store-batch: 1/3] trackerd: Add simple batch update support



commit 310e8e8a334fcad119c8119c0b51d8357828d86d
Author: Jürg Billeter <j bitron ch>
Date:   Tue May 12 17:58:21 2009 +0200

    trackerd: Add simple batch update support
---
 data/dbus/tracker-resources.xml  |   15 ++++++-
 src/trackerd/tracker-resources.c |   94 ++++++++++++++++++++++++++++++++++++++
 src/trackerd/tracker-resources.h |    7 +++
 3 files changed, 115 insertions(+), 1 deletions(-)

diff --git a/data/dbus/tracker-resources.xml b/data/dbus/tracker-resources.xml
index 233fc64..a5ffece 100644
--- a/data/dbus/tracker-resources.xml
+++ b/data/dbus/tracker-resources.xml
@@ -34,11 +34,24 @@
       <arg type="aas" name="result" direction="out" />
     </method>
 
-    <!-- SPARQL Update extensions, allows bulk insert and delete -->
+    <!-- SPARQL Update extensions, insert and delete -->
     <method name="SparqlUpdate">
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
       <arg type="s" name="query" direction="in" />
     </method>
 
+    <!-- SPARQL Update as part of a batch, use this method when sending a
+         possibly large amount of updates to improve performance, may delay
+         database commit until receiving BatchCommit -->
+    <method name="BatchSparqlUpdate">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="s" name="query" direction="in" />
+    </method>
+
+    <!-- Commits pending updates to the database -->
+    <method name="BatchCommit">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+    </method>
+
   </interface>
 </node>
diff --git a/src/trackerd/tracker-resources.c b/src/trackerd/tracker-resources.c
index fdb29dd..783162d 100644
--- a/src/trackerd/tracker-resources.c
+++ b/src/trackerd/tracker-resources.c
@@ -45,12 +45,17 @@
 #define RDF_PREFIX TRACKER_RDF_PREFIX
 #define RDF_TYPE RDF_PREFIX "type"
 
+/* Transaction every 'x' batch items */
+#define TRACKER_STORE_TRANSACTION_MAX	4000
+
 G_DEFINE_TYPE(TrackerResources, tracker_resources, G_TYPE_OBJECT)
 
 #define TRACKER_RESOURCES_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_RESOURCES, TrackerResourcesPrivate))
 
 
 typedef struct {
+	gboolean    batch_mode;
+	gint        batch_count;
 	GSList     *event_sources;
 } TrackerResourcesPrivate;
 
@@ -254,13 +259,23 @@ tracker_resources_sparql_update (TrackerResources	 *self,
 				 DBusGMethodInvocation	 *context,
 				 GError			**error)
 {
+	TrackerResourcesPrivate *priv;
 	GError 		     *actual_error = NULL;
 	guint		      request_id;
 
+	priv = TRACKER_RESOURCES_GET_PRIVATE (self);
+
 	request_id = tracker_dbus_get_next_request_id ();
 
 	tracker_dbus_async_return_if_fail (update != NULL, context);
 
+	if (priv->batch_mode) {
+		/* commit pending batch items */
+		tracker_data_commit_transaction ();
+		priv->batch_mode = FALSE;
+		priv->batch_count = 0;
+	}
+
 	tracker_dbus_request_new (request_id,
 				  "DBus request for SPARQL Update, "
 				  "update:'%s'",
@@ -282,6 +297,85 @@ tracker_resources_sparql_update (TrackerResources	 *self,
 	tracker_dbus_request_success (request_id);
 }
 
+void
+tracker_resources_batch_sparql_update (TrackerResources          *self,
+				       const gchar	         *update,
+				       DBusGMethodInvocation	 *context,
+				       GError			**error)
+{
+	TrackerResourcesPrivate *priv;
+	GError 		     *actual_error = NULL;
+	guint		      request_id;
+
+	priv = TRACKER_RESOURCES_GET_PRIVATE (self);
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (update != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request for batch SPARQL Update, "
+				  "update:'%s'",
+				  update);
+
+	if (!priv->batch_mode) {
+		/* switch to batch mode
+		   delays database commits to improve performance */
+		priv->batch_mode = TRUE;
+		priv->batch_count = 0;
+		tracker_data_begin_transaction ();
+	}
+
+	tracker_data_update_sparql (update, &actual_error);
+
+	if (actual_error) {
+		tracker_dbus_request_failed (request_id,
+					     &actual_error,
+					     NULL);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	if (++priv->batch_count >= TRACKER_STORE_TRANSACTION_MAX) {
+		/* commit pending batch items */
+		tracker_data_commit_transaction ();
+		priv->batch_mode = FALSE;
+		priv->batch_count = 0;
+	}
+
+	dbus_g_method_return (context);
+
+	tracker_dbus_request_success (request_id);
+}
+
+void
+tracker_resources_batch_commit (TrackerResources	 *self,
+				DBusGMethodInvocation	 *context,
+				GError			**error)
+{
+	TrackerResourcesPrivate *priv;
+	guint		      request_id;
+
+	priv = TRACKER_RESOURCES_GET_PRIVATE (self);
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request for batch commit");
+
+	if (priv->batch_mode) {
+		/* commit pending batch items */
+		tracker_data_commit_transaction ();
+		priv->batch_mode = FALSE;
+		priv->batch_count = 0;
+	}
+
+	dbus_g_method_return (context);
+
+	tracker_dbus_request_success (request_id);
+}
+
 
 static void
 on_statements_committed (gpointer user_data)
diff --git a/src/trackerd/tracker-resources.h b/src/trackerd/tracker-resources.h
index a50d4ef..c102926 100644
--- a/src/trackerd/tracker-resources.h
+++ b/src/trackerd/tracker-resources.h
@@ -79,6 +79,13 @@ void		 tracker_resources_sparql_update	 (TrackerResources       *object,
 							  const gchar		 *update,
 							  DBusGMethodInvocation  *context,
 							  GError		**error);
+void		 tracker_resources_batch_sparql_update	 (TrackerResources       *object,
+							  const gchar		 *update,
+							  DBusGMethodInvocation  *context,
+							  GError		**error);
+void		 tracker_resources_batch_commit		 (TrackerResources       *object,
+							  DBusGMethodInvocation  *context,
+							  GError		**error);
 
 
 G_END_DECLS



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