зеркало из https://github.com/mozilla/gecko-dev.git
Bug 724203 - Optimize nsLocalFile::IsDirectory on Windows by 50% giving 5ms startup improvement. r=neil.
This commit is contained in:
Родитель
f115f9ac71
Коммит
b0ce243e0e
|
@ -694,6 +694,7 @@ NS_IMPL_ISUPPORTS2(nsDirEnumerator, nsISimpleEnumerator, nsIDirectoryEnumerator)
|
|||
|
||||
nsLocalFile::nsLocalFile()
|
||||
: mDirty(true)
|
||||
, mResolveDirty(true)
|
||||
, mFollowSymlinks(false)
|
||||
{
|
||||
}
|
||||
|
@ -735,6 +736,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsLocalFile,
|
|||
|
||||
nsLocalFile::nsLocalFile(const nsLocalFile& other)
|
||||
: mDirty(true)
|
||||
, mResolveDirty(true)
|
||||
, mFollowSymlinks(other.mFollowSymlinks)
|
||||
, mWorkingPath(other.mWorkingPath)
|
||||
{
|
||||
|
@ -797,6 +799,7 @@ nsLocalFile::ResolveAndStat()
|
|||
|| !IsShortcutPath(mWorkingPath))
|
||||
{
|
||||
mDirty = false;
|
||||
mResolveDirty = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -810,6 +813,7 @@ nsLocalFile::ResolveAndStat()
|
|||
mResolvedPath.Assign(mWorkingPath);
|
||||
return rv;
|
||||
}
|
||||
mResolveDirty = false;
|
||||
|
||||
// get the details of the resolved path
|
||||
rv = GetFileInfo(mResolvedPath, &mFileInfo64);
|
||||
|
@ -820,6 +824,50 @@ nsLocalFile::ResolveAndStat()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the mResolvedPath member variable with the file or symlink target
|
||||
* if follow symlinks is on. This is a copy of the Resolve parts from
|
||||
* ResolveAndStat. ResolveAndStat is much slower though because of the stat.
|
||||
*
|
||||
* @return NS_OK on success.
|
||||
*/
|
||||
nsresult
|
||||
nsLocalFile::Resolve()
|
||||
{
|
||||
// if we aren't dirty then we are already done
|
||||
if (!mResolveDirty) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// we can't resolve/stat anything that isn't a valid NSPR addressable path
|
||||
if (mWorkingPath.IsEmpty()) {
|
||||
return NS_ERROR_FILE_INVALID_PATH;
|
||||
}
|
||||
|
||||
// this is usually correct
|
||||
mResolvedPath.Assign(mWorkingPath);
|
||||
|
||||
// if this isn't a shortcut file or we aren't following symlinks then
|
||||
// we're done.
|
||||
if (!mFollowSymlinks ||
|
||||
!IsShortcutPath(mWorkingPath)) {
|
||||
mResolveDirty = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// we need to resolve this shortcut to what it points to, this will
|
||||
// set mResolvedPath. Even if it fails we need to have the resolved
|
||||
// path equal to working path for those functions that always use
|
||||
// the resolved path.
|
||||
nsresult rv = ResolveShortcut();
|
||||
if (NS_FAILED(rv)) {
|
||||
mResolvedPath.Assign(mWorkingPath);
|
||||
return rv;
|
||||
}
|
||||
|
||||
mResolveDirty = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsLocalFile::nsIFile,nsILocalFile
|
||||
|
@ -2491,27 +2539,31 @@ nsLocalFile::IsExecutable(bool *_retval)
|
|||
NS_IMETHODIMP
|
||||
nsLocalFile::IsDirectory(bool *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG(_retval);
|
||||
nsresult rv = IsFile(_retval);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult rv = ResolveAndStat();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*_retval = (mFileInfo64.type == PR_FILE_DIRECTORY);
|
||||
return NS_OK;
|
||||
*_retval = !*_retval;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::IsFile(bool *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG(_retval);
|
||||
NS_ENSURE_ARG(_retval);
|
||||
nsresult rv = Resolve();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult rv = ResolveAndStat();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
DWORD attributes = GetFileAttributes(mResolvedPath.get());
|
||||
if (INVALID_FILE_ATTRIBUTES == attributes) {
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
*_retval = (mFileInfo64.type == PR_FILE_FILE);
|
||||
return NS_OK;
|
||||
*_retval = !(attributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -95,6 +95,7 @@ private:
|
|||
~nsLocalFile() {}
|
||||
|
||||
bool mDirty; // cached information can only be used when this is false
|
||||
bool mResolveDirty;
|
||||
bool mFollowSymlinks; // should we follow symlinks when working on this file
|
||||
|
||||
// this string will always be in native format!
|
||||
|
@ -110,9 +111,15 @@ private:
|
|||
|
||||
PRFileInfo64 mFileInfo64;
|
||||
|
||||
void MakeDirty() { mDirty = true; mShortWorkingPath.Truncate(); }
|
||||
void MakeDirty()
|
||||
{
|
||||
mDirty = true;
|
||||
mResolveDirty = true;
|
||||
mShortWorkingPath.Truncate();
|
||||
}
|
||||
|
||||
nsresult ResolveAndStat();
|
||||
nsresult Resolve();
|
||||
nsresult ResolveShortcut();
|
||||
|
||||
void EnsureShortPath();
|
||||
|
|
Загрузка…
Ссылка в новой задаче