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/PhisicalFileAccessorCachee.cs

154 lines
4.9 KiB

using System;
using System.IO;
using ZeroLevel.Collections;
using ZeroLevel.Services.Cache;
using ZeroLevel.Services.FileSystem;
using ZeroLevel.Services.Memory;
namespace ZeroLevel.Services.PartitionStorage
{
internal sealed class PhisicalFileAccessorCachee
: IDisposable
{
private readonly TimerCachee<ParallelFileReader> _indexReadersCachee;
private readonly TimerCachee<ParallelFileReader> _dataReadersCachee;
private readonly ConcurrentHashSet<string> _lockedFiles = new ConcurrentHashSet<string>();
public PhisicalFileAccessorCachee(TimeSpan dataExpirationPeriod, TimeSpan indexExpirationPeriod)
{
_dataReadersCachee = new TimerCachee<ParallelFileReader>(dataExpirationPeriod, s => new ParallelFileReader(s), i => i.Dispose(), 8192);
_indexReadersCachee = new TimerCachee<ParallelFileReader>(indexExpirationPeriod, s => new ParallelFileReader(s), i => i.Dispose(), 8192);
}
#region DATA
public void DropDataReader(string filePath)
{
_dataReadersCachee.Drop(filePath);
}
private ParallelFileReader GetDataReader(string filePath)
{
if (File.Exists(filePath) == false)
throw new FileNotFoundException(filePath);
return _dataReadersCachee.Get(filePath);
}
public IViewAccessor GetDataAccessor(string filePath, long offset)
{
if (false == _lockedFiles.Contains(filePath))
{
var reader = GetDataReader(filePath);
try
{
return reader.GetAccessor(offset);
}
catch (ObjectDisposedException)
{
_dataReadersCachee.Drop(filePath);
reader = _dataReadersCachee.Get(filePath);
}
return reader.GetAccessor(offset);
}
return null!;
}
public IViewAccessor GetDataAccessor(string filePath, long offset, int length)
{
if (false == _lockedFiles.Contains(filePath))
{
var reader = GetDataReader(filePath);
try
{
return reader.GetAccessor(offset, length);
}
catch (ObjectDisposedException)
{
_dataReadersCachee.Drop(filePath);
reader = _dataReadersCachee.Get(filePath);
}
return reader.GetAccessor(offset, length);
}
return null!;
}
public void DropAllDataReaders()
{
_dataReadersCachee.DropAll();
}
#endregion
#region Indexes
public void DropIndexReader(string filePath)
{
_indexReadersCachee.Drop(filePath);
}
private ParallelFileReader GetIndexReader(string filePath)
{
if (File.Exists(filePath) == false)
throw new FileNotFoundException(filePath);
return _indexReadersCachee.Get(filePath);
}
public IViewAccessor GetIndexAccessor(string filePath, long offset)
{
if (false == _lockedFiles.Contains(filePath))
{
var reader = GetIndexReader(filePath);
try
{
return reader.GetAccessor(offset);
}
catch (ObjectDisposedException)
{
_indexReadersCachee.Drop(filePath);
reader = _indexReadersCachee.Get(filePath);
}
return reader.GetAccessor(offset);
}
return null!;
}
public IViewAccessor GetIndexAccessor(string filePath, long offset, int length)
{
if (false == _lockedFiles.Contains(filePath))
{
var reader = GetIndexReader(filePath);
try
{
return reader.GetAccessor(offset, length);
}
catch (ObjectDisposedException)
{
_indexReadersCachee.Drop(filePath);
reader = _indexReadersCachee.Get(filePath);
}
return reader.GetAccessor(offset, length);
}
return null!;
}
public void DropAllIndexReaders()
{
_indexReadersCachee.DropAll();
}
#endregion
public void LockFile(string filePath)
{
_lockedFiles.Add(filePath);
DropDataReader(filePath);
DropIndexReader(filePath);
}
public void UnlockFile(string filePath)
{
_lockedFiles.TryRemove(filePath);
}
public void Dispose()
{
_lockedFiles.Clear();
_dataReadersCachee.Dispose();
_indexReadersCachee.Dispose();
}
}
}

Powered by TurnKey Linux.