You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/PartitionStorage/Partition/BasePartition.cs

204 lines
7.0 KiB

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using ZeroLevel.Services.FileSystem;
using ZeroLevel.Services.Memory;
using ZeroLevel.Services.PartitionStorage.Interfaces;
using ZeroLevel.Services.Serialization;
namespace ZeroLevel.Services.PartitionStorage.Partition
{
/// <summary>
/// General operations with a partition
/// </summary>
internal abstract class BasePartition<TKey, TInput, TValue, TMeta>
: IStorePartitionBase<TKey, TInput, TValue>
{
public string Catalog { get { return _catalog; } }
protected readonly TMeta _info;
protected readonly string _catalog;
protected IStoreSerializer<TKey, TInput, TValue> Serializer { get; }
protected readonly StoreOptions<TKey, TInput, TValue, TMeta> _options;
private readonly IndexBuilder<TKey, TValue> _indexBuilder;
private readonly Dictionary<string, MemoryStreamWriter> _writeStreams = new Dictionary<string, MemoryStreamWriter>();
private readonly PhisicalFileAccessorCachee _phisicalFileAccessor;
protected PhisicalFileAccessorCachee PhisicalFileAccessorCachee => _phisicalFileAccessor;
internal BasePartition(StoreOptions<TKey, TInput, TValue, TMeta> options,
TMeta info,
IStoreSerializer<TKey, TInput, TValue> serializer, PhisicalFileAccessorCachee fileAccessorCachee)
{
_options = options;
_info = info;
_catalog = _options.GetCatalogPath(info);
if (Directory.Exists(_catalog) == false)
{
Directory.CreateDirectory(_catalog);
}
_phisicalFileAccessor = fileAccessorCachee;
_indexBuilder = _options.Index.Enabled ? new IndexBuilder<TKey, TValue>(_options.Index.StepType, _options.Index.StepValue, _catalog, fileAccessorCachee) : null;
Serializer = serializer;
}
#region IStorePartitionBase
public int CountDataFiles() => Directory.Exists(_catalog) ? (Directory.GetFiles(_catalog)?.Length ?? 0) : 0;
public string GetCatalogPath() => _catalog;
public void DropData() => FSUtils.CleanAndTestFolder(_catalog);
public void Dispose()
{
CloseWriteStreams();
Release();
}
#endregion
public abstract void Release();
/// <summary>
/// Rebuild indexes for all files
/// </summary>
protected void RebuildIndexes()
{
if (_options.Index.Enabled)
{
_indexBuilder.RebuildIndex();
}
}
/// <summary>
/// Rebuild index for the specified file
/// </summary>
internal void RebuildFileIndex(string file)
{
if (_options.Index.Enabled)
{
_indexBuilder.RebuildFileIndex(file);
}
}
/// <summary>
/// Delete the index for the specified file
/// </summary>
internal void DropFileIndex(string file)
{
if (_options.Index.Enabled)
{
_indexBuilder.DropFileIndex(file);
}
}
/// <summary>
/// Close all streams for writing
/// </summary>
protected void CloseWriteStreams()
{
foreach (var s in _writeStreams)
{
try
{
s.Value.Stream.Flush();
s.Value.Dispose();
}
catch { }
}
_writeStreams.Clear();
}
/// <summary>
/// Attempting to open a file for writing
/// </summary>
protected bool TryGetWriteStream(string fileName, out MemoryStreamWriter writer)
{
try
{
bool taken = false;
Monitor.Enter(_writeStreams, ref taken);
try
{
if (_writeStreams.TryGetValue(fileName, out var w))
{
writer = w;
return true;
}
else
{
var filePath = Path.Combine(_catalog, fileName);
var stream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None, 4096 * 1024);
var new_w = new MemoryStreamWriter(stream);
_writeStreams[fileName] = new_w;
writer = new_w;
return true;
}
}
finally
{
if (taken)
{
Monitor.Exit(_writeStreams);
}
}
}
catch (Exception ex)
{
Log.SystemError(ex, "[StorePartitionBuilder.TryGetWriteStream]");
}
writer = null;
return false;
}
/// <summary>
/// Attempting to open a file for reading
/// </summary>
protected bool TryGetReadStream(string fileName, out MemoryStreamReader reader)
{
try
{
var filePath = Path.Combine(_catalog, fileName);
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096 * 1024);
reader = new MemoryStreamReader(stream);
return true;
}
catch (Exception ex)
{
Log.SystemError(ex, "[StorePartitionBuilder.TryGetReadStream]");
}
reader = null;
return false;
}
protected IViewAccessor GetViewAccessor(TKey key, long offset)
{
var fileName = _options.GetFileName(key, _info);
var filePath = Path.Combine(_catalog, fileName);
return GetViewAccessor(filePath, offset);
}
protected IViewAccessor GetViewAccessor(TKey key, long offset, int length)
{
var fileName = _options.GetFileName(key, _info);
var filePath = Path.Combine(_catalog, fileName);
return GetViewAccessor(filePath, offset, length);
}
protected IViewAccessor GetViewAccessor(string filePath, long offset)
{
try
{
return PhisicalFileAccessorCachee.GetDataAccessor(filePath, offset);
}
catch (Exception ex)
{
Log.SystemError(ex, $"[StorePartitionAccessor.GetViewAccessor] '{filePath}'");
}
return null;
}
protected IViewAccessor GetViewAccessor(string filePath, long offset, int length)
{
try
{
return PhisicalFileAccessorCachee.GetDataAccessor(filePath, offset, length);
}
catch (Exception ex)
{
Log.SystemError(ex, $"[StorePartitionAccessor.GetViewAccessor] '{filePath}'");
}
return null;
}
}
}

Powered by TurnKey Linux.