|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using ZeroLevel.Services.FileSystem;
|
|
|
|
|
|
|
|
|
|
namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Options
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="TKey">Record key</typeparam>
|
|
|
|
|
/// <typeparam name="TInput">The value that is written in the stream</typeparam>
|
|
|
|
|
/// <typeparam name="TValue">Value after compression of TInput values by duplicate keys (TInput list or similar)</typeparam>
|
|
|
|
|
/// <typeparam name="TMeta">Meta information for partition search</typeparam>
|
|
|
|
|
public class StoreOptions<TKey, TInput, TValue, TMeta>
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Method for key comparison
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Func<TKey, TKey, int> KeyComparer { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Storage root directory
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string RootFolder { get; set; }
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Maximum degree of parallelis
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int MaxDegreeOfParallelism { get; set; } = 64;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Function for translating a list of TInput into one TValue
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Func<IEnumerable<TInput>, TValue> MergeFunction { get; set; }
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// List of partitions for accessing the catalog
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<StoreCatalogPartition<TMeta>> Partitions { get; set; } = new List<StoreCatalogPartition<TMeta>>();
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// File Partition
|
|
|
|
|
/// </summary>
|
|
|
|
|
public StoreFilePartition<TKey, TMeta> FilePartition { get; set; }
|
|
|
|
|
|
|
|
|
|
public IndexOptions Index { get; set; } = new IndexOptions
|
|
|
|
|
{
|
|
|
|
|
Enabled = false,
|
|
|
|
|
FileIndexCount = 64
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
internal string GetFileName(TKey key, TMeta info)
|
|
|
|
|
{
|
|
|
|
|
return FilePartition.PathExtractor(key, info);
|
|
|
|
|
}
|
|
|
|
|
internal string GetCatalogPath(TMeta info)
|
|
|
|
|
{
|
|
|
|
|
var path = RootFolder;
|
|
|
|
|
foreach (var partition in Partitions)
|
|
|
|
|
{
|
|
|
|
|
var pathPart = partition.PathExtractor(info);
|
|
|
|
|
pathPart = FSUtils.FileNameCorrection(pathPart);
|
|
|
|
|
if (string.IsNullOrWhiteSpace(pathPart))
|
|
|
|
|
{
|
|
|
|
|
throw new Exception($"Partition '{partition.Name}' not return name of part of path");
|
|
|
|
|
}
|
|
|
|
|
path = Path.Combine(path, pathPart);
|
|
|
|
|
}
|
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public StoreOptions<TKey, TInput, TValue, TMeta> Clone()
|
|
|
|
|
{
|
|
|
|
|
var options = new StoreOptions<TKey, TInput, TValue, TMeta>
|
|
|
|
|
{
|
|
|
|
|
Index = new IndexOptions
|
|
|
|
|
{
|
|
|
|
|
Enabled = this.Index.Enabled,
|
|
|
|
|
FileIndexCount = this.Index.FileIndexCount
|
|
|
|
|
},
|
|
|
|
|
FilePartition = this.FilePartition,
|
|
|
|
|
KeyComparer = this.KeyComparer,
|
|
|
|
|
MaxDegreeOfParallelism = this.MaxDegreeOfParallelism,
|
|
|
|
|
MergeFunction = this.MergeFunction,
|
|
|
|
|
Partitions = this.Partitions
|
|
|
|
|
.Select(p => new StoreCatalogPartition<TMeta>(p.Name, p.PathExtractor))
|
|
|
|
|
.ToList(),
|
|
|
|
|
RootFolder = this.RootFolder
|
|
|
|
|
};
|
|
|
|
|
return options;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|