Skip to content

Commit 09ea1b3

Browse files
committed
HHH-8945 introduced "hibernate.session.initial_capacity" to reduce
StatefulPersistenceContext's Map#resize calls Conflicts: hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java
1 parent 8ec3c4a commit 09ea1b3

File tree

2 files changed

+42
-24
lines changed

2 files changed

+42
-24
lines changed

hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,5 +709,15 @@ public interface AvailableSettings {
709709
String LOG_SESSION_METRICS = "hibernate.session.events.log";
710710

711711
String AUTO_SESSION_EVENTS_LISTENER = "hibernate.session.events.auto";
712+
713+
/**
714+
* A {@link org.hibernate.engine.internal.StatefulPersistenceContext} maintains multiple Maps for a Session. For
715+
* performance reasons, it can be desirable to initialize the Maps with a non-default capacity, minimizing the
716+
* occurrences of #resize calls. The capacity generally correlates with the quantity of entities expected to be
717+
* managed by an average Session.
718+
*
719+
* Default: 8
720+
*/
721+
String SESSION_INITIAL_CAPACITY = "hibernate.session.initial_capacity";
712722

713723
}

hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@
3838
import java.util.Map;
3939
import java.util.Map.Entry;
4040

41-
import org.jboss.logging.Logger;
42-
4341
import org.hibernate.AssertionFailure;
4442
import org.hibernate.Hibernate;
4543
import org.hibernate.HibernateException;
@@ -52,6 +50,7 @@
5250
import org.hibernate.cache.spi.NaturalIdCacheKey;
5351
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
5452
import org.hibernate.cache.spi.access.SoftLock;
53+
import org.hibernate.cfg.AvailableSettings;
5554
import org.hibernate.collection.spi.PersistentCollection;
5655
import org.hibernate.engine.loading.internal.LoadContexts;
5756
import org.hibernate.engine.spi.AssociationKey;
@@ -76,8 +75,10 @@
7675
import org.hibernate.pretty.MessageHelper;
7776
import org.hibernate.proxy.HibernateProxy;
7877
import org.hibernate.proxy.LazyInitializer;
78+
import org.hibernate.service.config.spi.ConfigurationService;
7979
import org.hibernate.tuple.ElementWrapper;
8080
import org.hibernate.type.CollectionType;
81+
import org.jboss.logging.Logger;
8182

8283
/**
8384
* A <strong>stateful</strong> implementation of the {@link PersistenceContext} contract meaning that we maintain this
@@ -93,11 +94,12 @@ public class StatefulPersistenceContext implements PersistenceContext {
9394

9495
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, StatefulPersistenceContext.class.getName() );
9596

96-
private static final boolean tracing = LOG.isTraceEnabled();
97+
private static final boolean tracing = LOG.isTraceEnabled();
9798

9899
public static final Object NO_ROW = new MarkerObject( "NO_ROW" );
99100

100-
public static final int INIT_COLL_SIZE = 8;
101+
private static final int DEFAULT_INITIAL_CAPACITY = 8;
102+
private final int initialCapacity;
101103

102104
private SessionImplementor session;
103105

@@ -162,29 +164,32 @@ public class StatefulPersistenceContext implements PersistenceContext {
162164
*/
163165
public StatefulPersistenceContext(SessionImplementor session) {
164166
this.session = session;
167+
168+
initialCapacity = session.getFactory().getServiceRegistry().getService( ConfigurationService.class )
169+
.getSetting( AvailableSettings.SESSION_INITIAL_CAPACITY, Integer.class, DEFAULT_INITIAL_CAPACITY );
165170

166-
entitiesByKey = new HashMap<EntityKey, Object>( INIT_COLL_SIZE );
167-
entitiesByUniqueKey = new HashMap<EntityUniqueKey, Object>( INIT_COLL_SIZE );
171+
entitiesByKey = new HashMap<EntityKey, Object>( initialCapacity );
172+
entitiesByUniqueKey = new HashMap<EntityUniqueKey, Object>( initialCapacity );
168173
//noinspection unchecked
169-
proxiesByKey = new ConcurrentReferenceHashMap<EntityKey, Object>( INIT_COLL_SIZE, .75f, 1, ConcurrentReferenceHashMap.ReferenceType.STRONG, ConcurrentReferenceHashMap.ReferenceType.WEAK, null );
170-
entitySnapshotsByKey = new HashMap<EntityKey, Object>( INIT_COLL_SIZE );
174+
proxiesByKey = new ConcurrentReferenceHashMap<EntityKey, Object>( initialCapacity, .75f, 1, ConcurrentReferenceHashMap.ReferenceType.STRONG, ConcurrentReferenceHashMap.ReferenceType.WEAK, null );
175+
entitySnapshotsByKey = new HashMap<EntityKey, Object>( initialCapacity );
171176

172177
entityEntryContext = new EntityEntryContext();
173-
// entityEntries = IdentityMap.instantiateSequenced( INIT_COLL_SIZE );
174-
collectionEntries = IdentityMap.instantiateSequenced( INIT_COLL_SIZE );
175-
parentsByChild = new IdentityHashMap<Object,Object>( INIT_COLL_SIZE );
178+
// entityEntries = IdentityMap.instantiateSequenced( initialCapacity );
179+
collectionEntries = IdentityMap.instantiateSequenced( initialCapacity );
180+
parentsByChild = new IdentityHashMap<Object,Object>( initialCapacity );
176181

177-
collectionsByKey = new HashMap<CollectionKey, PersistentCollection>( INIT_COLL_SIZE );
178-
arrayHolders = new IdentityHashMap<Object, PersistentCollection>( INIT_COLL_SIZE );
182+
collectionsByKey = new HashMap<CollectionKey, PersistentCollection>( initialCapacity );
183+
arrayHolders = new IdentityHashMap<Object, PersistentCollection>( initialCapacity );
179184

180185
nullifiableEntityKeys = new HashSet<EntityKey>();
181186

182187
initTransientState();
183188
}
184189

185190
private void initTransientState() {
186-
nullAssociations = new HashSet<AssociationKey>( INIT_COLL_SIZE );
187-
nonlazyCollections = new ArrayList<PersistentCollection>( INIT_COLL_SIZE );
191+
nullAssociations = new HashSet<AssociationKey>( initialCapacity );
192+
nonlazyCollections = new ArrayList<PersistentCollection>( initialCapacity );
188193
}
189194

190195
@Override
@@ -208,7 +213,7 @@ public LoadContexts getLoadContexts() {
208213
@Override
209214
public void addUnownedCollection(CollectionKey key, PersistentCollection collection) {
210215
if (unownedCollections==null) {
211-
unownedCollections = new HashMap<CollectionKey,PersistentCollection>(INIT_COLL_SIZE);
216+
unownedCollections = new HashMap<CollectionKey,PersistentCollection>(initialCapacity);
212217
}
213218
unownedCollections.put( key, collection );
214219
}
@@ -1659,6 +1664,9 @@ public static StatefulPersistenceContext deserialize(
16591664
}
16601665
final StatefulPersistenceContext rtn = new StatefulPersistenceContext( session );
16611666
SessionFactoryImplementor sfi = session.getFactory();
1667+
1668+
int initialCapacity = sfi.getServiceRegistry().getService( ConfigurationService.class )
1669+
.getSetting( AvailableSettings.SESSION_INITIAL_CAPACITY, Integer.class, DEFAULT_INITIAL_CAPACITY );
16621670

16631671
// during deserialization, we need to reconnect all proxies and
16641672
// collections to this session, as well as the EntityEntry and
@@ -1672,14 +1680,14 @@ public static StatefulPersistenceContext deserialize(
16721680

16731681
int count = ois.readInt();
16741682
if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] entitiesByKey entries");
1675-
rtn.entitiesByKey = new HashMap<EntityKey,Object>( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
1683+
rtn.entitiesByKey = new HashMap<EntityKey,Object>( count < initialCapacity ? initialCapacity : count );
16761684
for ( int i = 0; i < count; i++ ) {
16771685
rtn.entitiesByKey.put( EntityKey.deserialize( ois, sfi ), ois.readObject() );
16781686
}
16791687

16801688
count = ois.readInt();
16811689
if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] entitiesByUniqueKey entries");
1682-
rtn.entitiesByUniqueKey = new HashMap<EntityUniqueKey,Object>( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
1690+
rtn.entitiesByUniqueKey = new HashMap<EntityUniqueKey,Object>( count < initialCapacity ? initialCapacity : count );
16831691
for ( int i = 0; i < count; i++ ) {
16841692
rtn.entitiesByUniqueKey.put( EntityUniqueKey.deserialize( ois, session ), ois.readObject() );
16851693
}
@@ -1688,7 +1696,7 @@ public static StatefulPersistenceContext deserialize(
16881696
if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] proxiesByKey entries");
16891697
//noinspection unchecked
16901698
rtn.proxiesByKey = new ConcurrentReferenceHashMap<EntityKey, Object>(
1691-
count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count,
1699+
count < initialCapacity ? initialCapacity : count,
16921700
.75f,
16931701
1,
16941702
ConcurrentReferenceHashMap.ReferenceType.STRONG,
@@ -1709,15 +1717,15 @@ public static StatefulPersistenceContext deserialize(
17091717

17101718
count = ois.readInt();
17111719
if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] entitySnapshotsByKey entries");
1712-
rtn.entitySnapshotsByKey = new HashMap<EntityKey,Object>( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
1720+
rtn.entitySnapshotsByKey = new HashMap<EntityKey,Object>( count < initialCapacity ? initialCapacity : count );
17131721
for ( int i = 0; i < count; i++ ) {
17141722
rtn.entitySnapshotsByKey.put( EntityKey.deserialize( ois, sfi ), ois.readObject() );
17151723
}
17161724

17171725
rtn.entityEntryContext = EntityEntryContext.deserialize( ois, rtn );
17181726
// count = ois.readInt();
17191727
// if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] entityEntries entries");
1720-
// rtn.entityEntries = IdentityMap.instantiateSequenced( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
1728+
// rtn.entityEntries = IdentityMap.instantiateSequenced( count < initialCapacity ? initialCapacity : count );
17211729
// for ( int i = 0; i < count; i++ ) {
17221730
// Object entity = ois.readObject();
17231731
// EntityEntry entry = EntityEntry.deserialize( ois, rtn );
@@ -1726,14 +1734,14 @@ public static StatefulPersistenceContext deserialize(
17261734

17271735
count = ois.readInt();
17281736
if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] collectionsByKey entries");
1729-
rtn.collectionsByKey = new HashMap<CollectionKey,PersistentCollection>( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
1737+
rtn.collectionsByKey = new HashMap<CollectionKey,PersistentCollection>( count < initialCapacity ? initialCapacity : count );
17301738
for ( int i = 0; i < count; i++ ) {
17311739
rtn.collectionsByKey.put( CollectionKey.deserialize( ois, session ), (PersistentCollection) ois.readObject() );
17321740
}
17331741

17341742
count = ois.readInt();
17351743
if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] collectionEntries entries");
1736-
rtn.collectionEntries = IdentityMap.instantiateSequenced( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
1744+
rtn.collectionEntries = IdentityMap.instantiateSequenced( count < initialCapacity ? initialCapacity : count );
17371745
for ( int i = 0; i < count; i++ ) {
17381746
final PersistentCollection pc = ( PersistentCollection ) ois.readObject();
17391747
final CollectionEntry ce = CollectionEntry.deserialize( ois, session );
@@ -1743,7 +1751,7 @@ public static StatefulPersistenceContext deserialize(
17431751

17441752
count = ois.readInt();
17451753
if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] arrayHolders entries");
1746-
rtn.arrayHolders = new IdentityHashMap<Object, PersistentCollection>( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
1754+
rtn.arrayHolders = new IdentityHashMap<Object, PersistentCollection>( count < initialCapacity ? initialCapacity : count );
17471755
for ( int i = 0; i < count; i++ ) {
17481756
rtn.arrayHolders.put( ois.readObject(), (PersistentCollection) ois.readObject() );
17491757
}

0 commit comments

Comments
 (0)