[tracker/wip/carlosg/parallel-stmts: 2/2] libtracker-data: Favor free interfaces over new ones harder




commit 2d9743a93b9046b4ad17f4a51f408f1337dd5ba1
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Oct 18 19:59:18 2020 +0200

    libtracker-data: Favor free interfaces over new ones harder
    
    We typically do that, but once we've found that the first interface
    in the pool is already busy with other statements, we assume they're
    all busy and jump into creating a new interface. Even worse, if that
    interface is kept busy indefinitely, every new query will opt for
    creating a new interface, quickly filling the allotment.
    
    There might be other interfaces in the pool that are already
    free, so check all of them before trying to create a new interface.
    This makes us more conservative at creating new interfaces on load
    periods, only doing so if all interfaces are actually busy.

 src/libtracker-data/tracker-db-manager.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)
---
diff --git a/src/libtracker-data/tracker-db-manager.c b/src/libtracker-data/tracker-db-manager.c
index 4eec98e11..5e98337de 100644
--- a/src/libtracker-data/tracker-db-manager.c
+++ b/src/libtracker-data/tracker-db-manager.c
@@ -819,7 +819,8 @@ TrackerDBInterface *
 tracker_db_manager_get_db_interface (TrackerDBManager *db_manager)
 {
        GError *internal_error = NULL;
-       TrackerDBInterface *interface;
+       TrackerDBInterface *interface = NULL;
+       guint len, i;
 
        /* The interfaces never actually leave the async queue,
         * we use it as a thread synchronized LRU, which doesn't
@@ -830,19 +831,30 @@ tracker_db_manager_get_db_interface (TrackerDBManager *db_manager)
         * in the interface lock).
         */
        g_async_queue_lock (db_manager->interfaces);
-       interface = g_async_queue_try_pop_unlocked (db_manager->interfaces);
+       len = g_async_queue_length_unlocked (db_manager->interfaces);
+
+       /* 1st. Find a free interface */
+       for (i = 0; i < len; i++) {
+               interface = g_async_queue_try_pop_unlocked (db_manager->interfaces);
+
+               if (!interface)
+                       break;
+               if (!tracker_db_interface_get_is_used (interface))
+                       break;
 
-       if (interface && tracker_db_interface_get_is_used (interface) &&
-           g_async_queue_length_unlocked (db_manager->interfaces) < MAX_INTERFACES) {
-               /* Put it back and go at creating a new one */
-               g_async_queue_push_front_unlocked (db_manager->interfaces, interface);
+               g_async_queue_push_unlocked (db_manager->interfaces, interface);
                interface = NULL;
        }
 
+       /* 2nd. If no more interfaces can be created, pick one */
+       if (!interface && len >= MAX_INTERFACES) {
+               interface = g_async_queue_try_pop_unlocked (db_manager->interfaces);
+       }
+
        if (interface) {
                g_signal_emit (db_manager, signals[UPDATE_INTERFACE], 0, interface);
        } else {
-               /* Create a new one to satisfy the request */
+               /* 3rd. Create a new interface to satisfy the request */
                interface = tracker_db_manager_create_db_interface (db_manager,
                                                                    TRUE, &internal_error);
 


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