Commit 6d656add authored by Rémi Denis-Courmont's avatar 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.
parent e4f31848
...@@ -41,6 +41,8 @@ void config_Free( module_t * ); ...@@ -41,6 +41,8 @@ void config_Free( module_t * );
int __config_LoadCmdLine ( vlc_object_t *, int *, const char *[], bool ); int __config_LoadCmdLine ( vlc_object_t *, int *, const char *[], bool );
int __config_LoadConfigFile( vlc_object_t *, const char * ); int __config_LoadConfigFile( vlc_object_t *, const char * );
int config_SortConfig (void);
void config_UnsortConfig (void);
char *config_GetDataDirDefault( void ); char *config_GetDataDirDefault( void );
......
...@@ -400,50 +400,97 @@ void __config_PutFloat( vlc_object_t *p_this, ...@@ -400,50 +400,97 @@ void __config_PutFloat( vlc_object_t *p_this,
} }
} }
/***************************************************************************** static int confcmp (const void *a, const void *b)
* 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 )
{ {
VLC_UNUSED(p_this); const module_config_t *const *ca = a, *const *cb = b;
module_t *p_parser;
if( !psz_name ) return NULL; return strcmp ((*ca)->psz_name, (*cb)->psz_name);
}
module_t **list = module_list_get (NULL); static int confnamecmp (const void *key, const void *elem)
if (list == NULL) {
return NULL; 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 ) nconf = 0;
continue; 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; for (item = parser->p_config, end = item + parser->confsize;
p_item < p_end; item < end;
p_item++ ) item++)
{ {
if( p_item->i_type & CONFIG_HINT ) if (item->i_type & CONFIG_HINT)
/* ignore hints */ continue; /* ignore hints */
continue; clist[nconf++] = item;
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;
}
} }
} }
module_list_free (mlist);
module_list_free (list); qsort (clist, nconf, sizeof (*clist), confcmp);
return NULL;
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;
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -138,6 +138,7 @@ void __module_InitBank( vlc_object_t *p_this ) ...@@ -138,6 +138,7 @@ void __module_InitBank( vlc_object_t *p_this )
* as for every other module. */ * as for every other module. */
AllocateBuiltinModule( p_this, vlc_entry__main ); AllocateBuiltinModule( p_this, vlc_entry__main );
vlc_rwlock_init (&config_lock); vlc_rwlock_init (&config_lock);
config_SortConfig ();
} }
else else
p_module_bank->i_usage++; p_module_bank->i_usage++;
...@@ -181,6 +182,8 @@ void module_EndBank( vlc_object_t *p_this, bool b_plugins ) ...@@ -181,6 +182,8 @@ void module_EndBank( vlc_object_t *p_this, bool b_plugins )
vlc_mutex_unlock( &module_lock ); vlc_mutex_unlock( &module_lock );
return; return;
} }
config_UnsortConfig ();
vlc_rwlock_destroy (&config_lock); vlc_rwlock_destroy (&config_lock);
p_module_bank = NULL; p_module_bank = NULL;
vlc_mutex_unlock( &module_lock ); vlc_mutex_unlock( &module_lock );
...@@ -237,6 +240,8 @@ void module_LoadPlugins( vlc_object_t * p_this, bool b_cache_delete ) ...@@ -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 ) if( p_module_bank->b_cache || b_cache_delete )
CacheLoad( p_this, p_module_bank, b_cache_delete ); CacheLoad( p_this, p_module_bank, b_cache_delete );
AllocateAllPlugins( p_this, p_module_bank ); AllocateAllPlugins( p_this, p_module_bank );
config_UnsortConfig ();
config_SortConfig ();
} }
#endif #endif
vlc_mutex_unlock( &module_lock ); vlc_mutex_unlock( &module_lock );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment