Implemented InMemoryMetadataStorage

master
Inga 🏳‍🌈 7 years ago
parent bd4eb3edc0
commit 588027c761
  1. 7
      EternalArrowBackup.sln
  2. 6
      Source/TargetMetadataStorage/Contracts/EternalArrowBackup.TargetMetadataStorage.Contracts.csproj
  3. 6
      Source/TargetMetadataStorage/Contracts/ITargetDirectory.cs
  4. 5
      Source/TargetMetadataStorage/Contracts/ITargetFile.cs
  5. 8
      Source/TargetMetadataStorage/Contracts/ITargetMetadataStorageForRecovery.cs
  6. 15
      Source/TargetMetadataStorage/InMemoryMetadataStorage/EternalArrowBackup.TargetMetadataStorage.InMemoryMetadataStorage.csproj
  7. 99
      Source/TargetMetadataStorage/InMemoryMetadataStorage/MetadataStorage.cs
  8. 62
      Source/TargetMetadataStorage/InMemoryMetadataStorage/TargetDirectory.cs
  9. 36
      Source/TargetMetadataStorage/InMemoryMetadataStorage/TargetFile.cs
  10. 24
      Source/TargetMetadataStorage/InMemoryMetadataStorage/TargetFileVersion.cs

@ -59,6 +59,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TargetBinaryStorage", "Targ
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EternalArrowBackup.TargetBinaryStorage.InMemoryBinaryStorage.Tests", "Tests\TargetBinaryStorage\InMemoryBinaryStorage\EternalArrowBackup.TargetBinaryStorage.InMemoryBinaryStorage.Tests.csproj", "{3D95405C-C305-4D73-9B2C-938156FD9B2E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EternalArrowBackup.TargetMetadataStorage.InMemoryMetadataStorage", "Source\TargetMetadataStorage\InMemoryMetadataStorage\EternalArrowBackup.TargetMetadataStorage.InMemoryMetadataStorage.csproj", "{AC7EA3E8-6469-4102-940F-31EF831E823F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -125,6 +127,10 @@ Global
{3D95405C-C305-4D73-9B2C-938156FD9B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D95405C-C305-4D73-9B2C-938156FD9B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D95405C-C305-4D73-9B2C-938156FD9B2E}.Release|Any CPU.Build.0 = Release|Any CPU
{AC7EA3E8-6469-4102-940F-31EF831E823F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC7EA3E8-6469-4102-940F-31EF831E823F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC7EA3E8-6469-4102-940F-31EF831E823F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC7EA3E8-6469-4102-940F-31EF831E823F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -156,5 +162,6 @@ Global
{12102767-6F40-4328-9CB5-290EF484682D} = {85879329-E36C-4585-8019-2825DEB4D0B8}
{61CADBF4-3D45-4980-81E5-5268199E615A} = {884B8E01-303A-40CF-8884-D62115F98683}
{3D95405C-C305-4D73-9B2C-938156FD9B2E} = {61CADBF4-3D45-4980-81E5-5268199E615A}
{AC7EA3E8-6469-4102-940F-31EF831E823F} = {99C42B64-99CF-4FB3-B270-079476B43FF7}
EndGlobalSection
EndGlobal

@ -1,7 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.7.0" />
</ItemGroup>
</Project>

@ -1,13 +1,15 @@
namespace EternalArrowBackup.TargetMetadataStorage.Contracts
{
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
public interface ITargetDirectory
{
string DirectoryName { get; }
Task UploadFile(string filename, string originalHash, long originalSize);
IObservable<ITargetFileVersion> GetAllLatestFileVersions(CancellationToken ct);
Task GetAllLatestFileVersions(ActionBlock<ITargetFileVersion> actionBlock, CancellationToken ct);
}
}

@ -1,10 +1,11 @@
namespace EternalArrowBackup.TargetMetadataStorage.Contracts
{
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
public interface ITargetFile
{
IObservable<ITargetFileVersion> GetAllVersions(CancellationToken ct);
Task GetAllVersions(ActionBlock<ITargetFileVersion> actionBlock, CancellationToken ct);
}
}

@ -1,13 +1,15 @@
namespace EternalArrowBackup.TargetMetadataStorage.Contracts
{
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
public interface ITargetMetadataStorageForRecovery
public interface ITargetMetadataStorageForRecovery : ITargetMetadataStorage
{
IObservable<ITargetDirectory> GetAllDirectories(CancellationToken ct);
Task GetAllDirectories(ActionBlock<ITargetDirectory> actionBlock, CancellationToken ct);
Task<ITargetFile> GetFile(string normalizedRelativeDirectoryPath, string filename);
Task GetBlobUsages(string hash, ActionBlock<ITargetFileVersion> actionBlock, CancellationToken ct);
}
}

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\EternalArrowBackup.TargetMetadataStorage.Contracts.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,99 @@
namespace EternalArrowBackup.TargetMetadataStorage.InMemoryMetadataStorage
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using EternalArrowBackup.TargetMetadataStorage.Contracts;
public class MetadataStorage : ITargetMetadataStorageForRecovery
{
private Dictionary<string, Dictionary<string, List<ITargetFileVersion>>> Data { get; } = new Dictionary<string, Dictionary<string, List<ITargetFileVersion>>>();
private Dictionary<string, List<ITargetFileVersion>> BlobsInfo { get; } = new Dictionary<string, List<ITargetFileVersion>>();
public Task GetAllDirectories(ActionBlock<ITargetDirectory> actionBlock, CancellationToken ct)
{
return Task.Run(() =>
{
foreach (var kvp in this.Data)
{
if (ct.IsCancellationRequested)
{
break;
}
actionBlock.Post(new TargetDirectory(this, kvp.Key, kvp.Value));
}
actionBlock.Complete();
});
}
public Task GetBlobUsages(string hash, ActionBlock<ITargetFileVersion> actionBlock, CancellationToken ct)
{
return Task.Run(() =>
{
if (!this.BlobsInfo.ContainsKey(hash))
{
actionBlock.Complete();
return;
}
foreach (var fileVersion in this.BlobsInfo[hash])
{
if (ct.IsCancellationRequested)
{
break;
}
actionBlock.Post(fileVersion);
}
actionBlock.Complete();
});
}
public Task<ITargetDirectory> GetDirectory(string normalizedRelativeDirectoryPath)
{
return Task.Run(() =>
{
if (!this.Data.ContainsKey(normalizedRelativeDirectoryPath))
{
this.Data[normalizedRelativeDirectoryPath] = new Dictionary<string, List<ITargetFileVersion>>();
}
return (ITargetDirectory)new TargetDirectory(this, normalizedRelativeDirectoryPath, this.Data[normalizedRelativeDirectoryPath]);
});
}
public Task<ITargetFile> GetFile(string normalizedRelativeDirectoryPath, string filename)
{
return Task.Run(() =>
{
if (!this.Data.ContainsKey(normalizedRelativeDirectoryPath))
{
this.Data[normalizedRelativeDirectoryPath] = new Dictionary<string, List<ITargetFileVersion>>();
}
if (!this.Data[normalizedRelativeDirectoryPath].ContainsKey(filename))
{
this.Data[normalizedRelativeDirectoryPath][filename] = new List<ITargetFileVersion>();
}
return (ITargetFile)new TargetFile(this.Data[normalizedRelativeDirectoryPath][filename]);
});
}
public void AddBlob(ITargetFileVersion fileVersion)
{
if (!this.BlobsInfo.ContainsKey(fileVersion.Hash))
{
this.BlobsInfo[fileVersion.Hash] = new List<ITargetFileVersion>();
}
this.BlobsInfo[fileVersion.Hash].Add(fileVersion);
}
}
}

@ -0,0 +1,62 @@
namespace EternalArrowBackup.TargetMetadataStorage.InMemoryMetadataStorage
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using EternalArrowBackup.TargetMetadataStorage.Contracts;
internal class TargetDirectory : ITargetDirectory
{
public TargetDirectory(MetadataStorage metadataStorage, string directoryName, Dictionary<string, List<ITargetFileVersion>> files)
{
this.MetadataStorage = metadataStorage;
this.DirectoryName = directoryName;
this.Files = files;
}
public string DirectoryName { get; }
private MetadataStorage MetadataStorage { get; }
private Dictionary<string, List<ITargetFileVersion>> Files { get; }
public Task GetAllLatestFileVersions(ActionBlock<ITargetFileVersion> actionBlock, CancellationToken ct)
{
return Task.Run(() =>
{
foreach (var file in this.Files.Values)
{
if (ct.IsCancellationRequested)
{
break;
}
if (file.Any())
{
actionBlock.Post(file.Last());
}
}
actionBlock.Complete();
});
}
public Task UploadFile(string filename, string originalHash, long originalSize)
{
return Task.Run(() =>
{
if (!this.Files.ContainsKey(filename))
{
this.Files[filename] = new List<ITargetFileVersion>();
}
var fileVersion = new TargetFileVersion(filename, originalHash, DateTime.UtcNow, originalSize);
this.Files[filename].Add(fileVersion);
MetadataStorage.AddBlob(fileVersion);
});
}
}
}

@ -0,0 +1,36 @@
namespace EternalArrowBackup.TargetMetadataStorage.InMemoryMetadataStorage
{
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using EternalArrowBackup.TargetMetadataStorage.Contracts;
internal class TargetFile : ITargetFile
{
public TargetFile(List<ITargetFileVersion> versions)
{
this.Versions = versions;
}
private List<ITargetFileVersion> Versions { get; }
public Task GetAllVersions(ActionBlock<ITargetFileVersion> actionBlock, CancellationToken ct)
{
return Task.Run(() =>
{
foreach (var version in this.Versions)
{
if (ct.IsCancellationRequested)
{
break;
}
actionBlock.Post(version);
}
actionBlock.Complete();
});
}
}
}

@ -0,0 +1,24 @@
namespace EternalArrowBackup.TargetMetadataStorage.InMemoryMetadataStorage
{
using System;
using EternalArrowBackup.TargetMetadataStorage.Contracts;
internal class TargetFileVersion : ITargetFileVersion
{
public TargetFileVersion(string filename, string hash, DateTime uploadDate, long size)
{
this.Filename = filename;
this.Hash = hash;
this.UploadDate = uploadDate;
this.Size = size;
}
public string Filename { get; }
public string Hash { get; }
public DateTime UploadDate { get; }
public long Size { get; }
}
}
Loading…
Cancel
Save