Changed various locking mechanism.
This commit is contained in:
@ -46,13 +46,26 @@ namespace HermesSocketServer.Store.Internal
|
||||
private async Task GenerateQuery(IList<K> keys, Func<int, string> generate, Func<string, IEnumerable<K>, IEnumerable<V>, Task<int>> execute)
|
||||
{
|
||||
ImmutableList<K>? list = null;
|
||||
lock (_lock)
|
||||
_rwls.EnterUpgradeableReadLock();
|
||||
try
|
||||
{
|
||||
if (!keys.Any())
|
||||
return;
|
||||
|
||||
list = keys.ToImmutableList();
|
||||
keys.Clear();
|
||||
_rwls.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
list = keys.ToImmutableList();
|
||||
keys.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitUpgradeableReadLock();
|
||||
}
|
||||
|
||||
var query = generate(list.Count);
|
||||
|
@ -51,13 +51,26 @@ namespace HermesSocketServer.Store.Internal
|
||||
private async Task GenerateQuery(IList<K> keys, Func<int, string> generate, Func<string, IEnumerable<K>, IEnumerable<V?>, Task<int>> execute)
|
||||
{
|
||||
ImmutableList<K>? list = null;
|
||||
lock (_lock)
|
||||
_rwls.EnterUpgradeableReadLock();
|
||||
try
|
||||
{
|
||||
if (!keys.Any())
|
||||
return;
|
||||
|
||||
list = keys.ToImmutableList();
|
||||
keys.Clear();
|
||||
_rwls.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
list = keys.ToImmutableList();
|
||||
keys.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitUpgradeableReadLock();
|
||||
}
|
||||
|
||||
var query = generate(list.Count);
|
||||
@ -77,16 +90,27 @@ namespace HermesSocketServer.Store.Internal
|
||||
private async Task GenerateDeleteQuery(IList<K> keys, IList<V> values, Func<int, string> generate, Func<string, IEnumerable<V>, Task<int>> execute)
|
||||
{
|
||||
ImmutableList<V>? list = null;
|
||||
lock (_lock)
|
||||
_rwls.EnterUpgradeableReadLock();
|
||||
try
|
||||
{
|
||||
if (!keys.Any() || !values.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
list = values.ToImmutableList();
|
||||
values.Clear();
|
||||
keys.Clear();
|
||||
_rwls.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
list = values.ToImmutableList();
|
||||
values.Clear();
|
||||
keys.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitUpgradeableReadLock();
|
||||
}
|
||||
|
||||
var query = generate(list.Count);
|
||||
|
@ -10,7 +10,7 @@ namespace HermesSocketServer.Store.Internal
|
||||
protected readonly IList<K> _added;
|
||||
protected readonly IList<K> _modified;
|
||||
protected readonly IList<K> _deleted;
|
||||
protected readonly object _lock;
|
||||
protected readonly ReaderWriterLockSlim _rwls;
|
||||
|
||||
|
||||
public GroupSaveStore()
|
||||
@ -19,7 +19,7 @@ namespace HermesSocketServer.Store.Internal
|
||||
_added = new List<K>();
|
||||
_modified = new List<K>();
|
||||
_deleted = new List<K>();
|
||||
_lock = new object();
|
||||
_rwls = new ReaderWriterLockSlim();
|
||||
}
|
||||
|
||||
public abstract Task Load();
|
||||
@ -28,22 +28,46 @@ namespace HermesSocketServer.Store.Internal
|
||||
protected abstract void OnPostRemove(K key, V value);
|
||||
public abstract Task Save();
|
||||
|
||||
|
||||
public bool Exists(K key)
|
||||
{
|
||||
_rwls.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return _store.ContainsKey(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public V? Get(K key)
|
||||
{
|
||||
lock (_lock)
|
||||
_rwls.EnterReadLock();
|
||||
try
|
||||
{
|
||||
if (_store.TryGetValue(key, out var value))
|
||||
return value;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitReadLock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<K, V> Get()
|
||||
{
|
||||
lock (_lock)
|
||||
_rwls.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return _store.ToImmutableDictionary();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Modify(K? key, V value)
|
||||
@ -51,19 +75,32 @@ namespace HermesSocketServer.Store.Internal
|
||||
if (key == null)
|
||||
return false;
|
||||
|
||||
lock (_lock)
|
||||
_rwls.EnterUpgradeableReadLock();
|
||||
try
|
||||
{
|
||||
if (_store.TryGetValue(key, out V? oldValue))
|
||||
{
|
||||
OnInitialModify(key, oldValue, value);
|
||||
_store[key] = value;
|
||||
if (!_added.Contains(key) && !_modified.Contains(key))
|
||||
_rwls.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
_modified.Add(key);
|
||||
OnInitialModify(key, oldValue, value);
|
||||
_store[key] = value;
|
||||
if (!_added.Contains(key) && !_modified.Contains(key))
|
||||
{
|
||||
_modified.Add(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitWriteLock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitUpgradeableReadLock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -72,18 +109,31 @@ namespace HermesSocketServer.Store.Internal
|
||||
if (key == null)
|
||||
return false;
|
||||
|
||||
lock (_lock)
|
||||
_rwls.EnterUpgradeableReadLock();
|
||||
try
|
||||
{
|
||||
if (_store.TryGetValue(key, out V? value))
|
||||
{
|
||||
modify(value);
|
||||
if (!_added.Contains(key) && !_modified.Contains(key))
|
||||
_rwls.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
_modified.Add(key);
|
||||
modify(value);
|
||||
if (!_added.Contains(key) && !_modified.Contains(key))
|
||||
{
|
||||
_modified.Add(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitWriteLock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitUpgradeableReadLock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -92,25 +142,28 @@ namespace HermesSocketServer.Store.Internal
|
||||
if (key == null)
|
||||
return false;
|
||||
|
||||
lock (_lock)
|
||||
_rwls.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
if (_store.TryGetValue(key, out var value))
|
||||
{
|
||||
if (_store.Remove(key))
|
||||
_store.Remove(key);
|
||||
OnPostRemove(key, value);
|
||||
if (!_added.Remove(key))
|
||||
{
|
||||
OnPostRemove(key, value);
|
||||
if (!_added.Remove(key))
|
||||
_modified.Remove(key);
|
||||
if (!fromCascade && !_deleted.Contains(key))
|
||||
{
|
||||
_modified.Remove(key);
|
||||
if (!fromCascade && !_deleted.Contains(key))
|
||||
{
|
||||
_deleted.Add(key);
|
||||
}
|
||||
_deleted.Add(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rwls.ExitWriteLock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -119,20 +172,18 @@ namespace HermesSocketServer.Store.Internal
|
||||
if (key == null)
|
||||
return false;
|
||||
|
||||
lock (_lock)
|
||||
_rwls.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
if (_store.TryGetValue(key, out V? fetched))
|
||||
{
|
||||
if (fetched != value)
|
||||
OnInitialModify(key, fetched, value);
|
||||
_store[key] = value;
|
||||
if (!_added.Contains(key) && !_modified.Contains(key))
|
||||
{
|
||||
OnInitialModify(key, fetched, value);
|
||||
_store[key] = value;
|
||||
if (!_added.Contains(key) && !_modified.Contains(key))
|
||||
{
|
||||
_modified.Add(key);
|
||||
}
|
||||
return true;
|
||||
_modified.Add(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -145,7 +196,10 @@ namespace HermesSocketServer.Store.Internal
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
finally
|
||||
{
|
||||
_rwls.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user