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 * );
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 );
......
......@@ -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;
}
/*****************************************************************************
......
......@@ -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 );
......
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