mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-03 12:23:39 +00:00
Made load dialog faster when there are many saved games.
1. Added a child_range_index member function to config to generate an index 2. Changed the load dialog from the O(N^2) search for saved games to a O(N) listing.
This commit is contained in:
parent
81c2162d93
commit
82e7d2c6f8
@ -422,8 +422,7 @@ void config::merge_children_by_attribute(const t_token& key, const t_token& attr
|
||||
void config::merge_children_by_attribute(const std::string& key, const std::string& attribute){
|
||||
merge_children_by_attribute(t_token(key), t_token(attribute));}
|
||||
|
||||
config::child_itors config::child_range(const t_token& key)
|
||||
{
|
||||
config::child_itors config::child_range(const t_token& key) {
|
||||
check_valid();
|
||||
|
||||
child_map::iterator i = children.find(key);
|
||||
@ -437,8 +436,7 @@ config::child_itors config::child_range(const t_token& key)
|
||||
}
|
||||
config::child_itors config::child_range(const std::string& key){ return child_range( t_token(key) );}
|
||||
|
||||
config::const_child_itors config::child_range(const t_token& key) const
|
||||
{
|
||||
config::const_child_itors config::child_range(const t_token& key) const {
|
||||
check_valid();
|
||||
|
||||
child_map::const_iterator i = children.find(key);
|
||||
@ -452,8 +450,7 @@ config::const_child_itors config::child_range(const t_token& key) const
|
||||
}
|
||||
|
||||
config::const_child_itors config::child_range(const std::string& key) const { return child_range(t_token(key));}
|
||||
unsigned config::child_count(const t_token &key) const
|
||||
{
|
||||
unsigned config::child_count(const t_token &key) const {
|
||||
check_valid();
|
||||
|
||||
child_map::const_iterator i = children.find(key);
|
||||
@ -463,6 +460,25 @@ unsigned config::child_count(const t_token &key) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
config::t_child_range_index config::child_range_index(config::t_token const & key, config::t_token const & name) {
|
||||
t_child_range_index index;
|
||||
|
||||
child_map::iterator irange = children.find(key);
|
||||
if (irange != children.end()) {
|
||||
foreach(config * c, irange->second) {
|
||||
index.insert(std::make_pair((*c)[name].token(), c)); } }
|
||||
return index; }
|
||||
|
||||
config::t_const_child_range_index config::const_child_range_index(config::t_token const & key, config::t_token const & name) const {
|
||||
t_const_child_range_index index;
|
||||
|
||||
child_map::const_iterator irange = children.find(key);
|
||||
if (irange != children.end()) {
|
||||
foreach(config const * c, irange->second){
|
||||
index.insert(std::make_pair((*c)[name].token(), c)); } }
|
||||
return index; }
|
||||
|
||||
|
||||
unsigned config::child_count(const std::string &key) const { return child_count(t_token(key)); }
|
||||
config &config::child(const t_token& key, int n)
|
||||
{
|
||||
|
@ -117,6 +117,9 @@ public:
|
||||
//typedef std::map<t_token,child_list> child_map;
|
||||
typedef boost::unordered_map<t_token,child_list> child_map;
|
||||
|
||||
typedef boost::unordered_map<config::t_token, config *> t_child_range_index;
|
||||
typedef boost::unordered_map<config::t_token, config const *> t_const_child_range_index;
|
||||
|
||||
struct const_child_iterator;
|
||||
|
||||
struct child_iterator
|
||||
@ -298,6 +301,19 @@ public:
|
||||
typedef std::pair<const_attribute_iterator,const_attribute_iterator> const_attr_itors;
|
||||
child_itors child_range(const t_token& key);
|
||||
const_child_itors child_range(const t_token& key) const;
|
||||
|
||||
/** Creates an index into the child range to allow for quick searches.
|
||||
key is the key for the child range and name is the column to index.
|
||||
i.e. if the list of save games is stored in a child called save with titles
|
||||
then to create a container indexed by titles do
|
||||
|
||||
child_range_index(z_save, z_title);
|
||||
@Note the index is not stored in the config and is intended for
|
||||
repeated searches of large child ranges.
|
||||
*/
|
||||
t_child_range_index child_range_index(const t_token& key, config::t_token const & name);
|
||||
t_const_child_range_index const_child_range_index(const t_token& key, config::t_token const & name) const;
|
||||
|
||||
unsigned child_count(const t_token &key) const;
|
||||
|
||||
child_itors child_range(const std::string& key);
|
||||
|
@ -578,14 +578,20 @@ std::string load_game_dialog(display& disp, const config& game_config, bool* sho
|
||||
return "";
|
||||
}
|
||||
|
||||
config::t_child_range_index index = savegame::save_index::indexed_summaries();
|
||||
|
||||
std::vector<config*> summaries;
|
||||
std::vector<savegame::save_info>::const_iterator i;
|
||||
//FIXME: parent_to_child is not used yet
|
||||
std::map<std::string,std::string> parent_to_child;
|
||||
for(i = games.begin(); i != games.end(); ++i) {
|
||||
config& cfg = savegame::save_index::save_summary(i->name);
|
||||
parent_to_child[cfg["parent"]] = i->name;
|
||||
summaries.push_back(&cfg);
|
||||
config::t_token iname(i->name);
|
||||
config::t_child_range_index::iterator xcfgi = index.find( iname);
|
||||
if(xcfgi != index.end()){
|
||||
config& cfg = *xcfgi->second;
|
||||
parent_to_child[cfg["parent"]] = iname;
|
||||
summaries.push_back(&cfg);
|
||||
}
|
||||
}
|
||||
|
||||
const events::event_context context;
|
||||
|
@ -126,6 +126,13 @@ static lg::log_domain log_engine("engine");
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison, copying and hashing operations.
|
||||
static const config::t_token z_save("save", false);
|
||||
}
|
||||
namespace savegame {
|
||||
|
||||
const std::string save_info::format_time_local() const{
|
||||
@ -374,14 +381,18 @@ config& save_index::save_summary(std::string save)
|
||||
}
|
||||
|
||||
config& cfg = load();
|
||||
if (config &sv = cfg.find_child("save", "save", save))
|
||||
if (config &sv = cfg.find_child(z_save, z_save, save))
|
||||
return sv;
|
||||
|
||||
config &res = cfg.add_child("save");
|
||||
res["save"] = save;
|
||||
config &res = cfg.add_child(z_save);
|
||||
res[z_save] = save;
|
||||
return res;
|
||||
}
|
||||
|
||||
config::t_child_range_index save_index::indexed_summaries(){
|
||||
return load().child_range_index(z_save, z_save);
|
||||
}
|
||||
|
||||
void save_index::write_save_index()
|
||||
{
|
||||
log_scope("write_save_index()");
|
||||
|
@ -80,6 +80,8 @@ public:
|
||||
static config& save_summary(std::string save);
|
||||
/** Update the save_index file with changed savegame information. */
|
||||
static void write_save_index();
|
||||
/** Create an index to the save summaries. */
|
||||
static config::t_child_range_index indexed_summaries();
|
||||
|
||||
private:
|
||||
/** Default-Constructor (don't instantiate this class) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user