Move completions from linked list to std::set

This commit is contained in:
ridiculousfish 2012-04-09 20:17:06 -07:00
parent 8585e0e9b8
commit e2c3ca9950
2 changed files with 36 additions and 29 deletions

View file

@ -192,9 +192,20 @@ class completion_entry_t
} }
}; };
/** Linked list of all completion entries */ /** Set of all completion entries */
typedef std::list<completion_entry_t *> completion_entry_list_t; struct completion_entry_set_comparer {
static completion_entry_list_t completion_entries; /** Comparison for std::set */
bool operator()(completion_entry_t *p1, completion_entry_t *p2) const {
/* Paths always come last for no particular reason */
if (p1->cmd_is_path != p2->cmd_is_path) {
return p1->cmd_is_path < p2->cmd_is_path;
} else {
return p1->cmd < p2->cmd;
}
}
};
typedef std::set<completion_entry_t *, completion_entry_set_comparer> completion_entry_set_t;
static completion_entry_set_t completion_set;
/** The lock that guards the list of completion entries */ /** The lock that guards the list of completion entries */
static pthread_mutex_t completion_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t completion_lock = PTHREAD_MUTEX_INITIALIZER;
@ -355,13 +366,13 @@ bool completer_t::condition_test( const wcstring &condition )
static completion_entry_t *complete_find_exact_entry( const wchar_t *cmd, const bool cmd_is_path ) static completion_entry_t *complete_find_exact_entry( const wchar_t *cmd, const bool cmd_is_path )
{ {
ASSERT_IS_LOCKED(completion_lock); ASSERT_IS_LOCKED(completion_lock);
for (completion_entry_list_t::iterator iter = completion_entries.begin(); iter != completion_entries.end(); ++iter) completion_entry_t *result = NULL;
{ completion_entry_t tmp_entry(cmd, cmd_is_path, L"", false);
completion_entry_t *entry = *iter; completion_entry_set_t::iterator iter = completion_set.find(&tmp_entry);
if (entry->cmd == cmd && cmd_is_path == entry->cmd_is_path) if (iter != completion_set.end()) {
return entry; result = *iter;
} }
return NULL; return result;
} }
/** Locate the specified entry. Create it if it doesn't exist. Must be called while locked. */ /** Locate the specified entry. Create it if it doesn't exist. Must be called while locked. */
@ -375,7 +386,7 @@ static completion_entry_t *complete_get_exact_entry( const wchar_t *cmd, bool cm
if( c == NULL ) if( c == NULL )
{ {
c = new completion_entry_t(cmd, cmd_is_path, L"", true); c = new completion_entry_t(cmd, cmd_is_path, L"", true);
completion_entries.push_front(c); completion_set.insert(c);
} }
return c; return c;
@ -504,22 +515,18 @@ void complete_remove( const wchar_t *cmd,
{ {
CHECK( cmd, ); CHECK( cmd, );
scoped_lock lock(completion_lock); scoped_lock lock(completion_lock);
for (completion_entry_list_t::iterator iter = completion_entries.begin(); iter != completion_entries.end(); ) {
completion_entry_t *e = *iter; completion_entry_t tmp_entry(cmd, cmd_is_path, L"", false);
bool delete_it = false; completion_entry_set_t::iterator iter = completion_set.find(&tmp_entry);
if(cmd_is_path == e->cmd_is_path && cmd == e->cmd) { if (iter != completion_set.end()) {
delete_it = complete_remove_entry( e, short_opt, long_opt ); completion_entry_t *entry = *iter;
} bool delete_it = complete_remove_entry(entry, short_opt, long_opt);
if (delete_it) { if (delete_it) {
/* Delete this entry */ /* Delete this entry */
iter = completion_entries.erase(iter); completion_set.erase(iter);
delete e; delete entry;
} else {
/* Don't delete it */
++iter;
} }
} }
} }
/* Formats an error string by prepending the prefix and then appending the str in single quotes */ /* Formats an error string by prepending the prefix and then appending the str in single quotes */
@ -628,7 +635,7 @@ int complete_is_valid_option( const wchar_t *str,
scoped_lock lock(completion_lock); scoped_lock lock(completion_lock);
scoped_lock lock2(completion_entry_lock); scoped_lock lock2(completion_entry_lock);
for (completion_entry_list_t::iterator iter = completion_entries.begin(); iter != completion_entries.end(); ++iter) for (completion_entry_set_t::const_iterator iter = completion_set.begin(); iter != completion_set.end(); ++iter)
{ {
const completion_entry_t *i = *iter; const completion_entry_t *i = *iter;
const wcstring &match = i->cmd_is_path ? path : cmd; const wcstring &match = i->cmd_is_path ? path : cmd;
@ -1278,7 +1285,7 @@ bool completer_t::complete_param( const wcstring &scmd_orig, const wcstring &spo
scoped_lock lock(completion_lock); scoped_lock lock(completion_lock);
scoped_lock lock2(completion_entry_lock); scoped_lock lock2(completion_entry_lock);
for (completion_entry_list_t::iterator iter = completion_entries.begin(); iter != completion_entries.end(); ++iter) for (completion_entry_set_t::const_iterator iter = completion_set.begin(); iter != completion_set.end(); ++iter)
{ {
const completion_entry_t *i = *iter; const completion_entry_t *i = *iter;
const wcstring &match = i->cmd_is_path ? path : cmd; const wcstring &match = i->cmd_is_path ? path : cmd;
@ -1927,7 +1934,7 @@ void complete_print( wcstring &out )
{ {
scoped_lock locker(completion_lock); scoped_lock locker(completion_lock);
scoped_lock locker2(completion_entry_lock); scoped_lock locker2(completion_entry_lock);
for (completion_entry_list_t::const_iterator iter = completion_entries.begin(); iter != completion_entries.end(); ++iter) for (completion_entry_set_t::const_iterator iter = completion_set.begin(); iter != completion_set.end(); ++iter)
{ {
const completion_entry_t *e = *iter; const completion_entry_t *e = *iter;
const option_list_t options = e->get_options(); const option_list_t options = e->get_options();

View file

@ -2332,8 +2332,8 @@ void parser_t::eval_job( tokenizer *tok )
if(!skip ) if(!skip )
{ {
int was_builtin = 0; int was_builtin = 0;
// if( j->first_process->type==INTERNAL_BUILTIN && !j->first_process->next) if( j->first_process->type==INTERNAL_BUILTIN && !j->first_process->next)
// was_builtin = 1; was_builtin = 1;
prev_tokenizer_pos = current_tokenizer_pos; prev_tokenizer_pos = current_tokenizer_pos;
current_tokenizer_pos = job_begin_pos; current_tokenizer_pos = job_begin_pos;
exec( *this, j ); exec( *this, j );