[vlc-commits] objects: use a single flat list

Rémi Denis-Courmont git at videolan.org
Sun Mar 3 16:52:25 CET 2019


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Mar  3 15:31:40 2019 +0200| [f42fee164c71936de63b3796386e718142ca57eb] | committer: Rémi Denis-Courmont

objects: use a single flat list

This internally replaces the objects tree with a flat list. This makes
browsing from parent to children slower, which is a bad idea and only
vlc_object_find_name() relies on.

It is far more common to go from child to parent, which is unaffected
and remains O(1). Although it is also not typically a good idea.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f42fee164c71936de63b3796386e718142ca57eb
---

 src/misc/objects.c   | 29 ++++++++++++++++++++---------
 src/misc/variables.h |  3 +--
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/src/misc/objects.c b/src/misc/objects.c
index c2fb1ce45c..8cc3993935 100644
--- a/src/misc/objects.c
+++ b/src/misc/objects.c
@@ -56,19 +56,33 @@
 #include <assert.h>
 
 static vlc_mutex_t tree_lock = VLC_STATIC_MUTEX;
+static struct vlc_list tree_list = VLC_LIST_INITIALIZER(&tree_list);
 
 #define vlc_children_foreach(pos, priv) \
-    vlc_list_foreach(pos, &priv->children, siblings)
+    vlc_list_foreach(pos, &tree_list, list) \
+        if (pos->parent == vlc_externals(priv))
 
 static bool ObjectIsLastChild(vlc_object_t *obj, vlc_object_t *parent)
 {
-    return vlc_list_is_last(&vlc_internals(obj)->siblings,
-                            &vlc_internals(parent)->children);
+    struct vlc_list *node = &vlc_internals(obj)->list;
+
+    while ((node = node->next) != &tree_list) {
+        vlc_object_internals_t *priv =
+            container_of(node, vlc_object_internals_t, list);
+
+        if (priv->parent == parent)
+            return false;
+    }
+    return true;
 }
 
 static bool ObjectHasChild(vlc_object_t *obj)
 {
-    return !vlc_list_is_empty(&vlc_internals(obj)->children);
+    vlc_object_internals_t *priv;
+
+    vlc_children_foreach(priv, vlc_internals(obj))
+        return true;
+    return false;
 }
 
 static void PrintObjectPrefix(vlc_object_t *obj, bool last)
@@ -215,7 +229,6 @@ void *vlc_custom_create (vlc_object_t *parent, size_t length,
     vlc_cond_init (&priv->var_wait);
     atomic_init (&priv->refs, 1);
     priv->pf_destructor = NULL;
-    vlc_list_init(&priv->children);
     priv->resources = NULL;
 
     vlc_object_t *obj = (vlc_object_t *)(priv + 1);
@@ -224,8 +237,6 @@ void *vlc_custom_create (vlc_object_t *parent, size_t length,
 
     if (likely(parent != NULL))
     {
-        vlc_object_internals_t *papriv = vlc_internals (parent);
-
         obj->obj.logger = parent->obj.logger;
         obj->obj.no_interact = parent->obj.no_interact;
 
@@ -234,7 +245,7 @@ void *vlc_custom_create (vlc_object_t *parent, size_t length,
 
         /* Attach the parent to its child (structure lock needed) */
         vlc_mutex_lock(&tree_lock);
-        vlc_list_append(&priv->siblings, &papriv->children);
+        vlc_list_append(&priv->list, &tree_list);
         vlc_mutex_unlock(&tree_lock);
     }
     else
@@ -454,7 +465,7 @@ void vlc_object_release (vlc_object_t *obj)
 
     if (likely(refs == 1))
         /* Detach from parent to protect against vlc_object_find_name() */
-        vlc_list_remove(&priv->siblings);
+        vlc_list_remove(&priv->list);
     vlc_mutex_unlock(&tree_lock);
 
     if (likely(refs == 1))
diff --git a/src/misc/variables.h b/src/misc/variables.h
index 14aaa2336f..52bfdaec17 100644
--- a/src/misc/variables.h
+++ b/src/misc/variables.h
@@ -51,8 +51,7 @@ struct vlc_object_internals
     vlc_destructor_t pf_destructor;
 
     /* Objects tree structure */
-    struct vlc_list siblings;  /**< Siblings list node */
-    struct vlc_list children; /**< Children list */
+    struct vlc_list list; /**< Legacy list node */
 
     /* Object resources */
     struct vlc_res *resources;



More information about the vlc-commits mailing list