From: Michael D. <mik...@us...> - 2005-02-07 01:34:50
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10106/Collection Modified Files: ArrayHolder.cs Bag.cs CollectionPersister.cs IdentifierBag.cs List.cs Map.cs PersistentCollection.cs Set.cs SortedMap.cs SortedSet.cs Log Message: modifications to Collections and their Types for caching related code. Formatting of the Visitor classes and added in two missing Visitors. Index: Bag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Bag.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Bag.cs 6 Feb 2005 01:58:56 -0000 1.12 --- Bag.cs 7 Feb 2005 01:34:40 -0000 1.13 *************** *** 41,45 **** } ! initialized = true; directlyAccessible = true; } --- 41,45 ---- } ! SetInitialized(); directlyAccessible = true; } *************** *** 48,69 **** /// /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - public Bag( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) : base( session ) - { - BeforeInitialize( persister ); - object[ ] array = ( object[ ] ) disassembled; - for( int i = 0; i < array.Length; i++ ) - { - bag.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); - } - initialized = true; - } - - /// <summary> - /// - /// </summary> /// <returns></returns> public override ICollection Elements() --- 48,51 ---- *************** *** 218,221 **** --- 200,221 ---- /// <summary> + /// Initializes this Bag from the cached values. + /// </summary> + /// <param name="persister">The CollectionPersister to use to reassemble the Bag.</param> + /// <param name="disassembled">The disassembled Bag.</param> + /// <param name="owner">The owner object.</param> + public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) + { + BeforeInitialize( persister ); + object[] array = ( object[] ) disassembled; + for( int i = 0; i < array.Length; i++ ) + { + bag.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); + } + SetInitialized(); + } + + + /// <summary> /// Gets a <see cref="Boolean"/> indicating if this Bag needs to be recreated /// in the database. Index: Map.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Map.cs,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Map.cs 6 Feb 2005 01:58:56 -0000 1.18 --- Map.cs 7 Feb 2005 01:34:40 -0000 1.19 *************** *** 78,100 **** /// <summary> - /// Construct an initialized Map from its disassembled state. - /// </summary> - /// <param name="session">The ISession the Map should be a part of.</param> - /// <param name="persister">The CollectionPersister to use to reassemble the Map.</param> - /// <param name="disassembled">The disassembled Map.</param> - /// <param name="owner">The owner object.</param> - public Map( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) : base( session ) - { - BeforeInitialize( persister ); - object[ ] array = ( object[ ] ) disassembled; - for( int i = 0; i < array.Length; i += 2 ) - { - map[ persister.IndexType.Assemble( array[ i ], session, owner ) ] = - persister.ElementType.Assemble( array[ i + 1 ], session, owner ); - } - initialized = true; - } - - /// <summary> /// Construct an initialized Map based off the values from the existing IDictionary. /// </summary> --- 78,81 ---- *************** *** 104,108 **** { this.map = map; ! initialized = true; directlyAccessible = true; } --- 85,89 ---- { this.map = map; ! SetInitialized(); directlyAccessible = true; } *************** *** 332,335 **** --- 313,334 ---- /// <summary> + /// Initializes this Map from the cached values. + /// </summary> + /// <param name="persister">The CollectionPersister to use to reassemble the Map.</param> + /// <param name="disassembled">The disassembled Map.</param> + /// <param name="owner">The owner object.</param> + public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) + { + BeforeInitialize( persister ); + object[ ] array = ( object[ ] ) disassembled; + for( int i = 0; i < array.Length; i += 2 ) + { + map[ persister.IndexType.Assemble( array[ i ], session, owner ) ] = + persister.ElementType.Assemble( array[ i + 1 ], session, owner ); + } + SetInitialized(); + } + + /// <summary> /// /// </summary> Index: PersistentCollection.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/PersistentCollection.cs,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** PersistentCollection.cs 6 Feb 2005 01:58:56 -0000 1.19 --- PersistentCollection.cs 7 Feb 2005 01:34:40 -0000 1.20 *************** *** 197,201 **** /// Return the user-visible collection (or array) instance /// </summary> ! /// <returns></returns> public virtual object GetValue() { --- 197,206 ---- /// Return the user-visible collection (or array) instance /// </summary> ! /// <returns> ! /// By default, the NHibernate wrapper is an acceptable collection for ! /// the end user code to work with because it is interface compatible. ! /// An NHibernate List is an IList, an NHibernate Map is an IDictionary ! /// and those are the types user code is expecting. ! /// </returns> public virtual object GetValue() { *************** *** 221,226 **** /// <summary> ! /// Override on some subclasses. /// </summary> public virtual void EndRead() { --- 226,243 ---- /// <summary> ! /// Called when the reading the Collection from the database is finished. /// </summary> + /// <remarks> + /// <p> + /// This should be overridden by sub collections that use temporary collections + /// to store values read from the db. + /// </p> + /// <p> + /// This is also responsible for determining if the collection is cacheable by + /// setting the property <see cref="IsCacheable"/>. When NH is synched with h2.1 + /// this method will be changed to return that bool instead of setting the property, + /// but this accomplishes the same thing until then. + /// </p> + /// </remarks> public virtual void EndRead() { *************** *** 232,243 **** --- 249,288 ---- DelayedAddAll(additions); additions=null; + // can't cache the collection because it contains additions that are + // not in the database - those additions can't be put in the cache + // because they might throw TransientObjectExceptions when attempting + // to get their database identifier. + IsCacheable = false; //return false; } else { + // nothing happened that would prevent this collection from being safe + // to cache. + IsCacheable = true; //return true; } } + private bool _isCacheable; + + /// <summary> + /// Gets or sets a boolean indicating if this collection can be put into the + /// cache. + /// </summary> + /// <remarks> + /// This is a method new to NHibernate and is in here until the Loader design + /// can get synched up with h2.1's loader design. In h2.1 the <c>EndRead()</c> + /// method returns a bool that is used by the ISession to determine wether or + /// not the Collection can go in cache. Right now, the only thing that can keep + /// a collection from being cached is if Delayed Adds are supported - ie, adding + /// items to the collection without fully initializing it. + /// </remarks> + internal bool IsCacheable + { + get { return _isCacheable; } + set { _isCacheable = value; } + } + /// <summary> /// *************** *** 352,355 **** --- 397,409 ---- /// <summary> + /// Read the state of the collection from a disassembled cached value. + /// </summary> + /// <param name="persister"></param> + /// <param name="disassembled"></param> + /// <param name="owner"></param> + public abstract void InitializeFromCache(CollectionPersister persister, object disassembled, object owner); + + + /// <summary> /// Reads the elements Identifier from the reader. /// </summary> *************** *** 573,576 **** --- 627,633 ---- } + /// <summary> + /// Mark the collection as initialized. + /// </summary> protected void SetInitialized() { Index: List.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/List.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** List.cs 6 Feb 2005 01:58:56 -0000 1.17 --- List.cs 7 Feb 2005 01:34:40 -0000 1.18 *************** *** 82,86 **** { this.list = list; ! initialized = true; directlyAccessible = true; } --- 82,86 ---- { this.list = list; ! SetInitialized(); directlyAccessible = true; } *************** *** 323,333 **** /// <summary> ! /// /// </summary> ! /// <param name="session"></param> ! /// <param name="persister"></param> ! /// <param name="disassembled"></param> ! /// <param name="owner"></param> ! public List( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) : base( session ) { BeforeInitialize( persister ); --- 323,332 ---- /// <summary> ! /// Initializes this List from the cached values. /// </summary> ! /// <param name="persister">The CollectionPersister to use to reassemble the List.</param> ! /// <param name="disassembled">The disassembled List.</param> ! /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { BeforeInitialize( persister ); *************** *** 337,341 **** list.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } ! initialized = true; } --- 336,340 ---- list.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } ! SetInitialized(); } Index: CollectionPersister.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/CollectionPersister.cs,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** CollectionPersister.cs 31 Dec 2004 16:36:46 -0000 1.31 --- CollectionPersister.cs 7 Feb 2005 01:34:40 -0000 1.32 *************** *** 282,304 **** /// /// </summary> ! /// <param name="id"></param> ! /// <param name="coll"></param> ! /// <param name="s"></param> ! public void Cache( object id, PersistentCollection coll, ISessionImplementor s ) ! { ! if( cache != null ) ! { ! if( log.IsDebugEnabled ) ! { ! log.Debug( "Caching collection: " + role + "#" + id ); ! } ! cache.Put( id, coll.Disassemble( this ), s.Timestamp ); ! } ! } ! ! /// <summary> ! /// ! /// </summary> ! public ICacheConcurrencyStrategy CacheConcurrencyStrategy { get { return cache; } --- 282,286 ---- /// /// </summary> ! public ICacheConcurrencyStrategy Cache { get { return cache; } *************** *** 317,351 **** /// </summary> /// <param name="id"></param> - /// <param name="owner"></param> - /// <param name="s"></param> - /// <returns></returns> - public PersistentCollection GetCachedCollection( object id, object owner, ISessionImplementor s ) - { - if( cache == null ) - { - return null; - } - else - { - if( log.IsDebugEnabled ) - { - log.Debug( "Searching for collection in cache: " + role + "#" + id ); - } - object cached = cache.Get( id, s.Timestamp ); - if( cached == null ) - { - return null; - } - else - { - return collectionType.AssembleCachedCollection( s, this, cached, owner ); - } - } - } - - /// <summary> - /// - /// </summary> - /// <param name="id"></param> public void Softlock( object id ) { --- 299,302 ---- Index: ArrayHolder.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/ArrayHolder.cs,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** ArrayHolder.cs 6 Feb 2005 01:58:56 -0000 1.15 --- ArrayHolder.cs 7 Feb 2005 01:34:40 -0000 1.16 *************** *** 16,19 **** --- 16,22 ---- private static readonly ILog log = LogManager.GetLogger( typeof( PersistentCollection ) ); + /// <summary> + /// The <see cref="Array"/> that NHibernate is wrapping. + /// </summary> private Array array; *************** *** 21,24 **** --- 24,31 ---- private System.Type elementClass; + /// <summary> + /// A temporary list that holds the objects while the ArrayHolder is being + /// populated from the database. + /// </summary> [NonSerialized] private ArrayList tempList; *************** *** 33,37 **** { this.array = (Array) array; ! initialized = true; } --- 40,44 ---- { this.array = (Array) array; ! SetInitialized(); } *************** *** 192,196 **** /// <summary> ! /// /// </summary> public override void BeginRead() --- 199,204 ---- /// <summary> ! /// Before the <c>ReadFrom()</c> is called the ArrayHolder needs to setup ! /// a temporary list to hold the objects. /// </summary> public override void BeginRead() *************** *** 200,203 **** --- 208,216 ---- } + /// <summary> + /// Takes the contents stored in the temporary list created during <c>BeginRead()</c> + /// that was populated during <c>ReadFrom()</c> and write it to the underlying + /// array. + /// </summary> public override void EndRead() { *************** *** 211,214 **** --- 224,230 ---- } tempList = null; + + // TODO: h2.1 synch to return bool instead of IsCacheable (NH specific code) + IsCacheable = true; //return true; } *************** *** 239,252 **** /// <summary> ! /// /// </summary> ! /// <param name="session"></param> ! /// <param name="persister"></param> ! /// <param name="disassembled"></param> ! /// <param name="owner"></param> ! public ArrayHolder( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) ! : base( session ) { ! object[ ] cached = ( object[ ] ) disassembled; array = System.Array.CreateInstance( persister.ElementClass, cached.Length ); --- 255,266 ---- /// <summary> ! /// Initializes this array holder from the cached values. /// </summary> ! /// <param name="persister">The CollectionPersister to use to reassemble the Array.</param> ! /// <param name="disassembled">The disassembled Array.</param> ! /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { ! object[] cached = ( object[] ) disassembled; array = System.Array.CreateInstance( persister.ElementClass, cached.Length ); *************** *** 254,260 **** for( int i = 0; i < cached.Length; i++ ) { ! ( ( Array ) array ).SetValue( persister.ElementType.Assemble( cached[ i ], session, owner ), i ); } ! initialized = true; } --- 268,274 ---- for( int i = 0; i < cached.Length; i++ ) { ! array.SetValue( persister.ElementType.Assemble( cached[ i ], session, owner ), i ); } ! SetInitialized(); } *************** *** 275,278 **** --- 289,298 ---- } + /// <summary> + /// Returns the user-visible portion of the NHibernate ArrayHolder. + /// </summary> + /// <returns> + /// The array that contains the data, not the NHibernate wrapper. + /// </returns> public override object GetValue() { Index: SortedSet.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/SortedSet.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** SortedSet.cs 6 Feb 2005 01:58:56 -0000 1.12 --- SortedSet.cs 7 Feb 2005 01:34:40 -0000 1.13 *************** *** 71,95 **** this.comparer = comparer; } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="comparer"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - public SortedSet( ISessionImplementor session, CollectionPersister persister, IComparer comparer, object disassembled, object owner ) : this( session, comparer ) - { - BeforeInitialize( persister ); - object[ ] array = ( object[ ] ) disassembled; - for( int i = 0; i < array.Length; i++ ) - { - object newObject = persister.ElementType.Assemble( array[ i ], session, owner ); - internalSet.Add( newObject ); - } - - initialized = true; - } } } \ No newline at end of file --- 71,74 ---- Index: SortedMap.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/SortedMap.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** SortedMap.cs 6 Feb 2005 01:58:56 -0000 1.7 --- SortedMap.cs 7 Feb 2005 01:34:40 -0000 1.8 *************** *** 54,84 **** /// <summary> - /// Create an Initialized SortedMap from its disassembled state. - /// </summary> - /// <param name="session">The ISession the Map should be a part of.</param> - /// <param name="persister">The CollectionPersister to use to reassemble the Map.</param> - /// <param name="comparer">The IComparer to perform the sorting.</param> - /// <param name="disassembled">The disassembled Map.</param> - /// <param name="owner">The owner object.</param> - public SortedMap( ISessionImplementor session, CollectionPersister persister, IComparer comparer, object disassembled, object owner ) - : base( session ) - { - this.comparer = comparer; - BeforeInitialize( persister ); - object[ ] array = ( object[ ] ) disassembled; - - for( int i = 0; i < array.Length; i += 2 ) - { - object key = persister.IndexType.Assemble( array[ i ], session, owner ); - object val = persister.ElementType.Assemble( array[ i + 1 ], session, owner ); - - map[ key ] = val; - } - - initialized = true; - - } - - /// <summary> /// Constuct an uninitialized SortedMap that uses an IComparer to perform the sorting. /// </summary> --- 54,57 ---- Index: Set.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Set.cs,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** Set.cs 6 Feb 2005 01:58:56 -0000 1.22 --- Set.cs 7 Feb 2005 01:34:40 -0000 1.23 *************** *** 20,27 **** public class Set : PersistentCollection, ISet { ! /// <summary></summary> protected ISet internalSet; ! /// <summary></summary> [NonSerialized] protected IList tempList; --- 20,37 ---- public class Set : PersistentCollection, ISet { ! /// <summary> ! /// The <see cref="ISet"/> that NHibernate is wrapping. ! /// </summary> protected ISet internalSet; ! /// <summary> ! /// A temporary list that holds the objects while the Set is being ! /// populated from the database. ! /// </summary> ! /// <remarks> ! /// This is necessary to ensure that the object being added to the Set doesn't ! /// have its' <c>GetHashCode()</c> and <c>Equals()</c> methods called during the load ! /// process. ! /// </remarks> [NonSerialized] protected IList tempList; *************** *** 103,119 **** { internalSet = collection; ! initialized = true; directlyAccessible = true; } /// <summary> ! /// /// </summary> ! /// <param name="session"></param> ! /// <param name="persister"></param> ! /// <param name="disassembled"></param> ! /// <param name="owner"></param> ! public Set( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) ! : base( session ) { BeforeInitialize( persister ); --- 113,127 ---- { internalSet = collection; ! SetInitialized(); directlyAccessible = true; } /// <summary> ! /// Initializes this Set from the cached values. /// </summary> ! /// <param name="persister">The CollectionPersister to use to reassemble the Set.</param> ! /// <param name="disassembled">The disassembled Set.</param> ! /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { BeforeInitialize( persister ); *************** *** 123,127 **** internalSet.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } ! initialized = true; } --- 131,135 ---- internalSet.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } ! SetInitialized(); } *************** *** 391,397 **** /// <summary> ! /// Set up the temporary Identifier List that will be used in the EndRead() ! /// to resolve the Identifier to an Entity. ! /// <see cref="PersistentCollection.BeginRead"/> /// </summary> public override void BeginRead() --- 399,404 ---- /// <summary> ! /// Set up the temporary List that will be used in the EndRead() ! /// to fully create the set. /// </summary> public override void BeginRead() *************** *** 400,403 **** --- 407,415 ---- } + /// <summary> + /// Takes the contents stored in the temporary list created during <c>BeginRead()</c> + /// that was populated during <c>ReadFrom()</c> and write it to the underlying + /// Set. + /// </summary> public override void EndRead() { *************** *** 405,408 **** --- 417,422 ---- tempList = null; SetInitialized(); + // TODO: h2.1 synch to return bool instead of IsCacheable (NH specific code) + IsCacheable = true; // return true; } Index: IdentifierBag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/IdentifierBag.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** IdentifierBag.cs 6 Feb 2005 01:58:56 -0000 1.7 --- IdentifierBag.cs 7 Feb 2005 01:34:40 -0000 1.8 *************** *** 28,32 **** private IList values; ! private IDictionary identifiers; //element -> id /// <summary> --- 28,33 ---- private IList values; ! // TODO: h2.1 changed this to index->id, haven't made that change in nh yet. ! private IDictionary identifiers; //element -> id /// <summary> *************** *** 58,62 **** } ! initialized = true; directlyAccessible = true; identifiers = new Hashtable(); --- 59,63 ---- } ! SetInitialized(); directlyAccessible = true; identifiers = new Hashtable(); *************** *** 64,75 **** /// <summary> ! /// /// </summary> ! /// <param name="session"></param> ! /// <param name="persister"></param> ! /// <param name="disassembled"></param> ! /// <param name="owner"></param> ! public IdentifierBag( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) : base( session ) { BeforeInitialize( persister ); object[ ] array = ( object[ ] ) disassembled; --- 65,76 ---- /// <summary> ! /// Initializes this Bag from the cached values. /// </summary> ! /// <param name="persister">The CollectionPersister to use to reassemble the IdentifierBag.</param> ! /// <param name="disassembled">The disassembled IdentifierBag.</param> ! /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { + BeforeInitialize( persister ); object[ ] array = ( object[ ] ) disassembled; *************** *** 82,88 **** } ! initialized = true; } #region IList Members --- 83,90 ---- } ! SetInitialized(); } + #region IList Members |