Make SGPath cache stat() information, cheers Fred

* cache exists/isDir/isFile in SGPath, to avoid
  repeated calls.
This commit is contained in:
James Turner
2010-08-09 08:19:14 +01:00
parent d31c1df639
commit c4b4c0ce59
10 changed files with 107 additions and 56 deletions

View File

@@ -139,7 +139,7 @@ void SGBucket::set_bucket(const SGGeod& geod)
}
// Build the path name for this bucket
string SGBucket::gen_base_path() const {
std::string SGBucket::gen_base_path() const {
// long int index;
int top_lon, top_lat, main_lon, main_lat;
char hem, pole;

View File

@@ -34,6 +34,8 @@
using std::getline;
#endif
using std::string;
// Constructor
SGStarData::SGStarData( const SGPath& path )
{

View File

@@ -29,8 +29,6 @@
# include <dirent.h>
#endif
#include <sys/stat.h>
#include <simgear/debug/logstream.hxx>
#include <cstring>
@@ -119,12 +117,12 @@ PathList Dir::children(int types, const std::string& nameFilter) const
continue;
}
struct stat s;
if (stat(file(entry->d_name).c_str(), &s)) {
SGPath f = file(entry->d_name);
if (!f.exists()) {
continue; // stat() failed
}
if (S_ISDIR(s.st_mode)) {
if (f.isDir()) {
// directory handling
if (!(types & TYPE_DIR)) {
continue;
@@ -135,7 +133,7 @@ PathList Dir::children(int types, const std::string& nameFilter) const
continue;
}
}
} else if (S_ISREG(s.st_mode)) {
} else if (f.isFile()) {
// regular file handling
if (!(types & TYPE_FILE)) {
continue;
@@ -162,23 +160,7 @@ PathList Dir::children(int types, const std::string& nameFilter) const
bool Dir::exists() const
{
#ifdef _WIN32
struct _stat buf ;
if (_stat (_path.c_str(), &buf ) < 0) {
return false;
}
return ((S_IFDIR & buf.st_mode ) !=0);
#else
struct stat buf ;
if (stat(_path.c_str(), &buf ) < 0) {
return false ;
}
return ((S_ISDIR(buf.st_mode )) != 0);
#endif
return _path.isDir();
}
SGPath Dir::file(const std::string& name) const

View File

@@ -33,6 +33,8 @@
#endif
#include "sg_path.hxx"
using std::string;
/**
* define directory path separators
@@ -70,18 +72,38 @@ SGPath::fix()
// default constructor
SGPath::SGPath()
: path("")
: path(""),
_cached(false)
{
}
// create a path based on "path"
SGPath::SGPath( const std::string& p )
: path(p)
: path(p),
_cached(false)
{
fix();
}
SGPath::SGPath(const SGPath& p) :
path(p.path),
_cached(p._cached),
_exists(p._exists),
_isDir(p._isDir),
_isFile(p._isFile)
{
}
SGPath& SGPath::operator=(const SGPath& p)
{
path = p.path;
_cached = p._cached;
_exists = p._exists;
_isDir = p._isDir;
_isFile = p._isFile;
return *this;
}
// destructor
SGPath::~SGPath() {
@@ -92,6 +114,7 @@ SGPath::~SGPath() {
void SGPath::set( const string& p ) {
path = p;
fix();
_cached = false;
}
@@ -106,6 +129,7 @@ void SGPath::append( const string& p ) {
path += p;
}
fix();
_cached = false;
}
//add a new path component to the existing path string
@@ -123,6 +147,7 @@ void SGPath::concat( const string& p ) {
path += p;
}
fix();
_cached = false;
}
@@ -169,25 +194,54 @@ string SGPath::extension() const {
}
}
bool SGPath::exists() const
void SGPath::validate() const
{
#ifdef _WIN32
struct _stat buf;
if (_stat(path.c_str(), &buf) < 0) {
return false;
if (_cached) {
return;
}
return true;
#ifdef _WIN32
struct _stat buf ;
if (_stat (path.c_str(), &buf ) < 0) {
_exists = false;
} else {
_exists = true;
_isFile = ((S_IFREG & buf.st_mode ) !=0)
_isDir = ((S_IFDIR & buf.st_mode ) !=0)
}
#else
struct stat buf ;
if (stat(path.c_str(), &buf) < 0) {
return false ;
if (stat(path.c_str(), &buf ) < 0) {
_exists = false;
} else {
_exists = true;
_isFile = ((S_ISREG(buf.st_mode )) != 0);
_isDir = ((S_ISDIR(buf.st_mode )) != 0);
}
return true;
#endif
_cached = true;
}
bool SGPath::exists() const
{
validate();
return _exists;
}
bool SGPath::isDir() const
{
validate();
return _exists && _isDir;
}
bool SGPath::isFile() const
{
validate();
return _exists && _isFile;
}
#ifdef _WIN32

View File

@@ -35,8 +35,6 @@
#include <simgear/math/sg_types.hxx>
using std::string;
#ifdef _MSC_VER
typedef int mode_t;
#endif
@@ -53,18 +51,22 @@ class SGPath {
private:
string path;
std::string path;
public:
/** Default constructor */
SGPath();
SGPath(const SGPath& p);
SGPath& operator=(const SGPath& p);
/**
* Construct a path based on the starting path provided.
* @param p initial path
*/
SGPath( const string& p );
SGPath( const std::string& p );
/** Destructor */
~SGPath();
@@ -73,57 +75,57 @@ public:
* Set path to a new value
* @param p new path
*/
void set( const string& p );
void set( const std::string& p );
SGPath& operator= ( const char* p ) { this->set(p); return *this; }
/**
* Append another piece to the existing path. Inserts a path
* separator between the existing component and the new component.
* @param p additional path component */
void append( const string& p );
void append( const std::string& p );
/**
* Append a new piece to the existing path. Inserts a search path
* separator to the existing path and the new patch component.
* @param p additional path component */
void add( const string& p );
void add( const std::string& p );
/**
* Concatenate a string to the end of the path without inserting a
* path separator.
* @param p additional path suffix
*/
void concat( const string& p );
void concat( const std::string& p );
/**
* Get the file part of the path (everything after the last path sep)
* @return file string
*/
string file() const;
std::string file() const;
/**
* Get the directory part of the path.
* @return directory string
*/
string dir() const;
std::string dir() const;
/**
* Get the base part of the path (everything but the extension.)
* @return the base string
*/
string base() const;
std::string base() const;
/**
* Get the extension part of the path (everything after the final ".")
* @return the extension string
*/
string extension() const;
std::string extension() const;
/**
* Get the path string
* @return path string
*/
string str() const { return path; }
std::string str() const { return path; }
/**
* Get the path string
@@ -143,22 +145,30 @@ public:
*/
int create_dir(mode_t mode);
bool isFile() const;
bool isDir() const;
private:
void fix();
void validate() const;
mutable bool _cached;
mutable bool _exists;
mutable bool _isDir;
mutable bool _isFile;
};
/**
* Split a directory string into a list of it's parent directories.
*/
string_list sgPathBranchSplit( const string &path );
string_list sgPathBranchSplit( const std::string &path );
/**
* Split a directory search path into a vector of individual paths
*/
string_list sgPathSplit( const string &search_path );
string_list sgPathSplit( const std::string &search_path );
#endif // _SG_PATH_HXX

View File

@@ -28,7 +28,7 @@
#include <simgear/compiler.h>
#include <map>
using std::map;
#include <osg/AlphaFunc>
#include <osg/Group>
@@ -46,8 +46,8 @@ using std::map;
#include "matmodel.hxx"
using namespace simgear;
using std::string;
using std::map;
////////////////////////////////////////////////////////////////////////
// Implementation of SGMatModel.
////////////////////////////////////////////////////////////////////////

View File

@@ -30,6 +30,8 @@
#include <osgText/Text>
#include <osgText/Font>
using std::string;
class SGText::UpdateCallback : public osg::NodeCallback {
public:
UpdateCallback( osgText::Text * aText, SGConstPropertyNode_ptr aProperty, double aScale, double aOffset, double aTruncate, double aNumeric, const char * aFormat ) :

View File

@@ -39,7 +39,7 @@
#include <simgear/math/SGMath.hxx>
using std::string;
using namespace simgear;
osgDB::RegisterReaderWriterProxy<SGReaderWriterXML> g_readerWriter_XML_Proxy;

View File

@@ -150,7 +150,7 @@ public:
class ModelLoadHelper {
public:
virtual osg::Node *loadTileModel(const string& modelPath, bool cacheModel)=0;
virtual osg::Node *loadTileModel(const std::string& modelPath, bool cacheModel)=0;
};

View File

@@ -59,6 +59,7 @@
#define DEGHR(x) ((x)/15.)
#define RADHR(x) DEGHR(x*SGD_RADIANS_TO_DEGREES)
using std::string;
static const double MJD0 = 2415020.0;
static const double J2000 = 2451545.0 - MJD0;