Replace FileSystem hash index with a regular string cache.

This requires that .mix files have valid max database
entries for all files used by the mod.
This commit is contained in:
Paul Chote
2016-01-16 10:52:11 +00:00
parent 01cd6c93d9
commit 86e4cb763d

View File

@@ -25,8 +25,7 @@ namespace OpenRA.FileSystem
static readonly Dictionary<string, Assembly> AssemblyCache = new Dictionary<string, Assembly>(); static readonly Dictionary<string, Assembly> AssemblyCache = new Dictionary<string, Assembly>();
int order; int order;
Cache<uint, List<IReadOnlyPackage>> crcHashIndex = new Cache<uint, List<IReadOnlyPackage>>(_ => new List<IReadOnlyPackage>()); Cache<string, List<IReadOnlyPackage>> fileIndex = new Cache<string, List<IReadOnlyPackage>>(_ => new List<IReadOnlyPackage>());
Cache<uint, List<IReadOnlyPackage>> classicHashIndex = new Cache<uint, List<IReadOnlyPackage>>(_ => new List<IReadOnlyPackage>());
public IReadWritePackage CreatePackage(string filename, int order, Dictionary<string, byte[]> content) public IReadWritePackage CreatePackage(string filename, int order, Dictionary<string, byte[]> content)
{ {
@@ -107,27 +106,23 @@ namespace OpenRA.FileSystem
{ {
MountedPackages.Add(package); MountedPackages.Add(package);
foreach (var hash in package.ClassicHashes()) foreach (var filename in package.AllFileNames())
{ {
var packageList = classicHashIndex[hash]; var packageList = fileIndex[filename];
if (!packageList.Contains(package))
packageList.Add(package);
}
foreach (var hash in package.CrcHashes())
{
var packageList = crcHashIndex[hash];
if (!packageList.Contains(package)) if (!packageList.Contains(package))
packageList.Add(package); packageList.Add(package);
} }
} }
public bool Unmount(IReadOnlyPackage mount) public bool Unmount(IReadOnlyPackage package)
{ {
if (MountedPackages.Contains(mount)) foreach (var packagesForFile in fileIndex.Values)
mount.Dispose(); packagesForFile.RemoveAll(p => p == package);
return MountedPackages.RemoveAll(f => f == mount) > 0; if (MountedPackages.Contains(package))
package.Dispose();
return MountedPackages.RemoveAll(p => p == package) > 0;
} }
public void UnmountAll() public void UnmountAll()
@@ -137,8 +132,7 @@ namespace OpenRA.FileSystem
MountedPackages.Clear(); MountedPackages.Clear();
PackagePaths.Clear(); PackagePaths.Clear();
classicHashIndex = new Cache<uint, List<IReadOnlyPackage>>(_ => new List<IReadOnlyPackage>()); fileIndex = new Cache<string, List<IReadOnlyPackage>>(_ => new List<IReadOnlyPackage>());
crcHashIndex = new Cache<uint, List<IReadOnlyPackage>>(_ => new List<IReadOnlyPackage>());
} }
public void LoadFromManifest(Manifest manifest) public void LoadFromManifest(Manifest manifest)
@@ -151,10 +145,9 @@ namespace OpenRA.FileSystem
Mount(pkg.Key, pkg.Value); Mount(pkg.Key, pkg.Value);
} }
Stream GetFromCache(PackageHashType type, string filename) Stream GetFromCache(string filename)
{ {
var index = type == PackageHashType.CRC32 ? crcHashIndex : classicHashIndex; var package = fileIndex[filename]
var package = index[PackageEntry.HashFilename(filename, type)]
.Where(x => x.Exists(filename)) .Where(x => x.Exists(filename))
.MinByOrDefault(x => x.Priority); .MinByOrDefault(x => x.Priority);
@@ -191,11 +184,7 @@ namespace OpenRA.FileSystem
// TODO: This disables caching for explicit package requests // TODO: This disables caching for explicit package requests
if (filename.IndexOfAny(new[] { '/', '\\' }) == -1 && !explicitPackage) if (filename.IndexOfAny(new[] { '/', '\\' }) == -1 && !explicitPackage)
{ {
s = GetFromCache(PackageHashType.Classic, filename); s = GetFromCache(filename);
if (s != null)
return true;
s = GetFromCache(PackageHashType.CRC32, filename);
if (s != null) if (s != null)
return true; return true;
} }