Speed up FileName operator== (Georg's solution).

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@29498 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Enrico Forestieri 2009-05-02 17:12:31 +00:00
parent e0941bdb4b
commit ccc77c73da
13 changed files with 91 additions and 52 deletions

View File

@ -300,10 +300,25 @@ bool BufferList::isLoaded(Buffer const * b) const
}
namespace {
struct equivalent_to : public binary_function<FileName, FileName, bool>
{
bool operator()(FileName const & x, FileName const & y) const
{ return equivalent(x, y); }
};
}
Buffer * BufferList::getBuffer(support::FileName const & fname) const
{
// 1) cheap test, using string comparison of file names
BufferStorage::const_iterator it = find_if(bstore.begin(), bstore.end(),
bind(equal_to<FileName>(), bind(&Buffer::fileName, _1), fname));
if (it != bstore.end())
return *it;
// 2) possibly expensive test, using quivalence test of file names
it = find_if(bstore.begin(), bstore.end(),
bind(equivalent_to(), bind(&Buffer::fileName, _1), fname));
return it != bstore.end() ? (*it) : 0;
}

View File

@ -785,12 +785,13 @@ bool handleFoundFile(string const & ff, DepTable & head)
// (1) foundfile is an
// absolute path and should
// be inserted.
FileName absname(foundfile);
if (absname.isAbsolute()) {
FileName absname;
if (FileName::isAbsolute(foundfile)) {
LYXERR(Debug::DEPEND, "AbsolutePath file: " << foundfile);
// On initial insert we want to do the update at once
// since this file cannot be a file generated by
// the latex run.
absname.set(foundfile);
if (!insertIfExists(absname, head)) {
// check for spaces
string strippedfile = foundfile;

View File

@ -57,11 +57,11 @@ void LastFilesSection::read(istream & is)
if (c == '[')
break;
getline(is, tmp);
FileName const file(tmp);
if (tmp == "" || tmp[0] == '#' || tmp[0] == ' ' || !file.isAbsolute())
if (tmp.empty() || tmp[0] == '#' || tmp[0] == ' ' || !FileName::isAbsolute(tmp))
continue;
// read lastfiles
FileName const file(tmp);
if (file.exists() && !file.isDirectory()
&& lastfiles.size() < num_lastfiles)
lastfiles.push_back(file);
@ -111,10 +111,10 @@ void LastOpenedSection::read(istream & is)
if (c == '[')
break;
getline(is, tmp);
FileName const file(tmp);
if (tmp == "" || tmp[0] == '#' || tmp[0] == ' ' || !file.isAbsolute())
if (tmp.empty() || tmp[0] == '#' || tmp[0] == ' ' || !FileName::isAbsolute(tmp))
continue;
FileName const file(tmp);
if (file.exists() && !file.isDirectory())
lastopened.push_back(file);
else
@ -165,9 +165,9 @@ void LastFilePosSection::read(istream & is)
itmp >> filepos.pos;
itmp.ignore(2); // ignore ", "
getline(itmp, fname);
FileName const file(fname);
if (!file.isAbsolute())
if (!FileName::isAbsolute(fname))
continue;
FileName const file(fname);
if (file.exists() && !file.isDirectory()
&& lastfilepos.size() < num_lastfilepos)
lastfilepos[file] = filepos;
@ -242,9 +242,9 @@ void BookmarksSection::read(istream & is)
itmp >> pos;
itmp.ignore(2); // ignore ", "
getline(itmp, fname);
FileName const file(fname);
if (!file.isAbsolute())
if (!FileName::isAbsolute(fname))
continue;
FileName const file(fname);
// only load valid bookmarks
if (file.exists() && !file.isDirectory() && idx <= max_bookmarks)
bookmarks[idx] = Bookmark(file, pit, pos, 0, 0);

View File

@ -130,7 +130,7 @@ string const doSubstitution(InsetExternalParams const & params,
relToParentPath, use_latex_path,
PROTECT_EXTENSION,
ESCAPE_DOTS);
if (FileName(filename).isAbsolute()) {
if (FileName::isAbsolute(filename)) {
result = subst_path(result, "$$AbsOrRelPathMaster",
abspath, use_latex_path,
PROTECT_EXTENSION,

View File

@ -219,7 +219,7 @@ static string normalizeName(Buffer const & buffer,
OutputParams const & runparams, string const & name, string const & ext)
{
string const fname = makeAbsPath(name, buffer.filePath()).absFilename();
if (FileName(name).isAbsolute() || !FileName(fname + ext).isReadableFile())
if (FileName::isAbsolute(name) || !FileName(fname + ext).isReadableFile())
return name;
if (!runparams.nice)
return fname;
@ -408,8 +408,7 @@ support::FileNameList InsetBibtex::getBibFiles() const
vector<docstring>::const_iterator it = bibfilelist.begin();
vector<docstring>::const_iterator en = bibfilelist.end();
for (; it != en; ++it) {
FileName const file =
findtexfile(changeExtension(to_utf8(*it), "bib"), "bib");
FileName const file = getBibTeXPath(*it, buffer());
if (!file.empty())
vec.push_back(file);

View File

@ -455,7 +455,7 @@ int InsetInclude::latex(odocstream & os, OutputParams const & runparams) const
// if incfile is relative, make it relative to the master
// buffer directory.
if (!FileName(incfile).isAbsolute()) {
if (!FileName::isAbsolute(incfile)) {
// FIXME UNICODE
incfile = to_utf8(makeRelPath(from_utf8(included_file.absFilename()),
from_utf8(masterBuffer->filePath())));

View File

@ -105,6 +105,7 @@ struct FileName::Private
Private(string const & abs_filename) : fi(toqstr(abs_filename))
{
name = abs_filename;
fi.setCaching(fi.exists() ? true : false);
}
///
@ -129,6 +130,8 @@ struct FileName::Private
Qt::CaseSensitive : Qt::CaseInsensitive) == 0;
}
/// The absolute file name in UTF-8 encoding.
std::string name;
///
QFileInfo fi;
};
@ -148,6 +151,8 @@ FileName::FileName() : d(new Private)
FileName::FileName(string const & abs_filename)
: d(abs_filename.empty() ? new Private : new Private(abs_filename))
{
//LYXERR(Debug::FILES, "FileName(" << abs_filename << ')');
LASSERT(empty() || isAbsolute(d->name), /**/);
}
@ -159,6 +164,7 @@ FileName::~FileName()
FileName::FileName(FileName const & rhs) : d(new Private)
{
d->name = rhs.d->name;
d->fi = rhs.d->fi;
}
@ -171,6 +177,9 @@ FileName::FileName(FileName const & rhs, string const & suffix) : d(new Private)
FileName & FileName::operator=(FileName const & rhs)
{
if (&rhs == this)
return *this;
d->name = rhs.d->name;
d->fi = rhs.d->fi;
return *this;
}
@ -178,19 +187,20 @@ FileName & FileName::operator=(FileName const & rhs)
bool FileName::empty() const
{
return d->fi.absoluteFilePath().isEmpty();
return d->name.empty();
}
bool FileName::isAbsolute() const
bool FileName::isAbsolute(string const & name)
{
return d->fi.isAbsolute();
QFileInfo fi(toqstr(name));
return fi.isAbsolute();
}
string FileName::absFilename() const
{
return fromqstr(d->fi.absoluteFilePath());
return d->name;
}
@ -202,21 +212,28 @@ string FileName::realPath() const
void FileName::set(string const & name)
{
d->name = name;
d->fi.setFile(toqstr(name));
//LYXERR(Debug::FILES, "FileName::set(" << name << ')');
LASSERT(empty() || isAbsolute(d->name), /**/);
}
void FileName::set(FileName const & rhs, string const & suffix)
{
d->name = rhs.d->name + suffix;
if (!rhs.d->fi.isDir())
d->fi.setFile(rhs.d->fi.filePath() + toqstr(suffix));
else
d->fi.setFile(QDir(rhs.d->fi.absoluteFilePath()), toqstr(suffix));
//LYXERR(Debug::FILES, "FileName::set(" << d->name << ')');
LASSERT(empty() || isAbsolute(d->name), /**/);
}
void FileName::erase()
{
d->name.clear();
d->fi = QFileInfo();
}
@ -285,37 +302,39 @@ FileName FileName::fromFilesystemEncoding(string const & name)
bool FileName::exists() const
{
return d->fi.exists();
return !empty() && d->fi.exists();
}
bool FileName::isSymLink() const
{
return d->fi.isSymLink();
return !empty() && d->fi.isSymLink();
}
bool FileName::isFileEmpty() const
{
LASSERT(!empty(), return true);
return d->fi.size() == 0;
}
bool FileName::isDirectory() const
{
return d->fi.isDir();
return !empty() && d->fi.isDir();
}
bool FileName::isReadOnly() const
{
LASSERT(!empty(), return true);
return d->fi.isReadable() && !d->fi.isWritable();
}
bool FileName::isReadableDirectory() const
{
return d->fi.isDir() && d->fi.isReadable();
return isDirectory() && d->fi.isReadable();
}
@ -346,26 +365,29 @@ bool FileName::hasExtension(const string & ext)
FileName FileName::onlyPath() const
{
FileName path;
if (empty())
return path;
path.d->fi.setFile(d->fi.path());
path.d->name = fromqstr(path.d->fi.absoluteFilePath());
return path;
}
bool FileName::isReadableFile() const
{
return d->fi.isFile() && d->fi.isReadable();
return !empty() && d->fi.isFile() && d->fi.isReadable();
}
bool FileName::isWritable() const
{
return d->fi.isWritable();
return !empty() && d->fi.isWritable();
}
bool FileName::isDirWritable() const
{
LASSERT(d->fi.isDir(), return false);
LASSERT(isDirectory(), return false);
QFileInfo tmp(QDir(d->fi.absoluteFilePath()), "lyxwritetest");
QTemporaryFile qt_tmp(tmp.absoluteFilePath());
if (qt_tmp.open()) {
@ -440,7 +462,9 @@ FileName FileName::tempName(string const & mask)
FileName FileName::getcwd()
{
return FileName(".");
// return makeAbsPath("."); would create an infinite loop
QFileInfo fi(".");
return FileName(fromqstr(fi.absoluteFilePath()));
}
@ -653,7 +677,7 @@ bool FileName::createDirectory(int permission) const
bool FileName::createPath() const
{
LASSERT(!empty(), /**/);
LASSERT(!empty(), return false);
LYXERR(Debug::FILES, "creating path '" << *this << "'.");
if (isDirectory())
return false;
@ -933,7 +957,7 @@ docstring const FileName::relPath(string const & path) const
// see:
// http://www.qtsoftware.com/developer/task-tracker/
// index_html?id=248471&method=entry.
bool operator==(FileName const & l, FileName const & r)
bool equivalent(FileName const & l, FileName const & r)
{
// FIXME: In future use Qt.
// Qt 4.4: We need to solve this warning from Qt documentation:
@ -973,6 +997,12 @@ bool operator==(FileName const & l, FileName const & r)
}
bool operator==(FileName const & lhs, FileName const & rhs)
{
return lhs.absFilename() == rhs.absFilename();
}
bool operator!=(FileName const & lhs, FileName const & rhs)
{
return !(operator==(lhs, rhs));
@ -1021,10 +1051,10 @@ DocFileName::DocFileName(FileName const & abs_filename, bool save_abs)
void DocFileName::set(string const & name, string const & buffer_path)
{
FileName::set(name);
bool const nameIsAbsolute = isAbsolute();
save_abs_path_ = nameIsAbsolute;
if (!nameIsAbsolute)
save_abs_path_ = isAbsolute(name);
if (save_abs_path_)
FileName::set(name);
else
FileName::set(makeAbsPath(name, buffer_path).absFilename());
zipped_valid_ = false;
}

View File

@ -60,7 +60,7 @@ public:
/// Is this filename empty?
bool empty() const;
/// Is the filename absolute?
bool isAbsolute() const;
static bool isAbsolute(std::string const & name);
/// get the absolute file name in UTF-8 encoding
std::string absFilename() const;
@ -197,13 +197,14 @@ public:
docstring const absoluteFilePath() const;
private:
friend bool operator==(FileName const &, FileName const &);
friend bool equivalent(FileName const &, FileName const &);
///
struct Private;
Private * const d;
};
bool equivalent(FileName const &, FileName const &);
bool operator==(FileName const &, FileName const &);
bool operator!=(FileName const &, FileName const &);
bool operator<(FileName const &, FileName const &);

View File

@ -374,8 +374,7 @@ FileName const abs_path_from_command_line(string const & command_line)
return FileName();
string const str_path = fix_dir_name(command_line);
FileName path(str_path);
return path.isAbsolute() ? path : makeAbsPath(str_path);
return makeAbsPath(str_path);
}
@ -392,9 +391,8 @@ FileName const get_binary_path(string const & exe)
#else
string const exe_path = os::internal_path(exe);
#endif
FileName exepath(exe_path);
if (exepath.isAbsolute())
return exepath;
if (FileName::isAbsolute(exe_path))
return FileName(exe_path);
// Two possibilities present themselves.
// 1. The binary is relative to the CWD.

View File

@ -375,10 +375,9 @@ string const onlyPath(string const & filename)
// FIXME It might be nice if the code didn't simply assume that.
FileName const makeAbsPath(string const & relPath, string const & basePath)
{
FileName relative_path(relPath);
// checks for already absolute path
if (relative_path.isAbsolute())
return relative_path;
if (FileName::isAbsolute(relPath))
return FileName(relPath);
// Copies given paths
string tempRel = os::internal_path(relPath);
@ -387,8 +386,7 @@ FileName const makeAbsPath(string const & relPath, string const & basePath)
string tempBase;
FileName base_path(basePath);
if (base_path.isAbsolute())
if (FileName::isAbsolute(basePath))
tempBase = basePath;
else
tempBase = addPath(FileName::getcwd().absFilename(), basePath);
@ -488,8 +486,7 @@ string const expandPath(string const & path)
{
// checks for already absolute path
string rTemp = replaceEnvironmentPath(path);
FileName abs_path(rTemp);
if (abs_path.isAbsolute())
if (FileName::isAbsolute(rTemp))
return rTemp;
string temp;

View File

@ -197,7 +197,7 @@ string latex_path(string const & p)
// on windows_style_tex_paths_), but we use always forward slashes,
// since it gets written into a .tex file.
if (windows_style_tex_paths_ && FileName(p).isAbsolute()) {
if (windows_style_tex_paths_ && FileName::isAbsolute(p)) {
string dos_path = convert_path(p, PathStyle(windows));
LYXERR(Debug::LATEX, "<Path correction for LaTeX> ["
<< p << "]->>[" << dos_path << ']');

View File

@ -252,8 +252,7 @@ string latex_path(string const & p)
// on windows_style_tex_paths_), but we use always forward slashes,
// since it gets written into a .tex file.
FileName path(p);
if (!windows_style_tex_paths_ && path.isAbsolute()) {
if (!windows_style_tex_paths_ && FileName::isAbsolute(p)) {
string const drive = p.substr(0, 2);
string const cygprefix = cygdrive + "/" + drive.substr(0, 1);
string const cygpath = subst(subst(p, '\\', '/'), drive, cygprefix);

View File

@ -1049,8 +1049,7 @@ string const normalize_filename(string const & name)
/// convention (relative to .lyx file) if it is relative
void fix_relative_filename(string & name)
{
FileName fname(name);
if (fname.isAbsolute())
if (FileName::isAbsolute(name))
return;
name = to_utf8(makeRelPath(from_utf8(makeAbsPath(name, getMasterFilePath()).absFilename()),