perf fix wrt calling OpenRead way too often.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using IjwFramework.Collections;
|
||||||
|
|
||||||
namespace OpenRa.FileFormats
|
namespace OpenRa.FileFormats
|
||||||
{
|
{
|
||||||
@@ -9,10 +10,13 @@ namespace OpenRa.FileFormats
|
|||||||
static List<IFolder> mountedFolders = new List<IFolder>();
|
static List<IFolder> mountedFolders = new List<IFolder>();
|
||||||
static List<IFolder> temporaryMounts = new List<IFolder>();
|
static List<IFolder> temporaryMounts = new List<IFolder>();
|
||||||
|
|
||||||
|
static Cache<uint, List<IFolder>> allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||||
|
static Cache<uint, List<IFolder>> allTemporaryFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||||
|
|
||||||
public static void MountDefaultPackages()
|
public static void MountDefaultPackages()
|
||||||
{
|
{
|
||||||
FileSystem.Mount(new Folder("./"));
|
FileSystem.Mount(new Folder("./"));
|
||||||
if( File.Exists( "main.mix" ) )
|
if( FileSystem.Exists( "main.mix" ) )
|
||||||
FileSystem.Mount( new Package( "main.mix" ) );
|
FileSystem.Mount( new Package( "main.mix" ) );
|
||||||
FileSystem.Mount( new Package( "redalert.mix" ) );
|
FileSystem.Mount( new Package( "redalert.mix" ) );
|
||||||
FileSystem.Mount( new Package( "conquer.mix" ) );
|
FileSystem.Mount( new Package( "conquer.mix" ) );
|
||||||
@@ -34,22 +38,54 @@ namespace OpenRa.FileFormats
|
|||||||
public static void Mount(IFolder folder)
|
public static void Mount(IFolder folder)
|
||||||
{
|
{
|
||||||
mountedFolders.Add(folder);
|
mountedFolders.Add(folder);
|
||||||
|
|
||||||
|
foreach( var hash in folder.AllFileHashes() )
|
||||||
|
{
|
||||||
|
var l = allFiles[hash];
|
||||||
|
if( !l.Contains( folder ) )
|
||||||
|
l.Add( folder );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MountTemporary(IFolder folder)
|
public static void MountTemporary(IFolder folder)
|
||||||
{
|
{
|
||||||
mountedFolders.Add(folder);
|
mountedFolders.Add(folder);
|
||||||
temporaryMounts.Add(folder);
|
temporaryMounts.Add(folder);
|
||||||
|
|
||||||
|
foreach( var hash in folder.AllFileHashes() )
|
||||||
|
{
|
||||||
|
var l = allFiles[hash];
|
||||||
|
if( !l.Contains( folder ) )
|
||||||
|
l.Add( folder );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UnmountTemporaryPackages()
|
public static void UnmountTemporaryPackages()
|
||||||
{
|
{
|
||||||
mountedFolders.RemoveAll(f => temporaryMounts.Contains(f));
|
mountedFolders.RemoveAll(f => temporaryMounts.Contains(f));
|
||||||
temporaryMounts.Clear();
|
temporaryMounts.Clear();
|
||||||
|
|
||||||
|
allTemporaryFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream GetFromCache( Cache<uint, List<IFolder>> index, string filename )
|
||||||
|
{
|
||||||
|
foreach( var folder in index[ PackageEntry.HashFilename( filename ) ] )
|
||||||
|
{
|
||||||
|
Stream s = folder.GetContent(filename);
|
||||||
|
if( s != null )
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stream Open(string filename)
|
public static Stream Open(string filename)
|
||||||
{
|
{
|
||||||
|
var ret = GetFromCache( allFiles, filename )
|
||||||
|
?? GetFromCache( allTemporaryFiles, filename );
|
||||||
|
if( ret != null )
|
||||||
|
return ret;
|
||||||
|
|
||||||
foreach( IFolder folder in mountedFolders )
|
foreach( IFolder folder in mountedFolders )
|
||||||
{
|
{
|
||||||
Stream s = folder.GetContent(filename);
|
Stream s = folder.GetContent(filename);
|
||||||
@@ -62,6 +98,14 @@ namespace OpenRa.FileFormats
|
|||||||
|
|
||||||
public static Stream OpenWithExts( string filename, params string[] exts )
|
public static Stream OpenWithExts( string filename, params string[] exts )
|
||||||
{
|
{
|
||||||
|
foreach( var ext in exts )
|
||||||
|
{
|
||||||
|
var s = GetFromCache( allFiles, filename + ext )
|
||||||
|
?? GetFromCache( allTemporaryFiles, filename + ext );
|
||||||
|
if( s != null )
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
foreach( var ext in exts )
|
foreach( var ext in exts )
|
||||||
{
|
{
|
||||||
foreach( IFolder folder in mountedFolders )
|
foreach( IFolder folder in mountedFolders )
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace OpenRa.FileFormats
|
namespace OpenRa.FileFormats
|
||||||
{
|
{
|
||||||
@@ -10,8 +11,15 @@ namespace OpenRa.FileFormats
|
|||||||
|
|
||||||
public Stream GetContent(string filename)
|
public Stream GetContent(string filename)
|
||||||
{
|
{
|
||||||
try { return File.OpenRead(path + filename); }
|
Log.Write( "GetContent from folder: {0}", filename );
|
||||||
|
try { return File.OpenRead( Path.Combine( path, filename ) ); }
|
||||||
catch { return null; }
|
catch { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<uint> AllFileHashes()
|
||||||
|
{
|
||||||
|
foreach( var filename in Directory.GetFiles( path, "*", SearchOption.TopDirectoryOnly ) )
|
||||||
|
yield return PackageEntry.HashFilename( filename );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace OpenRa.FileFormats
|
|||||||
public interface IFolder
|
public interface IFolder
|
||||||
{
|
{
|
||||||
Stream GetContent(string filename);
|
Stream GetContent(string filename);
|
||||||
|
IEnumerable<uint> AllFileHashes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Package : IFolder
|
public class Package : IFolder
|
||||||
@@ -131,6 +132,11 @@ namespace OpenRa.FileFormats
|
|||||||
{
|
{
|
||||||
return GetContent(PackageEntry.HashFilename(filename));
|
return GetContent(PackageEntry.HashFilename(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<uint> AllFileHashes()
|
||||||
|
{
|
||||||
|
return index.Keys;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
|||||||
Reference in New Issue
Block a user