optimize
This commit is contained in:
@@ -136,35 +136,41 @@ bool FilenameDB::ResolvePath(CString &path)
|
|||||||
if(path == "") return true;
|
if(path == "") return true;
|
||||||
|
|
||||||
/* Split path into components. */
|
/* Split path into components. */
|
||||||
vector<CString> p;
|
int begin = 0, size = -1;
|
||||||
split(path, "/", p, true);
|
|
||||||
|
|
||||||
/* If we have "/foo", then add a blank entry to the beginning to line things up. */
|
|
||||||
if( path.Left(1) == "/" )
|
|
||||||
p.insert( p.begin(), "" );
|
|
||||||
|
|
||||||
/* Resolve each component. */
|
/* Resolve each component. */
|
||||||
CString ret = "";
|
CString ret = "";
|
||||||
for(unsigned i = 0; i < p.size(); ++i)
|
FileSet *fs = NULL;
|
||||||
|
File *prev_file = NULL;
|
||||||
|
static const CString slash("/");
|
||||||
|
while( 1 )
|
||||||
{
|
{
|
||||||
if( i != 0 )
|
split( path, slash, begin, size, true );
|
||||||
ret += "/";
|
if( begin == (int) path.size() )
|
||||||
|
break;
|
||||||
|
|
||||||
vector<CString> lst;
|
if( fs == NULL )
|
||||||
FileSet &fs = GetFileSet( ret );
|
fs = &GetFileSet( ret );
|
||||||
fs.GetFilesEqualTo(p[i], lst, false);
|
|
||||||
|
CString p = path.substr( begin, size );
|
||||||
|
set<File>::iterator it = fs->files.find( File(p) );
|
||||||
|
|
||||||
/* If there were no matches, the path isn't found. */
|
/* If there were no matches, the path isn't found. */
|
||||||
if(lst.empty()) return false;
|
if( it == fs->files.end() )
|
||||||
|
return false;
|
||||||
|
|
||||||
if( lst.size() > 1 && LOG )
|
if( prev_file )
|
||||||
LOG->Warn("Ambiguous filenames '%s' and '%s'",
|
prev_file->dirp = fs;
|
||||||
lst[0].c_str(), lst[1].c_str());
|
prev_file = &*it;
|
||||||
|
|
||||||
ret += lst[0];
|
if( ret.size() != 0 )
|
||||||
|
ret += "/";
|
||||||
|
ret += it->name;
|
||||||
|
|
||||||
|
fs = it->dirp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(path.Right(1) == "/")
|
if( path.size() && path[path.size()-1] == '/' )
|
||||||
path = ret + "/";
|
path = ret + "/";
|
||||||
else
|
else
|
||||||
path = ret;
|
path = ret;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
enum FileType { TTYPE_FILE, TTYPE_DIR, TTYPE_NONE };
|
enum FileType { TTYPE_FILE, TTYPE_DIR, TTYPE_NONE };
|
||||||
|
|
||||||
|
struct FileSet;
|
||||||
struct File
|
struct File
|
||||||
{
|
{
|
||||||
CString name;
|
CString name;
|
||||||
@@ -27,7 +28,12 @@ struct File
|
|||||||
|
|
||||||
/* Private data, for RageFileDrivers. */
|
/* Private data, for RageFileDrivers. */
|
||||||
void *priv;
|
void *priv;
|
||||||
File() { dir=false; size=-1; hash=-1; priv=NULL;}
|
|
||||||
|
/* If this is non-NULL, and dir is true, this is a pointer to the FileSet containing
|
||||||
|
* the directory contents. (This is a cache; it isn't always set.) */
|
||||||
|
FileSet *dirp;
|
||||||
|
|
||||||
|
File() { dir=false; dirp=NULL; size=-1; hash=-1; priv=NULL;}
|
||||||
File( const CString &fn )
|
File( const CString &fn )
|
||||||
{
|
{
|
||||||
SetName( fn );
|
SetName( fn );
|
||||||
|
|||||||
Reference in New Issue
Block a user