[vlc-devel] commit: Sort configuration items for faster lookup ( Rémi Denis-Courmont )

git version control git at videolan.org
Sat Jan 23 22:03:47 CET 2010


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Jan 23 23:00:31 2010 +0200| [6d656addd5f9d7f47f64070200398ac96c7f547b] | committer: Rémi Denis-Courmont 

Sort configuration items for faster lookup

We have well over one thousand configuration items, not counting
dummy hint entries. So now, sort all of them once (well, twice),
and use binary instead of linear search for lookups.
config_Get*, config_Put*, var_Create(with INHERIT flag),
var_CreateGet* and var_Inherit* do such lookups.

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

 src/config/configuration.h |    2 +
 src/config/core.c          |  113 +++++++++++++++++++++++++++++++-------------
 src/modules/modules.c      |    5 ++
 3 files changed, 87 insertions(+), 33 deletions(-)

diff --git a/src/config/configuration.h b/src/config/configuration.h
index a419552..c16d08e 100644
--- a/src/config/configuration.h
+++ b/src/config/configuration.h
@@ -41,6 +41,8 @@ void config_Free( module_t * );
 
 int __config_LoadCmdLine   ( vlc_object_t *, int *, const char *[], bool );
 int __config_LoadConfigFile( vlc_object_t *, const char * );
+int config_SortConfig (void);
+void config_UnsortConfig (void);
 
 char *config_GetDataDirDefault( void );
 
diff --git a/src/config/core.c b/src/config/core.c
index a8ffd53..19cd370 100644
--- a/src/config/core.c
+++ b/src/config/core.c
@@ -400,50 +400,97 @@ void __config_PutFloat( vlc_object_t *p_this,
     }
 }
 
-/*****************************************************************************
- * config_FindConfig: find the config structure associated with an option.
- *****************************************************************************
- * FIXME: This function really needs to be optimized.
- * FIXME: And now even more.
- * FIXME: remove p_this pointer parameter (or use it)
- *****************************************************************************/
-module_config_t *config_FindConfig( vlc_object_t *p_this, const char *psz_name )
+static int confcmp (const void *a, const void *b)
 {
-    VLC_UNUSED(p_this);
-    module_t *p_parser;
+    const module_config_t *const *ca = a, *const *cb = b;
 
-    if( !psz_name ) return NULL;
+    return strcmp ((*ca)->psz_name, (*cb)->psz_name);
+}
 
-    module_t **list = module_list_get (NULL);
-    if (list == NULL)
-        return NULL;
+static int confnamecmp (const void *key, const void *elem)
+{
+    const module_config_t *const *conf = elem;
 
-    for (size_t i = 0; (p_parser = list[i]) != NULL; i++)
+    return strcmp (key, (*conf)->psz_name);
+}
+
+static struct
+{
+    module_config_t **list;
+    size_t count;
+} config = { NULL, 0 };
+
+/**
+ * Index the configuration items by name for faster lookups.
+ */
+int config_SortConfig (void)
+{
+    size_t nmod;
+    module_t **mlist = module_list_get (&nmod);
+    if (unlikely(mlist == NULL))
+        return VLC_ENOMEM;
+
+    size_t nconf = 0;
+    for (size_t i = 0; i < nmod; i++)
+         nconf  += mlist[i]->confsize;
+
+    module_config_t **clist = malloc (sizeof (*clist) * nconf);
+    if (unlikely(clist == NULL))
     {
-        module_config_t *p_item, *p_end;
+        module_list_free (mlist);
+        return VLC_ENOMEM;
+    }
 
-        if( !p_parser->i_config_items )
-            continue;
+    nconf = 0;
+    for (size_t i = 0; i < nmod; i++)
+    {
+        module_t *parser = mlist[i];
+        module_config_t *item, *end;
 
-        for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize;
-             p_item < p_end;
-             p_item++ )
+        for (item = parser->p_config, end = item + parser->confsize;
+             item < end;
+             item++)
         {
-            if( p_item->i_type & CONFIG_HINT )
-                /* ignore hints */
-                continue;
-            if( !strcmp( psz_name, p_item->psz_name )
-             || ( p_item->psz_oldname
-              && !strcmp( psz_name, p_item->psz_oldname ) ) )
-            {
-                module_list_free (list);
-                return p_item;
-            }
+            if (item->i_type & CONFIG_HINT)
+                continue; /* ignore hints */
+            clist[nconf++] = item;
         }
     }
+    module_list_free (mlist);
 
-    module_list_free (list);
-    return NULL;
+    qsort (clist, nconf, sizeof (*clist), confcmp);
+
+    config.list = clist;
+    config.count = nconf;
+    return VLC_SUCCESS;
+}
+
+void config_UnsortConfig (void)
+{
+    module_config_t **clist;
+
+    clist = config.list;
+    config.list = NULL;
+    config.count = 0;
+
+    free (config.list);
+}
+
+/*****************************************************************************
+ * config_FindConfig: find the config structure associated with an option.
+ *****************************************************************************
+ * FIXME: remove p_this pointer parameter (or use it)
+ *****************************************************************************/
+module_config_t *config_FindConfig (vlc_object_t *p_this, const char *name)
+{
+    VLC_UNUSED(p_this);
+
+    if (unlikely(name == NULL))
+        return NULL;
+
+    module_config_t *const *p;
+    p = bsearch (name, config.list, config.count, sizeof (*p), confnamecmp);
+    return p ? *p : NULL;
 }
 
 /*****************************************************************************
diff --git a/src/modules/modules.c b/src/modules/modules.c
index c1bf56f..23e4bde 100644
--- a/src/modules/modules.c
+++ b/src/modules/modules.c
@@ -138,6 +138,7 @@ void __module_InitBank( vlc_object_t *p_this )
          * as for every other module. */
         AllocateBuiltinModule( p_this, vlc_entry__main );
         vlc_rwlock_init (&config_lock);
+        config_SortConfig ();
     }
     else
         p_module_bank->i_usage++;
@@ -181,6 +182,8 @@ void module_EndBank( vlc_object_t *p_this, bool b_plugins )
         vlc_mutex_unlock( &module_lock );
         return;
     }
+
+    config_UnsortConfig ();
     vlc_rwlock_destroy (&config_lock);
     p_module_bank = NULL;
     vlc_mutex_unlock( &module_lock );
@@ -237,6 +240,8 @@ void module_LoadPlugins( vlc_object_t * p_this, bool b_cache_delete )
         if( p_module_bank->b_cache || b_cache_delete )
             CacheLoad( p_this, p_module_bank, b_cache_delete );
         AllocateAllPlugins( p_this, p_module_bank );
+        config_UnsortConfig ();
+        config_SortConfig ();
     }
 #endif
     vlc_mutex_unlock( &module_lock );




More information about the vlc-devel mailing list