[tracker/wip/carlosg/resource-leak-fix: 5/5] libtracker-data: Perform trimming of unused resource URNs on shutdown



commit 4e8359a0bd710b4cf3e64d966b26f5987683d60d
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Jul 5 11:05:33 2017 +0200

    libtracker-data: Perform trimming of unused resource URNs on shutdown
    
    On shutdown it will now delete all elements in the Resource table that
    are not contained too in the Graph table (thus are graph URNs) and have
    a refcounting of 0 (meaning that they are not used in any class/property
    table).
    
    As the migration to refcounted Resource table doesn't result in graph
    URNs being added to the Graph table, database cleanup won't be performed
    until the Graph table has been populated (presumably by miners indexing
    anything)

 src/libtracker-data/tracker-data-manager.c |   61 ++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 98f732a..5eaf7b1 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -4742,10 +4742,71 @@ skip_ontology_check:
        return TRUE;
 }
 
+static guint
+data_manager_get_graph_count (TrackerDataManager *manager)
+{
+       TrackerDBStatement *stmt;
+       TrackerDBInterface *iface;
+       TrackerDBCursor *cursor;
+       guint count = 0;
+
+       iface = tracker_db_manager_get_writable_db_interface (manager->db_manager);
+       stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE,
+                                                     NULL, "SELECT COUNT(*) FROM Graph");
+       if (stmt) {
+               cursor = tracker_db_statement_start_cursor (stmt, NULL);
+               g_object_unref (stmt);
+       }
+
+       if (cursor && tracker_db_cursor_iter_next (cursor, NULL, NULL))
+               count = tracker_db_cursor_get_int (cursor, 0);
+
+       g_clear_object (&cursor);
+
+       return count;
+}
+
 void
 tracker_data_manager_dispose (GObject *object)
 {
        TrackerDataManager *manager = TRACKER_DATA_MANAGER (object);
+       TrackerDBStatement *stmt;
+       TrackerDBInterface *iface;
+       GError *error = NULL;
+       gboolean readonly;
+
+       readonly = (tracker_db_manager_get_flags (manager->db_manager, NULL, NULL) & 
TRACKER_DB_MANAGER_READONLY) == 0;
+
+       /* We need to be sure the data is coherent, so we'll refrain from doing
+        * any clean ups till there are elements in the Graph table.
+        *
+        * A database that's been freshly updated to the refcounted
+        * resources will have an empty Graph table, so we might unintentionally
+        * delete graph URNs if we clean up in this state.
+        */
+       if (!readonly && data_manager_get_graph_count (manager) > 0) {
+               /* Delete stale URIs in the Resource table */
+               g_debug ("Cleaning up stale resource URIs");
+
+               iface = tracker_db_manager_get_writable_db_interface (manager->db_manager);
+               stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE,
+                                                             &error,
+                                                             "DELETE FROM Resource WHERE Refcount <= 0 "
+                                                             "AND Resource.ID NOT IN (SELECT ID FROM 
Graph)");
+
+               if (stmt) {
+                       tracker_db_statement_execute (stmt, &error);
+                       g_object_unref (stmt);
+               }
+
+               if (error) {
+                       g_warning ("Could not clean up stale resource URIs: %s\n",
+                                  error->message);
+                       g_clear_error (&error);
+               }
+
+               tracker_db_interface_execute_query (iface, NULL, "VACUUM");
+       }
 
        g_clear_pointer (&manager->db_manager, tracker_db_manager_free);
 


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