DatabaseWriteUsage

This commit is contained in:
Dean Herbert
2018-02-12 17:55:11 +09:00
parent cc948d688f
commit edc3638175
14 changed files with 385 additions and 354 deletions

View File

@ -21,86 +21,91 @@ namespace osu.Game.IO
public new Storage Storage => base.Storage;
public FileStore(Func<OsuDbContext> createContext, Storage storage) : base(createContext, storage.GetStorageForDirectory(@"files"))
public FileStore(DatabaseContextFactory contextFactory, Storage storage) : base(contextFactory, storage.GetStorageForDirectory(@"files"))
{
Store = new StorageBackedResourceStore(Storage);
}
public FileInfo Add(Stream data, bool reference = true)
{
var context = GetContext();
string hash = data.ComputeSHA2Hash();
var existing = context.FileInfo.FirstOrDefault(f => f.Hash == hash);
var info = existing ?? new FileInfo { Hash = hash };
string path = info.StoragePath;
// we may be re-adding a file to fix missing store entries.
if (!Storage.Exists(path))
using (var usage = ContextFactory.GetForWrite())
{
data.Seek(0, SeekOrigin.Begin);
var context = usage.Context;
using (var output = Storage.GetStream(path, FileAccess.Write))
data.CopyTo(output);
string hash = data.ComputeSHA2Hash();
data.Seek(0, SeekOrigin.Begin);
var existing = context.FileInfo.FirstOrDefault(f => f.Hash == hash);
var info = existing ?? new FileInfo { Hash = hash };
string path = info.StoragePath;
// we may be re-adding a file to fix missing store entries.
if (!Storage.Exists(path))
{
data.Seek(0, SeekOrigin.Begin);
using (var output = Storage.GetStream(path, FileAccess.Write))
data.CopyTo(output);
data.Seek(0, SeekOrigin.Begin);
}
if (reference || existing == null)
Reference(info);
return info;
}
if (reference || existing == null)
Reference(info);
return info;
}
public void Reference(params FileInfo[] files) => reference(GetContext(), files);
private void reference(OsuDbContext context, FileInfo[] files)
public void Reference(params FileInfo[] files)
{
foreach (var f in files.GroupBy(f => f.ID))
using (var usage = ContextFactory.GetForWrite())
{
var refetch = context.Find<FileInfo>(f.First().ID) ?? f.First();
refetch.ReferenceCount += f.Count();
context.FileInfo.Update(refetch);
}
var context = usage.Context;
context.SaveChanges();
foreach (var f in files.GroupBy(f => f.ID))
{
var refetch = context.Find<FileInfo>(f.First().ID) ?? f.First();
refetch.ReferenceCount += f.Count();
context.FileInfo.Update(refetch);
}
}
}
public void Dereference(params FileInfo[] files) => dereference(GetContext(), files);
private void dereference(OsuDbContext context, FileInfo[] files)
public void Dereference(params FileInfo[] files)
{
foreach (var f in files.GroupBy(f => f.ID))
using (var usage = ContextFactory.GetForWrite())
{
var refetch = context.FileInfo.Find(f.Key);
refetch.ReferenceCount -= f.Count();
context.FileInfo.Update(refetch);
var context = usage.Context;
foreach (var f in files.GroupBy(f => f.ID))
{
var refetch = context.FileInfo.Find(f.Key);
refetch.ReferenceCount -= f.Count();
context.FileInfo.Update(refetch);
}
}
context.SaveChanges();
}
public override void Cleanup()
{
var context = GetContext();
foreach (var f in context.FileInfo.Where(f => f.ReferenceCount < 1))
using (var usage = ContextFactory.GetForWrite())
{
try
var context = usage.Context;
foreach (var f in context.FileInfo.Where(f => f.ReferenceCount < 1))
{
Storage.Delete(f.StoragePath);
context.FileInfo.Remove(f);
}
catch (Exception e)
{
Logger.Error(e, $@"Could not delete beatmap {f}");
try
{
Storage.Delete(f.StoragePath);
context.FileInfo.Remove(f);
}
catch (Exception e)
{
Logger.Error(e, $@"Could not delete beatmap {f}");
}
}
}
context.SaveChanges();
}
}
}