1- using System . Diagnostics ;
1+ using System . Collections . Generic ;
2+ using System . Diagnostics ;
3+ using System . Linq ;
24using NHibernate . Engine ;
35using NHibernate . Persister . Collection ;
46using NHibernate . Persister . Entity ;
57
68namespace NHibernate . Cache
79{
810 /// <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"/>.
1212 /// </summary>
1313 public sealed partial class CacheBatcher
1414 {
15- private CachePutBatch _putBatch ;
15+ private readonly Dictionary < ICacheConcurrencyStrategy , CachePutBatch > _putBatches =
16+ new Dictionary < ICacheConcurrencyStrategy , CachePutBatch > ( ) ;
1617 private readonly ISessionImplementor _session ;
17- private AbstractCacheBatch _currentBatch ;
18- private object _currentPersister ;
1918
2019 private static readonly INHibernateLogger Log = NHibernateLogger . For ( typeof ( CacheBatcher ) ) ;
2120
@@ -25,53 +24,50 @@ internal CacheBatcher(ISessionImplementor session)
2524 }
2625
2726 /// <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.
3028 /// </summary>
3129 /// <param name="persister">The entity persister.</param>
3230 /// <param name="data">The data to put in the cache.</param>
3331 internal void AddToBatch ( IEntityPersister persister , CachePutData data )
3432 {
35- if ( ShouldExecuteBatch ( persister , _putBatch ) )
36- {
37- ExecuteBatch ( ) ;
38- _currentPersister = persister ;
39- _currentBatch = _putBatch = new CachePutBatch ( _session , persister . Cache ) ;
40- }
4133 if ( Log . IsDebugEnabled ( ) )
4234 {
4335 Log . Debug ( "Adding a put operation to batch for entity {0} and key {1}" , persister . EntityName , data . Key ) ;
4436 }
45- _putBatch . Add ( data ) ;
37+ AddToBatch ( persister . Cache , data ) ;
4638 }
4739
4840 /// <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.
5142 /// </summary>
5243 /// <param name="persister">The collection persister.</param>
5344 /// <param name="data">The data to put in the cache.</param>
5445 internal void AddToBatch ( ICollectionPersister persister , CachePutData data )
5546 {
56- if ( ShouldExecuteBatch ( persister , _putBatch ) )
57- {
58- ExecuteBatch ( ) ;
59- _currentPersister = persister ;
60- _currentBatch = _putBatch = new CachePutBatch ( _session , persister . Cache ) ;
61- }
6247 if ( Log . IsDebugEnabled ( ) )
6348 {
6449 Log . Debug ( "Adding a put operation to batch for collection role {0} and key {1}" , persister . Role , data . Key ) ;
6550 }
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 ) ;
6763 }
6864
6965 /// <summary>
70- /// Executes the current batch .
66+ /// Executes the pending batches .
7167 /// </summary>
7268 internal void ExecuteBatch ( )
7369 {
74- if ( _currentBatch == null || _currentBatch . BatchSize == 0 )
70+ if ( _putBatches . Count == 0 )
7571 {
7672 return ;
7773 }
@@ -83,10 +79,18 @@ internal void ExecuteBatch()
8379 {
8480 duration = Stopwatch . StartNew ( ) ;
8581 }
86- _currentBatch . Execute ( ) ;
82+
83+ foreach ( var batch in _putBatches . Values )
84+ {
85+ batch . Execute ( ) ;
86+ }
87+
8788 if ( Log . IsDebugEnabled ( ) && duration != null )
8889 {
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 ) ;
9094 }
9195 }
9296 finally
@@ -100,22 +104,7 @@ internal void ExecuteBatch()
100104 /// </summary>
101105 internal void Cleanup ( )
102106 {
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 ( ) ;
119108 }
120109 }
121110}
0 commit comments