You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@lucenenet.apache.org by "Jon Davis (JIRA)" <ji...@apache.org> on 2007/10/16 20:30:50 UTC

[jira] Created: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Need to implement ICloneable on RAMDirectory
--------------------------------------------

                 Key: LUCENENET-103
                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
             Project: Lucene.Net
          Issue Type: Improvement
         Environment: C# 2.0
            Reporter: Jon Davis
            Priority: Minor


IClonable needs to be added to Lucene.net's RAMDirectory.

See Lucene (Java) item resolution at: 
http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html



-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 3:32 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                object[] arr = new object[buffers.Count];
                buffers.CopyTo(arr);
                clone.buffers.AddRange(arr);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 4:04 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 47.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a semi-shallow clone of this RAMDirectory, with 
        /// instanced RAMFiles that have shared dependency upon 
        /// the binary data.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 47.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a semi-shallow clone of this RAMDirectory, with 
        /// instanced RAMFiles that have dependent binary data.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Digy (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535663 ] 

Digy commented on LUCENENET-103:
--------------------------------

Hi Jon,

I tested the code you sent with some "additions and deletions into the original index and checking the clones"  and it seems OK.
(Note: copying "sizeInBytes" field to clone is also needed).
(I prepared a patch for this but I am not sure  about sending this code, because I don't know if this action results in a Copyright violation or  not.)


My Test results are:
using orgDir.Clone(false)  -> 3t
using orgDir.Clone(true)   -> 7t
using new RAMDirectory(orgDir) -> 9.5t 
with ~150,000 docs containing ~1,200,000 terms (t:100ms).

But I have some hesitations on applying the patch to Lucene.Net

First, although I couldn't generate an error in "Clone(false)" case, I think it can be dangerous since it does not clone the byte array, instead just put the address into the buffer(and this is the reason of speed-up).

Second, the original java-code from Nick Smith(Adding clone method to RAMDirectory+RAMFile) is not included in the current release of the Java Lucene. Adding this functionality to Lucene.Net means divergence from the Java code.


So I leave that hot potato for George Aroush(the only commiter of this project).


DIGY




> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535351 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:32 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone. We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job.

      was (Author: stimpy77):
    Erm, error, in RAMFile.Clone(deep) should be if (!deep) not if (deep).

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone. We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job.
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 3:17 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                object[] arr = new object[buffers.Count];
                buffers.CopyTo(arr);
                clone.buffers.AddRange(arr);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    clone.buffers.Add(buffers[i]);
                }
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 3:05 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    clone.buffers.Add(buffers[i]);
                }
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone(); // not helpful because ArrayList created synchronized
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    clone.buffers.Add(buffers[i]);
                }
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Digy (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535326 ] 

Digy commented on LUCENENET-103:
--------------------------------

Hi Jon,

To create an  <B>independent </B> copy from the source,  both Lucene and Lucene.Net use
"Lucene.Net.Store.Directory.Copy" static-method.  

Java(from SVN):
public RAMDirectory(Directory dir) throws IOException {
    this(dir, false);
  }
  
  private RAMDirectory(Directory dir, boolean closeDir) throws IOException {
    this();
    Directory.copy(dir, this, closeDir);
  }

.NET(from SVN):
public RAMDirectory(Directory dir):this(dir, false)
{
}
		
private RAMDirectory(Directory dir, bool closeDir):this()
{
	Directory.Copy(dir, this, closeDir);
}


No Diff between Java and .NET code. (I haven't also found a "clone" method in java version too)


DIGY


> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535351 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:33 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone. We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job.
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:44 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

{{
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
}}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:46 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 3:06 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    clone.buffers.Add(buffers[i]);
                }
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    clone.buffers.Add(buffers[i]);
                }
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:34 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}

      was (Author: stimpy77):
    In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:44 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}


      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

{{
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
}}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:40 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(true);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(true);
        }

        #endregion
    }
}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

Jon Davis commented on LUCENENET-103:
-------------------------------------

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}

> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 4:05 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 47.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a semi-shallow clone of this RAMDirectory, with 
        /// instanced RAMFiles that have shared dependency upon 
        /// the binary data.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

 ...

    class RAMFile : ICloneable
    {

 ...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 47.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a semi-shallow clone of this RAMDirectory, with 
        /// instanced RAMFiles that have shared dependency upon 
        /// the binary data.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:29 PM:
---------------------------------------------------------------

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}

      was (Author: stimpy77):
    In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:45 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

{{namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}}}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}

  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 3:09 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    clone.buffers.Add(buffers[i]);
                }
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    clone.buffers.Add(buffers[i]);
                }
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:45 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

{{namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}}}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 3:59 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 47.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:51 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on the previous RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on the previous RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jon Davis updated LUCENENET-103:
--------------------------------

    Comment: was deleted

> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535419 ] 

Jon Davis commented on LUCENENET-103:
-------------------------------------

Yeesh. If you guys are getting the same e-mails as I'm getting just for comment edits, I do apologize.

> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535351 ] 

Jon Davis commented on LUCENENET-103:
-------------------------------------

Erm, error, in RAMFile.Clone(deep) should be if (!deep) not if (deep).

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone. We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job.

> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:50 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on the previous RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on the previous RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Closed: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Digy (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Digy closed LUCENENET-103.
--------------------------

    Resolution: Won't Fix

Hi Jon,
After 2 years and many improvements in Lucene[.Net], if you think that this issue is still valid, feel free to reopen it.

DIGY

> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 2:36 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(true);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(true);
        }

        #endregion
    }
}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.

namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Performs a shallow copy of the object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 4:02 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 47.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a semi-shallow clone of this RAMDirectory, with 
        /// instanced RAMFiles that have dependent binary data.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was thirty seconds for a manual RAMDirectory duplication using IndexWriter.AddIndexes(), 1299ms for Directory.Copy, versus 669ms for a deep clone, and 47.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                // ArrayList.Clone not helpful because original ArrayList created synchronized
                // ..  does clone from synchronized retain original sync context ties?
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone();

                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                    clone.buffers.Add(buffers[i]);
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(buffers.Count));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535347 ] 

stimpy77 edited comment on LUCENENET-103 at 10/16/07 3:03 PM:
---------------------------------------------------------------

I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                //clone.buffers = (System.Collections.ArrayList) buffers.Clone(); // not helpful because ArrayList created synchronized
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    clone.buffers.Add(buffers[i]);
                }
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}

      was (Author: stimpy77):
    I should add, the objective for cloning was to make it more performant. The Directory copy approach was slower. For our purposes, the difference was 1299ms for Directory.Copy, versus 669ms for a deep clone, and 9.66ms for a shallow clone (and a LOT less RAM usage). We are going with a shallow clone because this is a multi-threaded server and there are thread locks all over the Lucene objects, but we don't modify a RAMDirectory once it is loaded. Rather, we rebuild the RAMDirectory in the equivalent of a cron job, then clone it across multiple threads.

In my environment I implemented ICloneable already, using the referenced hyperlink.
{code}
namespace Lucene.Net.Store
{
 ...	
	public sealed class RAMDirectory : Directory, ICloneable
	{
...

        #region ICloneable Members
        /// <summary>
        /// Creates a clone of the RAMDirectory.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMDirectory object.</returns>
        public object Clone(bool deep)
        {
            RAMDirectory clone = new RAMDirectory();
            System.Collections.IDictionaryEnumerator enmr = files.GetEnumerator();
            while (enmr.MoveNext())
            {
                string name = (string)enmr.Key;
                RAMFile rf = (RAMFile)enmr.Value;
                clone.files.Add(name, rf.Clone(deep));
            }
            return clone;
        }

        /// <summary>
        /// Creates a shallow clone of this RAMDirectory.
        /// </summary>
        /// <returns>A new RAMDirectory with dependency on this RAMDirectory's RAMFile binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }

	class RAMFile : ICloneable
	{

...

        #region ICloneable Members

        /// <summary>
        /// Creates a clone of the RAMFile.
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </summary>
        /// <param name="deep">
        /// If <paramref name="deep"/> is true, the clone is made 
        /// at the byte level. 
        /// If <paramref name="deep"/> is false, the clone is made
        /// at the buffers' references level.
        /// </param>
        /// <returns>A RAMFile object.</returns>
        public object Clone(bool deep)
        {
            RAMFile clone = new RAMFile();
            if (!deep)
            {
                clone.buffers = (System.Collections.ArrayList) buffers.Clone();
            }
            else
            {
                clone.buffers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
                for (int i = 0; i < buffers.Count; i++)
                {
                    byte[] buf = (byte[])buffers[i];
                    byte[] cloneBuf = (byte[])buf.Clone();
                    clone.buffers.Add(cloneBuf);
                }
            }
            clone.length = length;
            clone.lastModified = lastModified;
            return clone;
        }
        /// <summary>
        /// Creates a shallow clone of the RAMFile.
        /// </summary>
        /// <returns>A new RAMFile with dependency on this RAMFile's binary data.</returns>
        public object Clone()
        {
            return Clone(false);
        }

        #endregion
    }
}
{code}
  
> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (LUCENENET-103) Need to implement ICloneable on RAMDirectory

Posted by "Jon Davis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/LUCENENET-103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535675 ] 

Jon Davis commented on LUCENENET-103:
-------------------------------------

> First, although I couldn't generate an error in "Clone(false)" case, I think it can be dangerous since it does not clone the byte array, instead just put the address into the buffer(and this is the reason of speed-up).

Unsafe, not dangerous. It's the same principle as using unsafe pointers in C#. But yes, that is the nature of any shallow clone, and that's why I implemented a deep clone as well. People shouldn't use shallow clones unless they know what they are doing. That said, does Lucene's analyzers perform any writes/modifications to a Directory when the "user" is only reading a Directory?

The version I'm using (released build v2 from April, not from CVS) doesn't have sizeInBytes, it has length. I only considered Directory.Copy after you suggested getting it from CVS. For that matter, my test results differ from yours, and so perhaps some of this issue is moot as I should have checked to see what's in CVS before posting.

> Need to implement ICloneable on RAMDirectory
> --------------------------------------------
>
>                 Key: LUCENENET-103
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-103
>             Project: Lucene.Net
>          Issue Type: Improvement
>         Environment: C# 2.0
>            Reporter: Jon Davis
>            Priority: Minor
>
> IClonable needs to be added to Lucene.net's RAMDirectory.
> See Lucene (Java) item resolution at: 
> http://www.mail-archive.com/lucene-dev@jakarta.apache.org/msg03725.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.