faster config file saving

This commit is contained in:
OV2 2010-09-30 23:43:05 +02:00
parent 8c665e6299
commit 851839cdea
2 changed files with 64 additions and 17 deletions

View File

@ -186,11 +186,6 @@
#define snprintf _snprintf // needs ANSI compliant name #define snprintf _snprintf // needs ANSI compliant name
#endif #endif
#ifndef MAX
# define MAX(a,b) ((a) > (b)? (a) : (b))
# define MIN(a,b) ((a) < (b)? (a) : (b))
#endif
#define SORT_SECTIONS_BY_SIZE // output #define SORT_SECTIONS_BY_SIZE // output
using namespace std; using namespace std;
@ -208,6 +203,7 @@ ConfigFile::ConfigFile(void) {
void ConfigFile::Clear(void){ void ConfigFile::Clear(void){
data.clear(); data.clear();
sectionSizes.ClearSections();
linectr = 0; linectr = 0;
} }
@ -287,8 +283,10 @@ void ConfigFile::LoadFile(Reader *r, const char *name){
ConfigEntry e(line, section, key, val); ConfigEntry e(line, section, key, val);
e.comment = comment; e.comment = comment;
data.erase(e); if(data.erase(e))
sectionSizes.DecreaseSectionSize(e.section);
data.insert(e); data.insert(e);
sectionSizes.IncreaseSectionSize(e.section);
} while(!eof); } while(!eof);
curConfigFile = NULL; curConfigFile = NULL;
} }
@ -470,12 +468,14 @@ bool ConfigFile::SetString(const char *key, string val, const char *comment){
if(i!=data.end()){ if(i!=data.end()){
e.line=i->line; e.line=i->line;
data.erase(e); data.erase(e);
sectionSizes.DecreaseSectionSize(e.section);
ret=true; ret=true;
} }
if((i==data.end() && (!alphaSort || timeSort)) || (!alphaSort && timeSort)) if((i==data.end() && (!alphaSort || timeSort)) || (!alphaSort && timeSort))
e.line = linectr++; e.line = linectr++;
data.insert(e); data.insert(e);
sectionSizes.IncreaseSectionSize(e.section);
return ret; return ret;
} }
@ -562,7 +562,12 @@ const char* ConfigFile::GetComment(const char *key)
} }
bool ConfigFile::DeleteKey(const char *key){ bool ConfigFile::DeleteKey(const char *key){
return (data.erase(ConfigEntry(key))>0); ConfigEntry e = ConfigEntry(key);
if(data.erase(e)) {
sectionSizes.DecreaseSectionSize(e.section);
return true;
}
return false;
} }
/***********************************************/ /***********************************************/
@ -574,6 +579,7 @@ bool ConfigFile::DeleteSection(const char *section){
if(s==data.end()) return false; if(s==data.end()) return false;
for(e=s; e!=data.end() && e->section==section; e++) ; for(e=s; e!=data.end() && e->section==section; e++) ;
data.erase(s, e); data.erase(s, e);
sectionSizes.DeleteSection(section);
return true; return true;
} }
@ -589,13 +595,8 @@ ConfigFile::secvec_t ConfigFile::GetSection(const char *section){
return v; return v;
} }
int ConfigFile::GetSectionSize(const char *section){ int ConfigFile::GetSectionSize(const std::string section){
int count=0; return sectionSizes.GetSectionSize(section);
const unsigned int seclen=strlen(section);
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
for(i=data.begin(); i!=data.end(); i++)
if(i->section==section || !strncasecmp(section,i->section.c_str(),MIN(seclen,i->section.size()))) count++;
return count;
} }
// Clears all key-value pairs that didn't receive a "Get" or "Exists" command // Clears all key-value pairs that didn't receive a "Get" or "Exists" command
@ -621,8 +622,8 @@ void ConfigFile::ClearLines()
bool ConfigFile::ConfigEntry::section_then_key_less::operator()(const ConfigEntry &a, const ConfigEntry &b) { bool ConfigFile::ConfigEntry::section_then_key_less::operator()(const ConfigEntry &a, const ConfigEntry &b) {
if(curConfigFile && a.section!=b.section){ if(curConfigFile && a.section!=b.section){
const int sva = curConfigFile->GetSectionSize(a.section.c_str()); const int sva = curConfigFile->GetSectionSize(a.section);
const int svb = curConfigFile->GetSectionSize(b.section.c_str()); const int svb = curConfigFile->GetSectionSize(b.section);
if(sva<svb) return true; if(sva<svb) return true;
if(sva>svb) return false; if(sva>svb) return false;
return a.section<b.section; return a.section<b.section;

View File

@ -179,6 +179,7 @@
#define _CONFIG_H_ #define _CONFIG_H_
#include <set> #include <set>
#include <map>
#include <vector> #include <vector>
#include <string> #include <string>
@ -188,6 +189,11 @@
#include "snes9x.h" #include "snes9x.h"
#include "reader.h" #include "reader.h"
#ifndef MAX
# define MAX(a,b) ((a) > (b)? (a) : (b))
# define MIN(a,b) ((a) < (b)? (a) : (b))
#endif
class ConfigFile { class ConfigFile {
public: public:
ConfigFile(void); ConfigFile(void);
@ -222,7 +228,7 @@ class ConfigFile {
bool DeleteSection(const char *section); bool DeleteSection(const char *section);
typedef std::vector<std::pair<std::string,std::string> > secvec_t; typedef std::vector<std::pair<std::string,std::string> > secvec_t;
secvec_t GetSection(const char *section); secvec_t GetSection(const char *section);
int GetSectionSize(const char *section); int GetSectionSize(const std::string section);
// Clears all key-value pairs that didn't receive a Set command, or a Get command with autoAdd on // Clears all key-value pairs that didn't receive a Set command, or a Get command with autoAdd on
void ClearUnused(void); void ClearUnused(void);
@ -349,7 +355,47 @@ class ConfigFile {
friend struct key_less; friend struct key_less;
friend struct line_less; friend struct line_less;
}; };
class SectionSizes {
protected:
std::map<std::string,uint32> sections;
public:
uint32 GetSectionSize(const std::string section) {
uint32 count=0;
uint32 seclen;
std::map<std::string,uint32>::iterator it;
for(it=sections.begin(); it!=sections.end(); it++) {
seclen = MIN(section.size(),it->first.size());
if(it->first==section || !section.compare(0,seclen,it->first,0,seclen)) count+=it->second;
}
return count;
}
void IncreaseSectionSize(const std::string section) {
std::map<std::string,uint32>::iterator it=sections.find(section);
if(it!=sections.end())
it->second++;
else
sections.insert(std::pair<std::string,uint32>(section,1));
}
void DecreaseSectionSize(const std::string section) {
std::map<std::string,uint32>::iterator it=sections.find(section);
if(it!=sections.end())
it->second--;
}
void ClearSections() {
sections.clear();
}
void DeleteSection(const std::string section) {
sections.erase(section);
}
};
std::set<ConfigEntry, ConfigEntry::key_less> data; std::set<ConfigEntry, ConfigEntry::key_less> data;
SectionSizes sectionSizes;
int linectr; int linectr;
static bool defaultAutoAdd; static bool defaultAutoAdd;
static bool niceAlignment; static bool niceAlignment;