forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCacheBatcher.cs
121 lines (110 loc) · 3.48 KB
/
CacheBatcher.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System.Diagnostics;
using NHibernate.Engine;
using NHibernate.Persister.Collection;
using NHibernate.Persister.Entity;
namespace NHibernate.Cache
{
/// <summary>
/// A batcher for batching operations of <see cref="ICacheConcurrencyStrategy"/>, where the batch size is retrieved
/// from an <see cref="IEntityPersister"/> or <see cref="ICollectionPersister"/>.
/// When a different persister or a different operation is added to the batch, the current batch will be executed.
/// </summary>
public sealed partial class CacheBatcher
{
private CachePutBatch _putBatch;
private readonly ISessionImplementor _session;
private AbstractCacheBatch _currentBatch;
private object _currentPersister;
private static readonly INHibernateLogger Log = NHibernateLogger.For(typeof(CacheBatcher));
internal CacheBatcher(ISessionImplementor session)
{
_session = session;
}
/// <summary>
/// Adds a put operation to the batch. If the batch size reached the persister batch
/// size, the batch will be executed.
/// </summary>
/// <param name="persister">The entity persister.</param>
/// <param name="data">The data to put in the cache.</param>
internal void AddToBatch(IEntityPersister persister, CachePutData data)
{
if (ShouldExecuteBatch(persister, _putBatch))
{
ExecuteBatch();
_currentPersister = persister;
_currentBatch = _putBatch = new CachePutBatch(_session, persister.Cache);
}
if (Log.IsDebugEnabled())
{
Log.Debug("Adding a put operation to batch for entity {0} and key {1}", persister.EntityName, data.Key);
}
_putBatch.Add(data);
}
/// <summary>
/// Adds a put operation to the batch. If the batch size reached the persister batch
/// size, the batch will be executed.
/// </summary>
/// <param name="persister">The collection persister.</param>
/// <param name="data">The data to put in the cache.</param>
internal void AddToBatch(ICollectionPersister persister, CachePutData data)
{
if (ShouldExecuteBatch(persister, _putBatch))
{
ExecuteBatch();
_currentPersister = persister;
_currentBatch = _putBatch = new CachePutBatch(_session, persister.Cache);
}
if (Log.IsDebugEnabled())
{
Log.Debug("Adding a put operation to batch for collection role {0} and key {1}", persister.Role, data.Key);
}
_putBatch.Add(data);
}
/// <summary>
/// Executes the current batch.
/// </summary>
internal void ExecuteBatch()
{
if (_currentBatch == null || _currentBatch.BatchSize == 0)
{
return;
}
try
{
Stopwatch duration = null;
if (Log.IsDebugEnabled())
{
duration = Stopwatch.StartNew();
}
_currentBatch.Execute();
if (Log.IsDebugEnabled() && duration != null)
{
Log.Debug("ExecuteBatch for {0} keys took {1} ms", _currentBatch.BatchSize, duration.ElapsedMilliseconds);
}
}
finally
{
Cleanup();
}
}
/// <summary>
/// Cleans up the current batch.
/// </summary>
internal void Cleanup()
{
_putBatch = null;
_currentBatch = null;
_currentPersister = null;
}
private bool ShouldExecuteBatch(IEntityPersister persister, AbstractCacheBatch batch)
{
return batch != _currentBatch || _currentPersister != persister ||
_currentBatch.BatchSize >= persister.GetBatchSize();
}
private bool ShouldExecuteBatch(ICollectionPersister persister, AbstractCacheBatch batch)
{
return batch != _currentBatch || _currentPersister != persister ||
_currentBatch.BatchSize >= persister.GetBatchSize();
}
}
}