Fix concurrent work. Partition storage

pull/4/head
Ogoun 2 years ago
parent f4e014b0e5
commit cebcb9feb2

@ -57,18 +57,27 @@ namespace ZeroLevel.Services.PartitionStorage
RebuildFileIndexWithSteps(file); RebuildFileIndexWithSteps(file);
} }
} }
/// <summary> /// <summary>
/// Delete the index for the specified file /// Delete the index for the specified file
/// </summary> /// </summary>
internal void DropFileIndex(string file) internal void DropFileIndex(string file)
{ {
var index_file = Path.Combine(_indexCatalog, Path.GetFileName(file)); var index_file = Path.Combine(_indexCatalog, Path.GetFileName(file));
_phisicalFileAccessorCachee.DropIndexReader(index_file); _phisicalFileAccessorCachee.LockFile(index_file);
try
{
if (File.Exists(index_file)) if (File.Exists(index_file))
{ {
File.Delete(index_file); File.Delete(index_file);
} }
} }
finally
{
_phisicalFileAccessorCachee.UnlockFile(index_file);
}
}
/// <summary> /// <summary>
/// Rebuild index with specified number of steps for specified file /// Rebuild index with specified number of steps for specified file
/// </summary> /// </summary>
@ -93,7 +102,14 @@ namespace ZeroLevel.Services.PartitionStorage
{ {
var step = (int)Math.Round(dict.Count / (float)_stepValue, MidpointRounding.ToZero); var step = (int)Math.Round(dict.Count / (float)_stepValue, MidpointRounding.ToZero);
var index_file = Path.Combine(_indexCatalog, Path.GetFileName(file)); var index_file = Path.Combine(_indexCatalog, Path.GetFileName(file));
DropFileIndex(index_file);
_phisicalFileAccessorCachee.LockFile(index_file);
if (File.Exists(index_file))
{
File.Delete(index_file);
}
try
{
var d_arr = dict.OrderBy(p => p.Key).ToArray(); var d_arr = dict.OrderBy(p => p.Key).ToArray();
using (var writer = new MemoryStreamWriter(new FileStream(index_file, FileMode.Create, FileAccess.Write, FileShare.None))) using (var writer = new MemoryStreamWriter(new FileStream(index_file, FileMode.Create, FileAccess.Write, FileShare.None)))
{ {
@ -105,6 +121,11 @@ namespace ZeroLevel.Services.PartitionStorage
} }
} }
} }
finally
{
_phisicalFileAccessorCachee.UnlockFile(index_file);
}
}
} }
/// <summary> /// <summary>
/// Rebuild index with specified step for keys /// Rebuild index with specified step for keys
@ -118,7 +139,13 @@ namespace ZeroLevel.Services.PartitionStorage
using (var reader = new MemoryStreamReader(new FileStream(Path.Combine(_dataCatalog, file), FileMode.Open, FileAccess.Read, FileShare.None))) using (var reader = new MemoryStreamReader(new FileStream(Path.Combine(_dataCatalog, file), FileMode.Open, FileAccess.Read, FileShare.None)))
{ {
var index_file = Path.Combine(_indexCatalog, Path.GetFileName(file)); var index_file = Path.Combine(_indexCatalog, Path.GetFileName(file));
DropFileIndex(index_file); _phisicalFileAccessorCachee.LockFile(index_file);
if (File.Exists(index_file))
{
File.Delete(index_file);
}
try
{
using (var writer = new MemoryStreamWriter(new FileStream(index_file, FileMode.Create, FileAccess.Write, FileShare.None))) using (var writer = new MemoryStreamWriter(new FileStream(index_file, FileMode.Create, FileAccess.Write, FileShare.None)))
{ {
var counter = 1; var counter = 1;
@ -137,6 +164,11 @@ namespace ZeroLevel.Services.PartitionStorage
} }
} }
} }
finally
{
_phisicalFileAccessorCachee.UnlockFile(index_file);
}
}
} }
} }
} }

@ -124,6 +124,9 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
TKey key; TKey key;
TInput input; TInput input;
var dict = new Dictionary<TKey, HashSet<TInput>>(); var dict = new Dictionary<TKey, HashSet<TInput>>();
PhisicalFileAccessorCachee.LockFile(file);
try
{
using (var reader = new MemoryStreamReader(new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.None, 4096 * 1024))) using (var reader = new MemoryStreamReader(new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.None, 4096 * 1024)))
{ {
while (reader.EOS == false) while (reader.EOS == false)
@ -161,6 +164,11 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
File.Delete(file); File.Delete(file);
File.Move(tempFile, file, true); File.Move(tempFile, file, true);
} }
finally
{
PhisicalFileAccessorCachee.UnlockFile(file);
}
}
#endregion #endregion
} }
} }

@ -115,12 +115,20 @@ namespace ZeroLevel.Services.PartitionStorage
// 2. Replace source // 2. Replace source
var name = Path.GetFileName(file); var name = Path.GetFileName(file);
var updateFilePath = Path.Combine(folder, name); var updateFilePath = Path.Combine(folder, name);
_phisicalFileAccessor.LockFile(updateFilePath);
try
{
if (File.Exists(updateFilePath)) if (File.Exists(updateFilePath))
{ {
_phisicalFileAccessor.DropDataReader(updateFilePath);
File.Delete(updateFilePath); File.Delete(updateFilePath);
} }
File.Move(file, updateFilePath, true); File.Move(file, updateFilePath, true);
}
finally
{
_phisicalFileAccessor.UnlockFile(updateFilePath);
}
// 3. Rebuil index // 3. Rebuil index
(_accessor as BasePartition<TKey, TInput, TValue, TMeta>).RebuildFileIndex(name); (_accessor as BasePartition<TKey, TInput, TValue, TMeta>).RebuildFileIndex(name);

@ -5,6 +5,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ZeroLevel.Services.FileSystem; using ZeroLevel.Services.FileSystem;
using ZeroLevel.Services.Memory;
using ZeroLevel.Services.PartitionStorage.Interfaces; using ZeroLevel.Services.PartitionStorage.Interfaces;
using ZeroLevel.Services.PartitionStorage.Partition; using ZeroLevel.Services.PartitionStorage.Partition;
using ZeroLevel.Services.Serialization; using ZeroLevel.Services.Serialization;
@ -139,8 +140,11 @@ namespace ZeroLevel.Services.PartitionStorage
{ {
TKey key; TKey key;
TInput input; TInput input;
PhisicalFileAccessorCachee.LockFile(file);
try
{
var dict = new Dictionary<TKey, HashSet<TInput>>(); var dict = new Dictionary<TKey, HashSet<TInput>>();
var accessor = PhisicalFileAccessorCachee.GetDataAccessor(file, 0); var accessor = new StreamVewAccessor(new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.None, 1024 * 1024 * 32));
if (accessor != null) if (accessor != null)
{ {
using (var reader = new MemoryStreamReader(accessor)) using (var reader = new MemoryStreamReader(accessor))
@ -167,6 +171,7 @@ namespace ZeroLevel.Services.PartitionStorage
} }
} }
} }
var tempFile = FSUtils.GetAppLocalTemporaryFile(); var tempFile = FSUtils.GetAppLocalTemporaryFile();
using (var writer = new MemoryStreamWriter(new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096 * 1024))) using (var writer = new MemoryStreamWriter(new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096 * 1024)))
{ {
@ -179,10 +184,14 @@ namespace ZeroLevel.Services.PartitionStorage
writer.SerializeCompatible(v); writer.SerializeCompatible(v);
} }
} }
PhisicalFileAccessorCachee.DropDataReader(file);
File.Delete(file); File.Delete(file);
File.Move(tempFile, file, true); File.Move(tempFile, file, true);
} }
finally
{
PhisicalFileAccessorCachee.UnlockFile(file);
}
}
#endregion #endregion
} }
} }

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using ZeroLevel.Services.Cache; using ZeroLevel.Services.Cache;
using ZeroLevel.Services.FileSystem; using ZeroLevel.Services.FileSystem;
@ -12,6 +13,8 @@ namespace ZeroLevel.Services.PartitionStorage
private readonly TimerCachee<ParallelFileReader> _indexReadersCachee; private readonly TimerCachee<ParallelFileReader> _indexReadersCachee;
private readonly TimerCachee<ParallelFileReader> _dataReadersCachee; private readonly TimerCachee<ParallelFileReader> _dataReadersCachee;
private readonly HashSet<string> _lockedFiles = new HashSet<string>();
public PhisicalFileAccessorCachee(TimeSpan dataExpirationPeriod, TimeSpan indexExpirationPeriod) public PhisicalFileAccessorCachee(TimeSpan dataExpirationPeriod, TimeSpan indexExpirationPeriod)
{ {
_dataReadersCachee = new TimerCachee<ParallelFileReader>(dataExpirationPeriod, s => new ParallelFileReader(s), i => i.Dispose(), 8192); _dataReadersCachee = new TimerCachee<ParallelFileReader>(dataExpirationPeriod, s => new ParallelFileReader(s), i => i.Dispose(), 8192);
@ -31,6 +34,8 @@ namespace ZeroLevel.Services.PartitionStorage
return _dataReadersCachee.Get(filePath); return _dataReadersCachee.Get(filePath);
} }
public IViewAccessor GetDataAccessor(string filePath, long offset) public IViewAccessor GetDataAccessor(string filePath, long offset)
{
if (false == _lockedFiles.Contains(filePath))
{ {
var reader = GetDataReader(filePath); var reader = GetDataReader(filePath);
try try
@ -44,8 +49,12 @@ namespace ZeroLevel.Services.PartitionStorage
} }
return reader.GetAccessor(offset); return reader.GetAccessor(offset);
} }
return null;
}
public IViewAccessor GetDataAccessor(string filePath, long offset, int length) public IViewAccessor GetDataAccessor(string filePath, long offset, int length)
{
if (false == _lockedFiles.Contains(filePath))
{ {
var reader = GetDataReader(filePath); var reader = GetDataReader(filePath);
try try
@ -59,6 +68,8 @@ namespace ZeroLevel.Services.PartitionStorage
} }
return reader.GetAccessor(offset, length); return reader.GetAccessor(offset, length);
} }
return null;
}
public void DropAllDataReaders() public void DropAllDataReaders()
{ {
_dataReadersCachee.DropAll(); _dataReadersCachee.DropAll();
@ -78,6 +89,8 @@ namespace ZeroLevel.Services.PartitionStorage
return _indexReadersCachee.Get(filePath); return _indexReadersCachee.Get(filePath);
} }
public IViewAccessor GetIndexAccessor(string filePath, long offset) public IViewAccessor GetIndexAccessor(string filePath, long offset)
{
if (false == _lockedFiles.Contains(filePath))
{ {
var reader = GetIndexReader(filePath); var reader = GetIndexReader(filePath);
try try
@ -91,8 +104,12 @@ namespace ZeroLevel.Services.PartitionStorage
} }
return reader.GetAccessor(offset); return reader.GetAccessor(offset);
} }
return null;
}
public IViewAccessor GetIndexAccessor(string filePath, long offset, int length) public IViewAccessor GetIndexAccessor(string filePath, long offset, int length)
{
if (false == _lockedFiles.Contains(filePath))
{ {
var reader = GetIndexReader(filePath); var reader = GetIndexReader(filePath);
try try
@ -106,12 +123,26 @@ namespace ZeroLevel.Services.PartitionStorage
} }
return reader.GetAccessor(offset, length); return reader.GetAccessor(offset, length);
} }
return null;
}
public void DropAllIndexReaders() public void DropAllIndexReaders()
{ {
_indexReadersCachee.DropAll(); _indexReadersCachee.DropAll();
} }
#endregion #endregion
public void LockFile(string filePath)
{
_lockedFiles.Add(filePath);
DropDataReader(filePath);
DropIndexReader(filePath);
}
public void UnlockFile(string filePath)
{
_lockedFiles.Remove(filePath);
}
public void Dispose() public void Dispose()
{ {
_dataReadersCachee.Dispose(); _dataReadersCachee.Dispose();

@ -6,16 +6,16 @@
</Description> </Description>
<Authors>ogoun</Authors> <Authors>ogoun</Authors>
<Company>ogoun</Company> <Company>ogoun</Company>
<AssemblyVersion>3.3.8.9</AssemblyVersion> <AssemblyVersion>3.3.9.0</AssemblyVersion>
<PackageReleaseNotes>Partition storage. Suppress exception when find invoke</PackageReleaseNotes> <PackageReleaseNotes>Partition storage. Fix concurrent work</PackageReleaseNotes>
<PackageProjectUrl>https://github.com/ogoun/Zero/wiki</PackageProjectUrl> <PackageProjectUrl>https://github.com/ogoun/Zero/wiki</PackageProjectUrl>
<Copyright>Copyright Ogoun 2023</Copyright> <Copyright>Copyright Ogoun 2023</Copyright>
<PackageLicenseUrl></PackageLicenseUrl> <PackageLicenseUrl></PackageLicenseUrl>
<PackageIconUrl></PackageIconUrl> <PackageIconUrl></PackageIconUrl>
<RepositoryUrl>https://github.com/ogoun/Zero</RepositoryUrl> <RepositoryUrl>https://github.com/ogoun/Zero</RepositoryUrl>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<Version>3.3.8.9</Version> <Version>3.3.9.0</Version>
<FileVersion>3.3.8.9</FileVersion> <FileVersion>3.3.9.0</FileVersion>
<Platforms>AnyCPU;x64;x86</Platforms> <Platforms>AnyCPU;x64;x86</Platforms>
<PackageIcon>zero.png</PackageIcon> <PackageIcon>zero.png</PackageIcon>
<DebugType>full</DebugType> <DebugType>full</DebugType>

Loading…
Cancel
Save

Powered by TurnKey Linux.