Author: ste...@jb...
Date: 2006-07-05 14:17:27 -0400 (Wed, 05 Jul 2006)
New Revision: 10086
Modified:
trunk/Hibernate3/src/org/hibernate/collection/PersistentArrayHolder.java
trunk/Hibernate3/src/org/hibernate/collection/PersistentBag.java
trunk/Hibernate3/src/org/hibernate/collection/PersistentCollection.java
trunk/Hibernate3/src/org/hibernate/collection/PersistentElementHolder.java
trunk/Hibernate3/src/org/hibernate/collection/PersistentIdentifierBag.java
trunk/Hibernate3/src/org/hibernate/collection/PersistentIndexedElementHolder.java
trunk/Hibernate3/src/org/hibernate/collection/PersistentList.java
trunk/Hibernate3/src/org/hibernate/collection/PersistentMap.java
trunk/Hibernate3/src/org/hibernate/collection/PersistentSet.java
trunk/Hibernate3/src/org/hibernate/engine/CollectionLoadContext.java
trunk/Hibernate3/src/org/hibernate/type/ArrayType.java
trunk/Hibernate3/src/org/hibernate/type/BagType.java
trunk/Hibernate3/src/org/hibernate/type/CollectionType.java
trunk/Hibernate3/src/org/hibernate/type/CustomCollectionType.java
trunk/Hibernate3/src/org/hibernate/type/IdentifierBagType.java
trunk/Hibernate3/src/org/hibernate/type/ListType.java
trunk/Hibernate3/src/org/hibernate/type/MapType.java
trunk/Hibernate3/src/org/hibernate/type/SetType.java
trunk/Hibernate3/src/org/hibernate/usertype/UserCollectionType.java
trunk/Hibernate3/test/org/hibernate/test/usercollection/MyListType.java
trunk/Hibernate3/test/org/hibernate/test/usercollection/UserCollectionTypeTest.java
Log:
HHH-1789 : proper collection sizing for improved performance
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentArrayHolder.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentArrayHolder.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentArrayHolder.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -137,7 +137,7 @@
return true;
}
- public void beforeInitialize(CollectionPersister persister) {
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
//if (tempList==null) throw new UnsupportedOperationException("Can't lazily initialize arrays");
}
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentBag.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentBag.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentBag.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -71,8 +71,8 @@
return element;
}
- public void beforeInitialize(CollectionPersister persister) {
- this.bag = (List) persister.getCollectionType().instantiate();
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+ this.bag = ( List ) persister.getCollectionType().instantiate( anticipatedSize );
}
public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
@@ -134,11 +134,14 @@
public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
throws HibernateException {
- beforeInitialize(persister);
Serializable[] array = (Serializable[]) disassembled;
- for ( int i=0; i<array.length; i++ ) {
+ int size = array.length;
+ beforeInitialize( persister, size );
+ for ( int i = 0; i < size; i++ ) {
Object element = persister.getElementType().assemble( array[i], getSession(), owner );
- if ( element!=null ) bag.add( element );
+ if ( element!=null ) {
+ bag.add( element );
+ }
}
}
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentCollection.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentCollection.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentCollection.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -151,8 +151,11 @@
/**
* Called before any elements are read into the collection,
* allowing appropriate initializations to occur.
+ *
+ * @param persister The underlying collection persister.
+ * @param anticipatedSize The anticipated size of the collection after initilization is complete.
*/
- public void beforeInitialize(CollectionPersister persister);
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize);
/**
* Does the current state exactly match the snapshot?
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentElementHolder.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentElementHolder.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentElementHolder.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -120,7 +120,7 @@
return result.iterator();
}
- public void beforeInitialize(CollectionPersister persister) {}
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {}
public boolean isDirectlyAccessible() {
return true;
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentIdentifierBag.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentIdentifierBag.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentIdentifierBag.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -61,9 +61,10 @@
public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
throws HibernateException {
- beforeInitialize(persister);
Serializable[] array = (Serializable[]) disassembled;
- for ( int i=0; i<array.length; i+=2 ) {
+ int size = array.length;
+ beforeInitialize( persister, size );
+ for ( int i = 0; i < size; i+=2 ) {
identifiers.put(
new Integer(i/2),
persister.getIdentifierType().assemble( array[i], getSession(), owner )
@@ -159,14 +160,13 @@
return values.toArray(a);
}
- public void beforeInitialize(CollectionPersister persister) {
- identifiers = new HashMap();
- values = new ArrayList();
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+ identifiers = anticipatedSize <= 0 ? new HashMap() : new HashMap( anticipatedSize + 1 + (int)( anticipatedSize * .75f ), .75f );
+ values = anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize );
}
public Serializable disassemble(CollectionPersister persister)
- throws HibernateException {
-
+ throws HibernateException {
Serializable[] result = new Serializable[ values.size() * 2 ];
int i=0;
for (int j=0; j< values.size(); j++) {
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentIndexedElementHolder.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentIndexedElementHolder.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentIndexedElementHolder.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -161,7 +161,7 @@
return result.iterator();
}
- public void beforeInitialize(CollectionPersister persister) {}
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {}
public boolean isDirectlyAccessible() {
return true;
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentList.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentList.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentList.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -74,8 +74,8 @@
setDirectlyAccessible(true);
}
- public void beforeInitialize(CollectionPersister persister) {
- this.list = (List) persister.getCollectionType().instantiate();
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+ this.list = ( List ) persister.getCollectionType().instantiate( anticipatedSize );
}
public boolean isWrapper(Object collection) {
@@ -372,9 +372,10 @@
public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
throws HibernateException {
- beforeInitialize(persister);
- Serializable[] array = (Serializable[]) disassembled;
- for ( int i=0; i<array.length; i++ ) {
+ Serializable[] array = ( Serializable[] ) disassembled;
+ int size = array.length;
+ beforeInitialize( persister, size );
+ for ( int i = 0; i < size; i++ ) {
list.add( persister.getElementType().assemble( array[i], getSession(), owner ) );
}
}
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentMap.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentMap.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentMap.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -31,10 +31,8 @@
protected Map map;
- public Serializable getSnapshot(CollectionPersister persister)
- throws HibernateException {
+ public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
EntityMode entityMode = getSession().getEntityMode();
-
HashMap clonedMap = new HashMap( map.size() );
Iterator iter = map.entrySet().iterator();
while ( iter.hasNext() ) {
@@ -77,8 +75,8 @@
public PersistentMap() {} //needed for SOAP libraries, etc
- public void beforeInitialize(CollectionPersister persister) {
- this.map = (Map) persister.getCollectionType().instantiate();
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+ this.map = ( Map ) persister.getCollectionType().instantiate( anticipatedSize );
}
public PersistentMap(SessionImplementor session, Map map) {
@@ -317,9 +315,10 @@
public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
throws HibernateException {
- beforeInitialize(persister);
- Serializable[] array = (Serializable[]) disassembled;
- for (int i=0; i<array.length; i+=2 ) {
+ Serializable[] array = ( Serializable[] ) disassembled;
+ int size = array.length;
+ beforeInitialize( persister, size );
+ for ( int i = 0; i < size; i+=2 ) {
map.put(
persister.getIndexType().assemble( array[i], getSession(), owner ),
persister.getElementType().assemble( array[i+1], getSession(), owner )
Modified: trunk/Hibernate3/src/org/hibernate/collection/PersistentSet.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/collection/PersistentSet.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/collection/PersistentSet.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -78,8 +78,8 @@
public PersistentSet() {} //needed for SOAP libraries, etc
- public void beforeInitialize(CollectionPersister persister) {
- this.set = (Set) persister.getCollectionType().instantiate();
+ public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+ this.set = ( Set ) persister.getCollectionType().instantiate( anticipatedSize );
}
public PersistentSet(SessionImplementor session, java.util.Set set) {
@@ -95,11 +95,14 @@
public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
throws HibernateException {
- beforeInitialize(persister);
- Serializable[] array = (Serializable[]) disassembled;
- for (int i=0; i<array.length; i++ ) {
+ Serializable[] array = ( Serializable[] ) disassembled;
+ int size = array.length;
+ beforeInitialize( persister, size );
+ for (int i = 0; i < size; i++ ) {
Object element = persister.getElementType().assemble( array[i], getSession(), owner );
- if (element!=null) set.add(element);
+ if ( element != null ) {
+ set.add( element );
+ }
}
}
Modified: trunk/Hibernate3/src/org/hibernate/engine/CollectionLoadContext.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/engine/CollectionLoadContext.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/engine/CollectionLoadContext.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -102,7 +102,7 @@
.instantiate( context.getSession(), persister, key );
}
}
- collection.beforeInitialize(persister);
+ collection.beforeInitialize( persister, -1 );
collection.beginRead();
addLoadingCollectionEntry(ckey, collection, persister, resultSetId);
return collection;
Modified: trunk/Hibernate3/src/org/hibernate/type/ArrayType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/ArrayType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/type/ArrayType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -96,7 +96,7 @@
}
- public Object instantiate() {
+ public Object instantiate(int anticipatedSize) {
throw new UnsupportedOperationException();
}
Modified: trunk/Hibernate3/src/org/hibernate/type/BagType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/BagType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/type/BagType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -43,9 +43,8 @@
}
}
- public Object instantiate() {
- //TODO: does not work for EntityMode.DOM4J yet
- return new ArrayList();
+ public Object instantiate(int anticipatedSize) {
+ return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
}
}
Modified: trunk/Hibernate3/src/org/hibernate/type/CollectionType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/CollectionType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/type/CollectionType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -418,15 +418,29 @@
return result;
}
-
- public Object instantiateResult(Object original) {
- return instantiate();
+
+ /**
+ * Instantiate a new "underlying" collection exhibiting the same capacity
+ * charactersitcs and the passed "original".
+ *
+ * @param original The original collection.
+ * @return The newly instantiated collection.
+ */
+ protected Object instantiateResult(Object original) {
+ // by default just use an unanticipated capacity since we don't
+ // know how to extract the capacity to use from original here...
+ return instantiate( -1 );
}
/**
- * Instantiate an empty instance of the "underlying" collection (not a wrapper)
+ * Instantiate an empty instance of the "underlying" collection (not a wrapper),
+ * but with the given anticipated size (i.e. accounting for initial capacity
+ * and perhaps load factor).
+ *
+ * @param anticipatedSize The anticipated size of the instaniated collection
+ * after we are done populating it.
*/
- public abstract Object instantiate();
+ public abstract Object instantiate(int anticipatedSize);
public Object replace(
final Object original,
@@ -436,12 +450,17 @@
final Map copyCache)
throws HibernateException {
- if ( original == null ) return null;
- if ( !Hibernate.isInitialized( original ) ) return target;
+ if ( original == null ) {
+ return null;
+ }
+ if ( !Hibernate.isInitialized( original ) ) {
+ return target;
+ }
//if ( original == target ) return target; // can't do this, since need to merge element references
- Object result = target==null || target==original ? //instead, put the merged elements in a new collection
- instantiateResult( original ) : target;
+ // for a null target, or a target which is the same as the original, we
+ // need to put the merged elements in a new collection
+ Object result = target == null || target == original ? instantiateResult( original ) : target;
//for arrays, replaceElements() may return a different reference, since
//the array length might not match
Modified: trunk/Hibernate3/src/org/hibernate/type/CustomCollectionType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/CustomCollectionType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/type/CustomCollectionType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -7,7 +7,6 @@
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
-import org.hibernate.Hibernate;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.SessionFactoryImplementor;
@@ -57,11 +56,11 @@
}
public Class getReturnedClass() {
- return userType.instantiate().getClass();
+ return userType.instantiate( -1 ).getClass();
}
- public Object instantiate() {
- return userType.instantiate();
+ public Object instantiate(int anticipatedType) {
+ return userType.instantiate( anticipatedType );
}
public Iterator getElementsIterator(Object collection) {
Modified: trunk/Hibernate3/src/org/hibernate/type/IdentifierBagType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/IdentifierBagType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/type/IdentifierBagType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -24,8 +24,8 @@
return new PersistentIdentifierBag(session);
}
- public Object instantiate() {
- return new ArrayList();
+ public Object instantiate(int anticipatedSize) {
+ return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
}
public Class getReturnedClass() {
Modified: trunk/Hibernate3/src/org/hibernate/type/ListType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/ListType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/type/ListType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -41,8 +41,8 @@
}
}
- public Object instantiate() {
- return new ArrayList();
+ public Object instantiate(int anticipatedSize) {
+ return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
}
public Object indexOf(Object collection, Object element) {
Modified: trunk/Hibernate3/src/org/hibernate/type/MapType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/MapType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/type/MapType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -48,8 +48,10 @@
}
}
- public Object instantiate() {
- return new HashMap();
+ public Object instantiate(int anticipatedSize) {
+ return anticipatedSize <= 0
+ ? new HashMap()
+ : new HashMap( anticipatedSize + (int)( anticipatedSize * .75f ), .75f );
}
public Object replaceElements(
Modified: trunk/Hibernate3/src/org/hibernate/type/SetType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/SetType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/type/SetType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -40,9 +40,10 @@
}
}
- public Object instantiate() {
- //TODO: Might need to be a LinkedHashSet!!!!!!
- return new HashSet();
+ public Object instantiate(int anticipatedSize) {
+ return anticipatedSize <= 0
+ ? new HashSet()
+ : new HashSet( anticipatedSize + (int)( anticipatedSize * .75f ), .75f );
}
}
Modified: trunk/Hibernate3/src/org/hibernate/usertype/UserCollectionType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/usertype/UserCollectionType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/src/org/hibernate/usertype/UserCollectionType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -54,10 +54,17 @@
Map copyCache,
SessionImplementor session)
throws HibernateException;
-
+
/**
- * Instantiate an empty instance of the "underlying" collection (not a wrapper)
+ * Instantiate an empty instance of the "underlying" collection (not a wrapper),
+ * but with the given anticipated size (i.e. accounting for initial size
+ * and perhaps load factor).
+ *
+ * @param anticipatedSize The anticipated size of the instaniated collection
+ * after we are done populating it. Note, may be negative to indicate that
+ * we not yet know anything about the anticipated size (i.e., when initializing
+ * from a result set row by row).
*/
- public Object instantiate();
+ public Object instantiate(int anticipatedSize);
}
Modified: trunk/Hibernate3/test/org/hibernate/test/usercollection/MyListType.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/usercollection/MyListType.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/test/org/hibernate/test/usercollection/MyListType.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -12,6 +12,8 @@
public class MyListType implements UserCollectionType {
+ static int lastInstantiationRequest = -2;
+
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister) throws HibernateException {
return new PersistentMyList(session);
}
@@ -43,18 +45,14 @@
}
public Object replaceElements(Object original, Object target, CollectionPersister persister, Object owner, Map copyCache, SessionImplementor session) throws HibernateException {
-
IMyList result = (IMyList) target;
-
result.clear();
-
result.addAll((MyList)original);
-
return result;
-
}
- public Object instantiate() {
+ public Object instantiate(int anticipatedSize) {
+ lastInstantiationRequest = anticipatedSize;
return new MyList();
}
Modified: trunk/Hibernate3/test/org/hibernate/test/usercollection/UserCollectionTypeTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/usercollection/UserCollectionTypeTest.java 2006-07-05 16:35:26 UTC (rev 10085)
+++ trunk/Hibernate3/test/org/hibernate/test/usercollection/UserCollectionTypeTest.java 2006-07-05 18:17:27 UTC (rev 10086)
@@ -33,9 +33,22 @@
User u2 = (User) s.createCriteria(User.class).uniqueResult();
assertTrue( Hibernate.isInitialized( u2.getEmailAddresses() ) );
assertEquals( u2.getEmailAddresses().size(), 2 );
- s.delete(u2);
t.commit();
s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ u2 = ( User ) s.get( User.class, u.getUserName() );
+ u2.getEmailAddresses().size();
+ assertEquals( 2, MyListType.lastInstantiationRequest );
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.delete( u );
+ t.commit();
+ s.close();
}
|