Depending on their position on the hard disk, aircraft *-set.xml
files can be found instantly, or fgfs can have to search for them
for quite a while. Sometimes up to 20 seconds (guessed) or more,
and accompanied by annoying hard disk noise.
Yesterday I've written a simple patch cache for *-set.xml file paths.
With it, fgfs first looks in the cache. If it finds a matching entry,
then it checks if the file does actually exist, in which case it uses
that.
Otherwise it scans $FG_ROOT/Aircraft/ like it used to, and creates
a new path cache. It stops when it found the aircraft, so the new
cache won't contain all *-set.xml. The cache data are saved to
autosave.xml.
The cache isn't only recreated when an aircraft wasn't found (and,
thus, a new scan is necessary, anyway), but also when FG_ROOT changed.
This should be enough to get reliable data. It also cleans out stale
entries.
I'm quite happy with the results. Gets me almost instantaneous splash
screens most of the time, and the cache isn't often rebuilt. I didn't
commit, because I'm not sure if others want this. Why would they not?
- as Andy rightly points out, $ ls $FG_ROOT/Aircraft/*/*-set.xml
is very fast, and there might just be some bad (and easy to fix)
code that makes scanning also very fast. Then we wouldn't even
need the cache. (I've checked with a profiler and couldn't find
anything suspicious yet.)
- it clutters autosave.xml a bit. I have now 172 of such entries
in it:
<aircraft n="172">
<name type="string">do335-yasim-set.xml</name>
<path type="string">/whatever/Base.local/Aircraft/DO-335</path>
</aircraft>
Doesn't bother me one bit, but maybe others. :-)
- most users don't have as many aircraft installed as we developers,
so they don't have the problem at all
Any comments?
m.
Index: fg_init.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/FlightGear/src/Main/fg_init.cxx,v
retrieving revision 1.172.2.3
diff -u -p -r1.172.2.3 fg_init.cxx
--- fg_init.cxx 2 Apr 2007 23:19:42 -0000 1.172.2.3
+++ fg_init.cxx 3 Apr 2007 10:43:11 -0000
@@ -506,8 +506,11 @@ do_options (int argc, char ** argv)
}
-#define MAXDEPTH 1
-static string fgFindAircraftPath( const SGPath &path, const string &aircraft, int depth = 0 ) {
+static string fgFindAircraftPath( const SGPath &path, const string &aircraft,
+ SGPropertyNode *cache, int depth = 0 )
+{
+ const int MAXDEPTH = 1;
+
ulDirEnt* dire;
ulDir *dirp = ulOpenDir(path.str().c_str());
if (dirp == NULL) {
@@ -528,14 +531,36 @@ static string fgFindAircraftPath( const
SGPath next = path;
next.append(dire->d_name);
- result = fgFindAircraftPath( next, aircraft, depth + 1 );
- if ( ! result.empty() ) {
+ result = fgFindAircraftPath( next, aircraft, cache, depth + 1 );
+ if ( ! result.empty() )
break;
- }
- } else if ( !strcmp(dire->d_name, aircraft.c_str()) ) {
- result = path.str();
- break;
+ } else {
+ int len = strlen(dire->d_name);
+ if (len < 9 || strcmp(dire->d_name + len - 8, "-set.xml"))
+ continue;
+
+ // create cache node
+ int i = 0;
+ while (1)
+ if (!cache->getChild("aircraft", i++, false))
+ break;
+
+ SGPropertyNode *entry = cache->getChild("aircraft", --i, true);
+ SGPropertyNode *n;
+
+ n = entry->getNode("name", true);
+ n->setStringValue(dire->d_name);
+ n->setAttribute(SGPropertyNode::USERARCHIVE, true);
+
+ n = entry->getNode("path", true);
+ n->setStringValue(path.str().c_str());
+ n->setAttribute(SGPropertyNode::USERARCHIVE, true);
+
+ if ( !strcmp(dire->d_name, aircraft.c_str()) ) {
+ result = path.str();
+ break;
+ }
}
}
@@ -560,6 +585,30 @@ bool fgInitConfig ( int argc, char **arg
return false;
}
+ SGPropertyNode autosave;
+#ifdef _MSC_VER
+ char *envp = ::getenv( "APPDATA" );
+ if (envp != NULL ) {
+ SGPath config( envp );
+ config.append( "flightgear.org" );
+#else
+ if ( homedir != NULL ) {
+ SGPath config( homedir );
+ config.append( ".fgfs" );
+#endif
+ fgSetString("/sim/fg-home", config.c_str());
+ config.append( "autosave.xml" );
+ SG_LOG(SG_INPUT, SG_INFO, "Reading user settings from " << config.str());
+ try {
+ readProperties(config.str(), &autosave, SGPropertyNode::USERARCHIVE);
+ } catch (...) {
+ SG_LOG(SG_INPUT, SG_DEBUG, "First time reading user settings");
+ }
+ SG_LOG(SG_INPUT, SG_DEBUG, "Finished Reading user settings");
+ }
+ SGPropertyNode *cache_root = autosave.getNode("sim/startup/path-cache", true);
+
+
// Scan user config files and command line for a specified aircraft.
fgInitFGAircraft(argc, argv);
@@ -569,8 +618,36 @@ bool fgInitConfig ( int argc, char **arg
aircraft_search.append( "Aircraft" );
string aircraft_set = aircraft + "-set.xml";
+ string result;
+
+ // check if the *-set.xml file is already in the cache
+ if (globals->get_fg_root() == cache_root->getStringValue("fg-root", "")) {
+ vector<SGPropertyNode_ptr> cache = cache_root->getChildren("aircraft");
+ for (unsigned int i = 0; i < cache.size(); i++) {
+ const char *name = cache[i]->getStringValue("name", "");
+ SG_LOG(SG_INPUT, SG_DEBUG, "CACHE: checking " << name);
+ if (aircraft_set == name) {
+ const char *path = cache[i]->getStringValue("path", "");
+ SG_LOG(SG_INPUT, SG_DEBUG, "CACHE: found: " << path << " -> " << aircraft_set);
+ SGPath xml(path);
+ xml.append(name);
+ if (xml.exists())
+ result = path;
+ break;
+ }
+ }
+ }
+
+ if (result.empty()) {
+ // prepare cache for rescan
+ SGPropertyNode *n = cache_root->getNode("fg-root", true);
+ n->setStringValue(globals->get_fg_root().c_str());
+ n->setAttribute(SGPropertyNode::USERARCHIVE, true);
+ cache_root->removeChildren("aircraft");
+
+ result = fgFindAircraftPath( aircraft_search, aircraft_set, cache_root );
+ }
- string result = fgFindAircraftPath( aircraft_search, aircraft_set );
if ( !result.empty() ) {
fgSetString( "/sim/aircraft-dir", result.c_str() );
SGPath full_name( result );
@@ -596,26 +673,7 @@ bool fgInitConfig ( int argc, char **arg
SG_LOG( SG_INPUT, SG_ALERT, "No default aircraft specified" );
}
-#ifdef _MSC_VER
- char *envp = ::getenv( "APPDATA" );
- if (envp != NULL ) {
- SGPath config( envp );
- config.append( "flightgear.org" );
-#else
- if ( homedir != NULL ) {
- SGPath config( homedir );
- config.append( ".fgfs" );
-#endif
- fgSetString("/sim/fg-home", config.c_str());
- config.append( "autosave.xml" );
- SG_LOG(SG_INPUT, SG_INFO, "Reading user settings from " << config.str());
- try {
- readProperties(config.str(), globals->get_props(), SGPropertyNode::USERARCHIVE);
- } catch (...) {
- SG_LOG(SG_INPUT, SG_DEBUG, "First time reading user settings");
- }
- SG_LOG(SG_INPUT, SG_DEBUG, "Finished Reading user settings");
- }
+ copyProperties(&autosave, globals->get_props());
// parse options after loading aircraft to ensure any user
// overrides of defaults are honored.
@@ -1147,7 +1205,7 @@ bool fgInitPosition() {
string fix = fgGetString("/sim/presets/fix");
fgSetDouble( "/orientation/heading-deg", hdg );
- fgInitTowerLocationListener();
+ fgInitTowerLocationListener(); // FIXME bad place; called multiple times!
if ( !set_pos && !apt.empty() && !rwy_no.empty() ) {
// An airport + runway is requested
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel