[
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/[EMAIL PROTECTED]/msg03725.html
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.