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