|
|
@ -12,6 +12,7 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private readonly StoreOptions<TKey, TInput, TValue, TMeta> _options;
|
|
|
|
private readonly StoreOptions<TKey, TInput, TValue, TMeta> _options;
|
|
|
|
private readonly string _catalog;
|
|
|
|
private readonly string _catalog;
|
|
|
|
|
|
|
|
private readonly string _indexCatalog;
|
|
|
|
private readonly TMeta _info;
|
|
|
|
private readonly TMeta _info;
|
|
|
|
|
|
|
|
|
|
|
|
public string Catalog { get { return _catalog; } }
|
|
|
|
public string Catalog { get { return _catalog; } }
|
|
|
@ -21,6 +22,10 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
_info = info;
|
|
|
|
_info = info;
|
|
|
|
_options = options;
|
|
|
|
_options = options;
|
|
|
|
_catalog = _options.GetCatalogPath(info);
|
|
|
|
_catalog = _options.GetCatalogPath(info);
|
|
|
|
|
|
|
|
if (_options.Index.Enabled)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_indexCatalog = Path.Combine(_catalog, "__indexes__");
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public int CountDataFiles() => Directory.GetFiles(_catalog)?.Length ?? 0;
|
|
|
|
public int CountDataFiles() => Directory.GetFiles(_catalog)?.Length ?? 0;
|
|
|
@ -72,7 +77,7 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public IEnumerable<StorePartitionKeyValueSearchResult<TKey, TValue>> Find(IEnumerable<TKey> keys)
|
|
|
|
public IEnumerable<StorePartitionKeyValueSearchResult<TKey, TValue>> Find(IEnumerable<TKey> keys)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var results = keys
|
|
|
|
var results = keys.Distinct()
|
|
|
|
.GroupBy(
|
|
|
|
.GroupBy(
|
|
|
|
k => _options.GetFileName(k, _info),
|
|
|
|
k => _options.GetFileName(k, _info),
|
|
|
|
k => k, (key, g) => new { FileName = key, Keys = g.ToArray() });
|
|
|
|
k => k, (key, g) => new { FileName = key, Keys = g.ToArray() });
|
|
|
@ -123,15 +128,25 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (_options.Index.Enabled)
|
|
|
|
if (_options.Index.Enabled)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var indexFolder = Path.Combine(_catalog, "__indexes__");
|
|
|
|
FSUtils.CleanAndTestFolder(_indexCatalog);
|
|
|
|
FSUtils.CleanAndTestFolder(indexFolder);
|
|
|
|
|
|
|
|
var files = Directory.GetFiles(_catalog);
|
|
|
|
var files = Directory.GetFiles(_catalog);
|
|
|
|
if (files != null && files.Length > 0)
|
|
|
|
if (files != null && files.Length > 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var dict = new Dictionary<TKey, long>();
|
|
|
|
|
|
|
|
foreach (var file in files)
|
|
|
|
foreach (var file in files)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
dict.Clear();
|
|
|
|
RebuildFileIndex(file);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void RebuildFileIndex(string file)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (false == Directory.Exists(_indexCatalog))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Directory.CreateDirectory(_indexCatalog);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var dict = new Dictionary<TKey, long>();
|
|
|
|
using (var reader = GetReadStream(Path.GetFileName(file)))
|
|
|
|
using (var reader = GetReadStream(Path.GetFileName(file)))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
while (reader.EOS == false)
|
|
|
|
while (reader.EOS == false)
|
|
|
@ -145,7 +160,7 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
if (dict.Count > _options.Index.FileIndexCount * 8)
|
|
|
|
if (dict.Count > _options.Index.FileIndexCount * 8)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var step = (int)Math.Round(((float)dict.Count / (float)_options.Index.FileIndexCount), MidpointRounding.ToZero);
|
|
|
|
var step = (int)Math.Round(((float)dict.Count / (float)_options.Index.FileIndexCount), MidpointRounding.ToZero);
|
|
|
|
var index_file = Path.Combine(indexFolder, Path.GetFileName(file));
|
|
|
|
var index_file = Path.Combine(_indexCatalog, Path.GetFileName(file));
|
|
|
|
var d_arr = dict.OrderBy(p => p.Key).ToArray();
|
|
|
|
var d_arr = dict.OrderBy(p => p.Key).ToArray();
|
|
|
|
using (var writer = new MemoryStreamWriter(
|
|
|
|
using (var writer = new MemoryStreamWriter(
|
|
|
|
new FileStream(index_file, FileMode.Create, FileAccess.Write, FileShare.None)))
|
|
|
|
new FileStream(index_file, FileMode.Create, FileAccess.Write, FileShare.None)))
|
|
|
@ -159,9 +174,6 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Private methods
|
|
|
|
#region Private methods
|
|
|
|
private IEnumerable<StorePartitionKeyValueSearchResult<TKey, TValue>> Find(string fileName,
|
|
|
|
private IEnumerable<StorePartitionKeyValueSearchResult<TKey, TValue>> Find(string fileName,
|
|
|
@ -259,10 +271,10 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
|
|
|
|
|
|
|
|
public void RemoveAllExceptKeys(IEnumerable<TKey> keys)
|
|
|
|
public void RemoveAllExceptKeys(IEnumerable<TKey> keys)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var results = keys
|
|
|
|
var results = keys.Distinct()
|
|
|
|
.GroupBy(
|
|
|
|
.GroupBy(
|
|
|
|
k => _options.GetFileName(k, _info),
|
|
|
|
k => _options.GetFileName(k, _info),
|
|
|
|
k => k, (key, g) => new { FileName = key, Keys = g.ToArray() });
|
|
|
|
k => k, (key, g) => new { FileName = key, Keys = g.OrderBy(k => k).ToArray() });
|
|
|
|
foreach (var group in results)
|
|
|
|
foreach (var group in results)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
RemoveKeyGroup(group.FileName, group.Keys, false);
|
|
|
|
RemoveKeyGroup(group.FileName, group.Keys, false);
|
|
|
@ -276,10 +288,10 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
|
|
|
|
|
|
|
|
public void RemoveKeys(IEnumerable<TKey> keys)
|
|
|
|
public void RemoveKeys(IEnumerable<TKey> keys)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var results = keys
|
|
|
|
var results = keys.Distinct()
|
|
|
|
.GroupBy(
|
|
|
|
.GroupBy(
|
|
|
|
k => _options.GetFileName(k, _info),
|
|
|
|
k => _options.GetFileName(k, _info),
|
|
|
|
k => k, (key, g) => new { FileName = key, Keys = g.ToArray() });
|
|
|
|
k => k, (key, g) => new { FileName = key, Keys = g.OrderBy(k => k).ToArray() });
|
|
|
|
foreach (var group in results)
|
|
|
|
foreach (var group in results)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
RemoveKeyGroup(group.FileName, group.Keys, true);
|
|
|
|
RemoveKeyGroup(group.FileName, group.Keys, true);
|
|
|
@ -388,6 +400,12 @@ namespace ZeroLevel.Services.PartitionStorage
|
|
|
|
|
|
|
|
|
|
|
|
// 3. Replace from temporary to original
|
|
|
|
// 3. Replace from temporary to original
|
|
|
|
File.Move(tempFile, filePath, true);
|
|
|
|
File.Move(tempFile, filePath, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Rebuild index if needs
|
|
|
|
|
|
|
|
if (_options.Index.Enabled)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
RebuildFileIndex(filePath);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|