Skip to content

Commit a6955fc

Browse files
committed
Added IBatchableCacheConcurrencyStrategy and replaced XXXMultiple with XXXMany.
1 parent f141ce0 commit a6955fc

26 files changed

+203
-165
lines changed

src/NHibernate.Test/Async/CacheTest/Caches/BatchableCache.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace NHibernate.Test.CacheTest.Caches
2222
public partial class BatchableCache : ICache, IBatchableReadWriteCache
2323
{
2424

25-
public Task PutMultipleAsync(object[] keys, object[] values, CancellationToken cancellationToken)
25+
public Task PutManyAsync(object[] keys, object[] values, CancellationToken cancellationToken)
2626
{
2727
try
2828
{
@@ -39,7 +39,7 @@ public Task PutMultipleAsync(object[] keys, object[] values, CancellationToken c
3939
}
4040
}
4141

42-
public Task LockMultipleAsync(object[] keys, CancellationToken cancellationToken)
42+
public Task LockManyAsync(object[] keys, CancellationToken cancellationToken)
4343
{
4444
try
4545
{
@@ -52,7 +52,7 @@ public Task LockMultipleAsync(object[] keys, CancellationToken cancellationToken
5252
}
5353
}
5454

55-
public Task UnlockMultipleAsync(object[] keys, CancellationToken cancellationToken)
55+
public Task UnlockManyAsync(object[] keys, CancellationToken cancellationToken)
5656
{
5757
try
5858
{
@@ -81,7 +81,7 @@ public Task<object> GetAsync(object key, CancellationToken cancellationToken)
8181
}
8282
}
8383

84-
public Task<object[]> GetMultipleAsync(object[] keys, CancellationToken cancellationToken)
84+
public Task<object[]> GetManyAsync(object[] keys, CancellationToken cancellationToken)
8585
{
8686
try
8787
{

src/NHibernate.Test/CacheTest/Caches/BatchableCache.cs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ namespace NHibernate.Test.CacheTest.Caches
1212
public partial class BatchableCache : ICache, IBatchableReadWriteCache
1313
{
1414
private readonly IDictionary _hashtable = new Hashtable();
15-
private readonly string _regionName;
1615

1716
public List<object[]> GetMultipleCalls { get; } = new List<object[]>();
1817

@@ -26,7 +25,7 @@ public partial class BatchableCache : ICache, IBatchableReadWriteCache
2625

2726
public List<object> PutCalls { get; } = new List<object>();
2827

29-
public void PutMultiple(object[] keys, object[] values)
28+
public void PutMany(object[] keys, object[] values)
3029
{
3130
PutMultipleCalls.Add(keys);
3231
for (int i = 0; i < keys.Length; i++)
@@ -35,12 +34,12 @@ public void PutMultiple(object[] keys, object[] values)
3534
}
3635
}
3736

38-
public void LockMultiple(object[] keys)
37+
public void LockMany(object[] keys)
3938
{
4039
LockMultipleCalls.Add(keys);
4140
}
4241

43-
public void UnlockMultiple(object[] keys)
42+
public void UnlockMany(object[] keys)
4443
{
4544
UnlockMultipleCalls.Add(keys);
4645
}
@@ -49,7 +48,7 @@ public void UnlockMultiple(object[] keys)
4948

5049
public BatchableCache(string regionName)
5150
{
52-
_regionName = regionName;
51+
RegionName = regionName;
5352
}
5453

5554
/// <summary></summary>
@@ -59,7 +58,7 @@ public object Get(object key)
5958
return _hashtable[key];
6059
}
6160

62-
public object[] GetMultiple(object[] keys)
61+
public object[] GetMany(object[] keys)
6362
{
6463
GetMultipleCalls.Add(keys);
6564
var result = new object[keys.Length];
@@ -123,18 +122,9 @@ public long NextTimestamp()
123122
}
124123

125124
/// <summary></summary>
126-
public int Timeout
127-
{
128-
get
129-
{
130-
return Timestamper.OneMs * 60000; // ie. 60 seconds
131-
}
132-
}
125+
public int Timeout => Timestamper.OneMs * 60000;
133126

134-
public string RegionName
135-
{
136-
get { return _regionName; }
137-
}
127+
public string RegionName { get; }
138128

139129
#endregion
140130
}

src/NHibernate/Async/Cache/CachePutBatch.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ protected override async Task ExecuteAsync(CachePutData[] data, CancellationToke
4444

4545
var factory = Session.Factory;
4646
var cacheStrategy = CacheConcurrencyStrategy;
47-
var puts = await (cacheStrategy.PutMultipleAsync(keys, values, Session.Timestamp, versions, versionComparers, minimalPuts, cancellationToken)).ConfigureAwait(false);
47+
var puts = await (cacheStrategy.PutManyAsync(keys, values, Session.Timestamp, versions, versionComparers, minimalPuts, cancellationToken)).ConfigureAwait(false);
4848

4949
if (factory.Statistics.IsStatisticsEnabled && puts.Any(o => o))
5050
{
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Collections;
13+
using System.Text;
14+
using NHibernate.Cache.Entry;
15+
16+
namespace NHibernate.Cache
17+
{
18+
using System.Threading.Tasks;
19+
using System.Threading;
20+
public partial interface IBatchableCacheConcurrencyStrategy : ICacheConcurrencyStrategy
21+
{
22+
/// <summary>
23+
/// Attempt to retrieve multiple objects from the Cache
24+
/// </summary>
25+
/// <param name="keys">The keys (id) of the objects to get out of the Cache.</param>
26+
/// <param name="timestamp">A timestamp prior to the transaction start time</param>
27+
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
28+
/// <returns>An array of cached objects or <see langword="null" /></returns>
29+
/// <exception cref="CacheException"></exception>
30+
Task<object[]> GetManyAsync(CacheKey[] keys, long timestamp, CancellationToken cancellationToken);
31+
32+
/// <summary>
33+
/// Attempt to cache objects, after loading them from the database.
34+
/// </summary>
35+
/// <param name="keys">The keys (id) of the objects to put in the Cache.</param>
36+
/// <param name="values">The objects to put in the cache.</param>
37+
/// <param name="timestamp">A timestamp prior to the transaction start time.</param>
38+
/// <param name="versions">The version numbers of the objects we are putting.</param>
39+
/// <param name="versionComparers">The comparers to be used to compare version numbers</param>
40+
/// <param name="minimalPuts">Indicates that the cache should avoid a put if the item is already cached.</param>
41+
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
42+
/// <returns><see langword="true" /> if the objects were successfully cached.</returns>
43+
/// <exception cref="CacheException"></exception>
44+
Task<bool[]> PutManyAsync(CacheKey[] keys, object[] values, long timestamp, object[] versions, IComparer[] versionComparers,
45+
bool[] minimalPuts, CancellationToken cancellationToken);
46+
}
47+
}

src/NHibernate/Async/Cache/IBatchableReadCache.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ public partial interface IBatchableReadCache
2424
/// <param name="keys">The keys to be retrieved from the cache.</param>
2525
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
2626
/// <returns></returns>
27-
Task<object[]> GetMultipleAsync(object[] keys, CancellationToken cancellationToken);
27+
Task<object[]> GetManyAsync(object[] keys, CancellationToken cancellationToken);
2828
}
2929
}

src/NHibernate/Async/Cache/IBatchableWriteCache.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@ public partial interface IBatchableReadWriteCache : IBatchableReadCache
2424
/// <param name="keys">The keys to cache.</param>
2525
/// <param name="values">The objects to cache.</param>
2626
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
27-
Task PutMultipleAsync(object[] keys, object[] values, CancellationToken cancellationToken);
27+
Task PutManyAsync(object[] keys, object[] values, CancellationToken cancellationToken);
2828

2929
/// <summary>
3030
/// Lock the objects from being changed by another thread.
3131
/// </summary>
3232
/// <param name="keys">The keys to lock.</param>
3333
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
34-
Task LockMultipleAsync(object[] keys, CancellationToken cancellationToken);
34+
Task LockManyAsync(object[] keys, CancellationToken cancellationToken);
3535

3636
/// <summary>
3737
/// Unlock the objects that were previously locked.
3838
/// </summary>
3939
/// <param name="keys">The keys to unlock.</param>
4040
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
41-
Task UnlockMultipleAsync(object[] keys, CancellationToken cancellationToken);
41+
Task UnlockManyAsync(object[] keys, CancellationToken cancellationToken);
4242
}
4343
}

src/NHibernate/Async/Cache/ICacheConcurrencyStrategy.cs

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -130,31 +130,21 @@ internal static partial class CacheConcurrencyStrategyExtensions
130130
/// </summary>
131131
/// <param name="cache">The cache concurrency strategy.</param>
132132
/// <param name="keys">The keys (id) of the objects to get out of the Cache.</param>
133-
/// <param name="txTimestamp">A timestamp prior to the transaction start time</param>
133+
/// <param name="timestamp">A timestamp prior to the transaction start time</param>
134134
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
135135
/// <returns>An array of cached objects or <see langword="null" /></returns>
136136
/// <exception cref="CacheException"></exception>
137-
//6.0 TODO: Merge into ICacheConcurrencyStrategy.
138-
public static async Task<object[]> GetMultipleAsync(this ICacheConcurrencyStrategy cache, CacheKey[] keys, long txTimestamp, CancellationToken cancellationToken)
137+
public static Task<object[]> GetManyAsync(this ICacheConcurrencyStrategy cache, CacheKey[] keys, long timestamp, CancellationToken cancellationToken)
139138
{
140-
cancellationToken.ThrowIfCancellationRequested();
141-
switch (cache)
139+
if (!(cache is IBatchableCacheConcurrencyStrategy batchableCache))
142140
{
143-
case ReadOnlyCache readOnly:
144-
return await (readOnly.GetMultipleAsync(keys, txTimestamp, cancellationToken)).ConfigureAwait(false);
145-
case ReadWriteCache readWrite:
146-
return await (readWrite.GetMultipleAsync(keys, txTimestamp, cancellationToken)).ConfigureAwait(false);
147-
case NonstrictReadWriteCache nonstrictReadWrite:
148-
return await (nonstrictReadWrite.GetMultipleAsync(keys, txTimestamp, cancellationToken)).ConfigureAwait(false);
141+
throw new InvalidOperationException($"Cache concurrency strategy {cache.GetType()} does not support batching");
149142
}
150-
151-
// Fallback to Get
152-
var objects = new object[keys.Length];
153-
for (var i = 0; i < keys.Length; i++)
143+
if (cancellationToken.IsCancellationRequested)
154144
{
155-
objects[i] = await (cache.GetAsync(keys[i], txTimestamp, cancellationToken)).ConfigureAwait(false);
145+
return Task.FromCanceled<object[]>(cancellationToken);
156146
}
157-
return objects;
147+
return batchableCache.GetManyAsync(keys, timestamp, cancellationToken);
158148
}
159149

160150
/// <summary>
@@ -170,28 +160,18 @@ public static async Task<object[]> GetMultipleAsync(this ICacheConcurrencyStrate
170160
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
171161
/// <returns><see langword="true" /> if the objects were successfully cached.</returns>
172162
/// <exception cref="CacheException"></exception>
173-
//6.0 TODO: Merge into ICacheConcurrencyStrategy.
174-
public static async Task<bool[]> PutMultipleAsync(this ICacheConcurrencyStrategy cache, CacheKey[] keys, object[] values, long timestamp,
163+
public static Task<bool[]> PutManyAsync(this ICacheConcurrencyStrategy cache, CacheKey[] keys, object[] values, long timestamp,
175164
object[] versions, IComparer[] versionComparers, bool[] minimalPuts, CancellationToken cancellationToken)
176165
{
177-
cancellationToken.ThrowIfCancellationRequested();
178-
switch (cache)
166+
if (!(cache is IBatchableCacheConcurrencyStrategy batchableCache))
179167
{
180-
case ReadOnlyCache readOnly:
181-
return await (readOnly.PutMultipleAsync(keys, values, timestamp, versions, versionComparers, minimalPuts, cancellationToken)).ConfigureAwait(false);
182-
case ReadWriteCache readWrite:
183-
return await (readWrite.PutMultipleAsync(keys, values, timestamp, versions, versionComparers, minimalPuts, cancellationToken)).ConfigureAwait(false);
184-
case NonstrictReadWriteCache nonstrictReadWrite:
185-
return await (nonstrictReadWrite.PutMultipleAsync(keys, values, timestamp, versions, versionComparers, minimalPuts, cancellationToken)).ConfigureAwait(false);
168+
throw new InvalidOperationException($"Cache concurrency strategy {cache.GetType()} does not support batching");
186169
}
187-
188-
// Fallback to Put
189-
var result = new bool[keys.Length];
190-
for (var i = 0; i < keys.Length; i++)
170+
if (cancellationToken.IsCancellationRequested)
191171
{
192-
result[i] = await (cache.PutAsync(keys[i], values[i], timestamp, versions[i], versionComparers[i], minimalPuts[i], cancellationToken)).ConfigureAwait(false);
172+
return Task.FromCanceled<bool[]>(cancellationToken);
193173
}
194-
return result;
174+
return batchableCache.PutManyAsync(keys, values, timestamp, versions, versionComparers, minimalPuts, cancellationToken);
195175
}
196176
}
197177
}

src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace NHibernate.Cache
1818
{
1919
using System.Threading.Tasks;
2020
using System.Threading;
21-
public partial class NonstrictReadWriteCache : ICacheConcurrencyStrategy
21+
public partial class NonstrictReadWriteCache : IBatchableCacheConcurrencyStrategy
2222
{
2323

2424
/// <summary>
@@ -44,7 +44,7 @@ public async Task<object> GetAsync(CacheKey key, long txTimestamp, CancellationT
4444
return result;
4545
}
4646

47-
public Task<object[]> GetMultipleAsync(CacheKey[] keys, long txTimestamp, CancellationToken cancellationToken)
47+
public Task<object[]> GetManyAsync(CacheKey[] keys, long timestamp, CancellationToken cancellationToken)
4848
{
4949
if (_batchableReadCache == null)
5050
{
@@ -54,14 +54,14 @@ public Task<object[]> GetMultipleAsync(CacheKey[] keys, long txTimestamp, Cancel
5454
{
5555
return Task.FromCanceled<object[]>(cancellationToken);
5656
}
57-
return InternalGetMultipleAsync();
58-
async Task<object[]> InternalGetMultipleAsync()
57+
return InternalGetManyAsync();
58+
async Task<object[]> InternalGetManyAsync()
5959
{
6060
if (log.IsDebugEnabled())
6161
{
6262
log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable()));
6363
}
64-
var results = await (_batchableReadCache.GetMultipleAsync(keys.Select(o => (object) o).ToArray(), cancellationToken)).ConfigureAwait(false);
64+
var results = await (_batchableReadCache.GetManyAsync(keys.Select(o => (object) o).ToArray(), cancellationToken)).ConfigureAwait(false);
6565
if (!log.IsDebugEnabled())
6666
{
6767
return results;
@@ -77,7 +77,7 @@ async Task<object[]> InternalGetMultipleAsync()
7777
/// <summary>
7878
/// Add multiple items to the cache
7979
/// </summary>
80-
public Task<bool[]> PutMultipleAsync(CacheKey[] keys, object[] values, long timestamp, object[] versions, IComparer[] versionComparers,
80+
public Task<bool[]> PutManyAsync(CacheKey[] keys, object[] values, long timestamp, object[] versions, IComparer[] versionComparers,
8181
bool[] minimalPuts, CancellationToken cancellationToken)
8282
{
8383
if (_batchableReadWriteCache == null)
@@ -88,8 +88,8 @@ public Task<bool[]> PutMultipleAsync(CacheKey[] keys, object[] values, long time
8888
{
8989
return Task.FromCanceled<bool[]>(cancellationToken);
9090
}
91-
return InternalPutMultipleAsync();
92-
async Task<bool[]> InternalPutMultipleAsync()
91+
return InternalPutManyAsync();
92+
async Task<bool[]> InternalPutManyAsync()
9393
{
9494
var result = new bool[keys.Length];
9595
if (timestamp == long.MinValue)
@@ -111,7 +111,7 @@ async Task<bool[]> InternalPutMultipleAsync()
111111
var skipKeyIndexes = new HashSet<int>();
112112
if (checkKeys.Any())
113113
{
114-
var objects = await (_batchableReadWriteCache.GetMultipleAsync(checkKeys.ToArray(), cancellationToken)).ConfigureAwait(false);
114+
var objects = await (_batchableReadWriteCache.GetManyAsync(checkKeys.ToArray(), cancellationToken)).ConfigureAwait(false);
115115
for (var i = 0; i < objects.Length; i++)
116116
{
117117
if (objects[i] != null)
@@ -143,7 +143,7 @@ async Task<bool[]> InternalPutMultipleAsync()
143143
putValues[j++] = values[i];
144144
result[i] = true;
145145
}
146-
await (_batchableReadWriteCache.PutMultipleAsync(putKeys, putValues, cancellationToken)).ConfigureAwait(false);
146+
await (_batchableReadWriteCache.PutManyAsync(putKeys, putValues, cancellationToken)).ConfigureAwait(false);
147147
return result;
148148
}
149149
}

0 commit comments

Comments
 (0)