[ 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.
|