Lucene.Net.Core.Store (Types beginning with A-D): Updated documentation comments, fixed code formatting, and throw FileNotFoundException instead of Exception
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/7def889c Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/7def889c Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/7def889c Branch: refs/heads/api-work Commit: 7def889cb12eee96e19886a1acd70ab293120604 Parents: 548e768 Author: Shad Storhaug <[email protected]> Authored: Sun Mar 26 14:21:15 2017 +0700 Committer: Shad Storhaug <[email protected]> Committed: Sun Mar 26 15:22:24 2017 +0700 ---------------------------------------------------------------------- src/Lucene.Net.Core/Store/BaseDirectory.cs | 5 +- src/Lucene.Net.Core/Store/BufferedChecksum.cs | 12 +- .../Store/BufferedChecksumIndexInput.cs | 15 +- src/Lucene.Net.Core/Store/BufferedIndexInput.cs | 57 +++-- .../Store/BufferedIndexOutput.cs | 14 +- src/Lucene.Net.Core/Store/ByteArrayDataInput.cs | 40 +-- .../Store/ByteArrayDataOutput.cs | 1 + .../Store/ByteBufferIndexInput.cs | 53 ++-- src/Lucene.Net.Core/Store/CheckSumIndexInput.cs | 16 +- .../Store/CompoundFileDirectory.cs | 125 +++++----- src/Lucene.Net.Core/Store/CompoundFileWriter.cs | 39 ++- src/Lucene.Net.Core/Store/DataInput.cs | 136 +++++------ src/Lucene.Net.Core/Store/DataOutput.cs | 243 +++++++++---------- src/Lucene.Net.Core/Store/Directory.cs | 145 +++++------ src/Lucene.Net.Core/Store/IndexInput.cs | 2 +- src/Lucene.Net.Tests/Index/TestIndexInput.cs | 4 +- 16 files changed, 440 insertions(+), 467 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/BaseDirectory.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/BaseDirectory.cs b/src/Lucene.Net.Core/Store/BaseDirectory.cs index 2dd97f6..6c0592e 100644 --- a/src/Lucene.Net.Core/Store/BaseDirectory.cs +++ b/src/Lucene.Net.Core/Store/BaseDirectory.cs @@ -22,7 +22,8 @@ namespace Lucene.Net.Store */ /// <summary> - /// Base implementation for a concrete <seealso cref="Directory"/>. + /// Base implementation for a concrete <see cref="Directory"/>. + /// <para/> /// @lucene.experimental /// </summary> public abstract class BaseDirectory : Directory @@ -40,7 +41,7 @@ namespace Lucene.Net.Store /// <summary> /// Holds the LockFactory instance (implements locking for - /// this Directory instance). + /// this <see cref="Directory"/> instance). /// </summary> protected internal LockFactory m_lockFactory; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/BufferedChecksum.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/BufferedChecksum.cs b/src/Lucene.Net.Core/Store/BufferedChecksum.cs index 1232b32..6240ce4 100644 --- a/src/Lucene.Net.Core/Store/BufferedChecksum.cs +++ b/src/Lucene.Net.Core/Store/BufferedChecksum.cs @@ -1,5 +1,4 @@ using Lucene.Net.Support; -using System; namespace Lucene.Net.Store { @@ -21,7 +20,7 @@ namespace Lucene.Net.Store */ /// <summary> - /// Wraps another <seealso cref="Checksum"/> with an internal buffer + /// Wraps another <see cref="IChecksum"/> with an internal buffer /// to speed up checksum calculations. /// </summary> public class BufferedChecksum : IChecksum @@ -35,14 +34,14 @@ namespace Lucene.Net.Store public const int DEFAULT_BUFFERSIZE = 256; /// <summary> - /// Create a new BufferedChecksum with <seealso cref="#DEFAULT_BUFFERSIZE"/> </summary> + /// Create a new <see cref="BufferedChecksum"/> with <see cref="DEFAULT_BUFFERSIZE"/> </summary> public BufferedChecksum(IChecksum @in) : this(@in, DEFAULT_BUFFERSIZE) { } /// <summary> - /// Create a new BufferedChecksum with the specified bufferSize </summary> + /// Create a new <see cref="BufferedChecksum"/> with the specified <paramref name="bufferSize"/> </summary> public BufferedChecksum(IChecksum @in, int bufferSize) { this.@in = @in; @@ -58,6 +57,7 @@ namespace Lucene.Net.Store buffer[upto++] = (byte)b; } + // LUCENENET specific overload for updating a whole byte[] array public virtual void Update(byte[] b) { Update(b, 0, b.Length); @@ -81,7 +81,7 @@ namespace Lucene.Net.Store } } - public long Value + public virtual long Value { get { @@ -90,7 +90,7 @@ namespace Lucene.Net.Store } } - public void Reset() + public virtual void Reset() { upto = 0; @in.Reset(); http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/BufferedChecksumIndexInput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/BufferedChecksumIndexInput.cs b/src/Lucene.Net.Core/Store/BufferedChecksumIndexInput.cs index 22b90c1..0154a59 100644 --- a/src/Lucene.Net.Core/Store/BufferedChecksumIndexInput.cs +++ b/src/Lucene.Net.Core/Store/BufferedChecksumIndexInput.cs @@ -1,4 +1,5 @@ using Lucene.Net.Support; +using System; namespace Lucene.Net.Store { @@ -20,7 +21,7 @@ namespace Lucene.Net.Store */ /// <summary> - /// Simple implementation of <seealso cref="ChecksumIndexInput"/> that wraps + /// Simple implementation of <see cref="ChecksumIndexInput"/> that wraps /// another input and delegates calls. /// </summary> public class BufferedChecksumIndexInput : ChecksumIndexInput @@ -29,7 +30,7 @@ namespace Lucene.Net.Store internal readonly IChecksum digest; /// <summary> - /// Creates a new BufferedChecksumIndexInput </summary> + /// Creates a new <see cref="BufferedChecksumIndexInput"/> </summary> public BufferedChecksumIndexInput(IndexInput main) : base("BufferedChecksumIndexInput(" + main + ")") { @@ -50,14 +51,6 @@ namespace Lucene.Net.Store digest.Update(b, offset, len); } - /* - public override void ReadBytes(byte[] b, int offset, int len) - { - Main.ReadBytes(b, offset, len); - Digest.Update(b, offset, len); - } - */ - public override long Checksum { get @@ -83,7 +76,7 @@ namespace Lucene.Net.Store public override object Clone() { - throw new System.NotSupportedException(); + throw new NotSupportedException(); } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/BufferedIndexInput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/BufferedIndexInput.cs b/src/Lucene.Net.Core/Store/BufferedIndexInput.cs index fc72a7a..ee6e2ba 100644 --- a/src/Lucene.Net.Core/Store/BufferedIndexInput.cs +++ b/src/Lucene.Net.Core/Store/BufferedIndexInput.cs @@ -22,11 +22,11 @@ namespace Lucene.Net.Store */ /// <summary> - /// Base implementation class for buffered <seealso cref="IndexInput"/>. </summary> + /// Base implementation class for buffered <see cref="IndexInput"/>. </summary> public abstract class BufferedIndexInput : IndexInput { /// <summary> - /// Default buffer size set to {@value #BUFFER_SIZE}. </summary> + /// Default buffer size set to <see cref="BUFFER_SIZE"/>. </summary> public const int BUFFER_SIZE = 1024; // The normal read buffer size defaults to 1024, but @@ -36,13 +36,13 @@ namespace Lucene.Net.Store // BufferedIndexInputs created during merging. See // LUCENE-888 for details. /// <summary> - /// A buffer size for merges set to {@value #MERGE_BUFFER_SIZE}. + /// A buffer size for merges set to <see cref="MERGE_BUFFER_SIZE"/>. /// </summary> public const int MERGE_BUFFER_SIZE = 4096; private int bufferSize = BUFFER_SIZE; - protected internal byte[] m_buffer; + protected byte[] m_buffer; private long bufferStart = 0; // position in file of buffer private int bufferLength = 0; // end of valid bytes @@ -68,7 +68,7 @@ namespace Lucene.Net.Store } /// <summary> - /// Inits BufferedIndexInput with a specific bufferSize </summary> + /// Inits <see cref="BufferedIndexInput"/> with a specific <paramref name="bufferSize"/> </summary> public BufferedIndexInput(string resourceDesc, int bufferSize) : base(resourceDesc) { @@ -77,7 +77,7 @@ namespace Lucene.Net.Store } /// <summary> - /// Change the buffer size used by this IndexInput </summary> + /// Change the buffer size used by this <see cref="IndexInput"/> </summary> public void SetBufferSize(int newSize) { Debug.Assert(m_buffer == null || bufferSize == m_buffer.Length, "buffer=" + m_buffer + " bufferSize=" + bufferSize + " buffer.length=" + (m_buffer != null ? m_buffer.Length : 0)); @@ -132,7 +132,7 @@ namespace Lucene.Net.Store { if (bufferSize <= 0) { - throw new System.ArgumentException("bufferSize must be greater than 0 (got " + bufferSize + ")"); + throw new ArgumentException("bufferSize must be greater than 0 (got " + bufferSize + ")"); } } @@ -149,7 +149,7 @@ namespace Lucene.Net.Store // the buffer contains enough data to satisfy this request if (len > 0) // to allow b to be null if len is 0... { - System.Buffer.BlockCopy(m_buffer, bufferPosition, b, offset, len); + Buffer.BlockCopy(m_buffer, bufferPosition, b, offset, len); } bufferPosition += len; } @@ -158,7 +158,7 @@ namespace Lucene.Net.Store // the buffer does not have enough data. First serve all we've got. if (available > 0) { - System.Buffer.BlockCopy(m_buffer, bufferPosition, b, offset, available); + Buffer.BlockCopy(m_buffer, bufferPosition, b, offset, available); offset += available; len -= available; bufferPosition += available; @@ -173,12 +173,12 @@ namespace Lucene.Net.Store if (bufferLength < len) { // Throw an exception when refill() could not read len bytes: - System.Buffer.BlockCopy(m_buffer, 0, b, offset, bufferLength); + Buffer.BlockCopy(m_buffer, 0, b, offset, bufferLength); throw new EndOfStreamException("read past EOF: " + this); } else { - System.Buffer.BlockCopy(m_buffer, 0, b, offset, len); + Buffer.BlockCopy(m_buffer, 0, b, offset, len); bufferPosition = len; } } @@ -219,11 +219,15 @@ namespace Lucene.Net.Store } } + /// <summary> + /// NOTE: this was readInt() in Lucene + /// </summary> public override sealed int ReadInt32() { if (4 <= (bufferLength - bufferPosition)) { - return ((m_buffer[bufferPosition++] & 0xFF) << 24) | ((m_buffer[bufferPosition++] & 0xFF) << 16) | ((m_buffer[bufferPosition++] & 0xFF) << 8) | (m_buffer[bufferPosition++] & 0xFF); + return ((m_buffer[bufferPosition++] & 0xFF) << 24) | ((m_buffer[bufferPosition++] & 0xFF) << 16) + | ((m_buffer[bufferPosition++] & 0xFF) << 8) | (m_buffer[bufferPosition++] & 0xFF); } else { @@ -231,12 +235,17 @@ namespace Lucene.Net.Store } } + /// <summary> + /// NOTE: this was readLong() in Lucene + /// </summary> public override sealed long ReadInt64() { if (8 <= (bufferLength - bufferPosition)) { - int i1 = ((m_buffer[bufferPosition++] & 0xff) << 24) | ((m_buffer[bufferPosition++] & 0xff) << 16) | ((m_buffer[bufferPosition++] & 0xff) << 8) | (m_buffer[bufferPosition++] & 0xff); - int i2 = ((m_buffer[bufferPosition++] & 0xff) << 24) | ((m_buffer[bufferPosition++] & 0xff) << 16) | ((m_buffer[bufferPosition++] & 0xff) << 8) | (m_buffer[bufferPosition++] & 0xff); + int i1 = ((m_buffer[bufferPosition++] & 0xff) << 24) | ((m_buffer[bufferPosition++] & 0xff) << 16) + | ((m_buffer[bufferPosition++] & 0xff) << 8) | (m_buffer[bufferPosition++] & 0xff); + int i2 = ((m_buffer[bufferPosition++] & 0xff) << 24) | ((m_buffer[bufferPosition++] & 0xff) << 16) + | ((m_buffer[bufferPosition++] & 0xff) << 8) | (m_buffer[bufferPosition++] & 0xff); return (((long)i1) << 32) | (i2 & 0xFFFFFFFFL); } else @@ -245,6 +254,9 @@ namespace Lucene.Net.Store } } + /// <summary> + /// NOTE: this was readVInt() in Lucene + /// </summary> public override sealed int ReadVInt32() { if (5 <= (bufferLength - bufferPosition)) @@ -280,7 +292,7 @@ namespace Lucene.Net.Store { return i; } - throw new System.IO.IOException("Invalid vInt detected (too many bits)"); + throw new IOException("Invalid VInt32 detected (too many bits)"); } else { @@ -288,6 +300,9 @@ namespace Lucene.Net.Store } } + /// <summary> + /// NOTE: this was readVLong() in Lucene + /// </summary> public override sealed long ReadVInt64() { if (9 <= bufferLength - bufferPosition) @@ -346,7 +361,7 @@ namespace Lucene.Net.Store { return i; } - throw new System.IO.IOException("Invalid vLong detected (negative values disallowed)"); + throw new IOException("Invalid VInt64 detected (negative values disallowed)"); } else { @@ -409,8 +424,8 @@ namespace Lucene.Net.Store /// <summary> /// Expert: implements seek. Sets current position in this file, where the - /// next <seealso cref="#readInternal(byte[],int,int)"/> will occur. </summary> - /// <seealso cref= #readInternal(byte[],int,int) </seealso> + /// next <see cref="ReadInternal(byte[], int, int)"/> will occur. </summary> + /// <seealso cref="ReadInternal(byte[], int, int)"/> protected abstract void SeekInternal(long pos); public override object Clone() @@ -427,8 +442,8 @@ namespace Lucene.Net.Store /// <summary> /// Flushes the in-memory buffer to the given output, copying at most - /// <code>numBytes</code>. - /// <p> + /// <paramref name="numBytes"/>. + /// <para/> /// <b>NOTE:</b> this method does not refill the buffer, however it does /// advance the buffer position. /// </summary> @@ -449,7 +464,7 @@ namespace Lucene.Net.Store } /// <summary> - /// Returns default buffer sizes for the given <seealso cref="IOContext"/> + /// Returns default buffer sizes for the given <see cref="IOContext"/> /// </summary> public static int GetBufferSize(IOContext context) // LUCENENET NOTE: Renamed from BufferSize to prevent naming conflict { http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/BufferedIndexOutput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/BufferedIndexOutput.cs b/src/Lucene.Net.Core/Store/BufferedIndexOutput.cs index e2eb9a6..6ec731e 100644 --- a/src/Lucene.Net.Core/Store/BufferedIndexOutput.cs +++ b/src/Lucene.Net.Core/Store/BufferedIndexOutput.cs @@ -21,11 +21,11 @@ namespace Lucene.Net.Store */ /// <summary> - /// Base implementation class for buffered <seealso cref="IndexOutput"/>. </summary> + /// Base implementation class for buffered <see cref="IndexOutput"/>. </summary> public abstract class BufferedIndexOutput : IndexOutput { /// <summary> - /// The default buffer size in bytes ({@value #DEFAULT_BUFFER_SIZE}). </summary> + /// The default buffer size in bytes (<see cref="DEFAULT_BUFFER_SIZE"/>). </summary> public const int DEFAULT_BUFFER_SIZE = 16384; private readonly int bufferSize; @@ -35,8 +35,8 @@ namespace Lucene.Net.Store private readonly CRC32 crc = new CRC32(); /// <summary> - /// Creates a new <seealso cref="BufferedIndexOutput"/> with the default buffer size - /// ({@value #DEFAULT_BUFFER_SIZE} bytes see <seealso cref="#DEFAULT_BUFFER_SIZE"/>) + /// Creates a new <see cref="BufferedIndexOutput"/> with the default buffer size + /// (<see cref="DEFAULT_BUFFER_SIZE"/> bytes see <see cref="DEFAULT_BUFFER_SIZE"/>) /// </summary> public BufferedIndexOutput() : this(DEFAULT_BUFFER_SIZE) @@ -44,14 +44,14 @@ namespace Lucene.Net.Store } /// <summary> - /// Creates a new <seealso cref="BufferedIndexOutput"/> with the given buffer size. </summary> + /// Creates a new <see cref="BufferedIndexOutput"/> with the given buffer size. </summary> /// <param name="bufferSize"> the buffer size in bytes used to buffer writes internally. </param> - /// <exception cref="IllegalArgumentException"> if the given buffer size is less or equal to <tt>0</tt> </exception> + /// <exception cref="ArgumentException"> if the given buffer size is less or equal to <c>0</c> </exception> public BufferedIndexOutput(int bufferSize) { if (bufferSize <= 0) { - throw new System.ArgumentException("bufferSize must be greater than 0 (got " + bufferSize + ")"); + throw new ArgumentException("bufferSize must be greater than 0 (got " + bufferSize + ")"); } this.bufferSize = bufferSize; buffer = new byte[bufferSize]; http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/ByteArrayDataInput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/ByteArrayDataInput.cs b/src/Lucene.Net.Core/Store/ByteArrayDataInput.cs index f966460..74aecdf 100644 --- a/src/Lucene.Net.Core/Store/ByteArrayDataInput.cs +++ b/src/Lucene.Net.Core/Store/ByteArrayDataInput.cs @@ -24,6 +24,7 @@ namespace Lucene.Net.Store /// <summary> /// DataInput backed by a byte array. /// <b>WARNING:</b> this class omits all low-level checks. + /// <para/> /// @lucene.experimental /// </summary> public sealed class ByteArrayDataInput : DataInput @@ -53,8 +54,10 @@ namespace Lucene.Net.Store Reset(bytes, 0, bytes.Length); } - // NOTE: sets pos to 0, which is not right if you had - // called reset w/ non-zero offset!! + /// <summary> + /// NOTE: sets pos to 0, which is not right if you had + /// called reset w/ non-zero offset!! + /// </summary> public void Rewind() { pos = 0; @@ -110,7 +113,8 @@ namespace Lucene.Net.Store /// </summary> public override int ReadInt32() { - return ((bytes[pos++] & 0xFF) << 24) | ((bytes[pos++] & 0xFF) << 16) | ((bytes[pos++] & 0xFF) << 8) | (bytes[pos++] & 0xFF); + return ((bytes[pos++] & 0xFF) << 24) | ((bytes[pos++] & 0xFF) << 16) + | ((bytes[pos++] & 0xFF) << 8) | (bytes[pos++] & 0xFF); } /// <summary> @@ -118,8 +122,10 @@ namespace Lucene.Net.Store /// </summary> public override long ReadInt64() { - int i1 = ((bytes[pos++] & 0xff) << 24) | ((bytes[pos++] & 0xff) << 16) | ((bytes[pos++] & 0xff) << 8) | (bytes[pos++] & 0xff); - int i2 = ((bytes[pos++] & 0xff) << 24) | ((bytes[pos++] & 0xff) << 16) | ((bytes[pos++] & 0xff) << 8) | (bytes[pos++] & 0xff); + int i1 = ((bytes[pos++] & 0xff) << 24) | ((bytes[pos++] & 0xff) << 16) + | ((bytes[pos++] & 0xff) << 8) | (bytes[pos++] & 0xff); + int i2 = ((bytes[pos++] & 0xff) << 24) | ((bytes[pos++] & 0xff) << 16) + | ((bytes[pos++] & 0xff) << 8) | (bytes[pos++] & 0xff); return (((long)i1) << 32) | (i2 & 0xFFFFFFFFL); } @@ -128,16 +134,6 @@ namespace Lucene.Net.Store /// </summary> public override int ReadVInt32() { - // .NET Port: going back to original style code instead of Java code below due to sbyte/byte diff - /*byte b = Bytes[Pos++]; - int i = b & 0x7F; - for (int shift = 7; (b & 0x80) != 0; shift += 7) - { - b = Bytes[Pos++]; - i |= (b & 0x7F) << shift; - } - return i;*/ - byte b = bytes[pos++]; if ((sbyte)b >= 0) { @@ -169,7 +165,7 @@ namespace Lucene.Net.Store { return i; } - throw new Exception("Invalid vInt detected (too many bits)"); + throw new Exception("Invalid VInt32 detected (too many bits)"); } /// <summary> @@ -177,16 +173,6 @@ namespace Lucene.Net.Store /// </summary> public override long ReadVInt64() { - // .NET Port: going back to old style code - /*byte b = Bytes[Pos++]; - long i = b & 0x7F; - for (int shift = 7; (b & 0x80) != 0; shift += 7) - { - b = Bytes[Pos++]; - i |= (b & 0x7FL) << shift; - } - return i;*/ - byte b = bytes[pos++]; if ((sbyte)b >= 0) { @@ -241,7 +227,7 @@ namespace Lucene.Net.Store { return i; } - throw new Exception("Invalid vLong detected (negative values disallowed)"); + throw new Exception("Invalid VInt64 detected (negative values disallowed)"); } // NOTE: AIOOBE not EOF if you read too much http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/ByteArrayDataOutput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/ByteArrayDataOutput.cs b/src/Lucene.Net.Core/Store/ByteArrayDataOutput.cs index a079571..0a5101f 100644 --- a/src/Lucene.Net.Core/Store/ByteArrayDataOutput.cs +++ b/src/Lucene.Net.Core/Store/ByteArrayDataOutput.cs @@ -26,6 +26,7 @@ namespace Lucene.Net.Store /// DataOutput backed by a byte array. /// <b>WARNING:</b> this class omits most low-level checks, /// so be sure to test heavily with assertions enabled. + /// <para/> /// @lucene.experimental /// </summary> public class ByteArrayDataOutput : DataOutput http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/ByteBufferIndexInput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/ByteBufferIndexInput.cs b/src/Lucene.Net.Core/Store/ByteBufferIndexInput.cs index e7f672f..8e38f65 100644 --- a/src/Lucene.Net.Core/Store/ByteBufferIndexInput.cs +++ b/src/Lucene.Net.Core/Store/ByteBufferIndexInput.cs @@ -2,6 +2,7 @@ using Lucene.Net.Support; using Lucene.Net.Util; using System; using System.Diagnostics; +using System.IO; using System.Reflection; namespace Lucene.Net.Store @@ -24,15 +25,15 @@ namespace Lucene.Net.Store */ /// <summary> - /// Base IndexInput implementation that uses an array - /// of ByteBuffers to represent a file. - /// <p> - /// Because Java's ByteBuffer uses an int to address the + /// Base <see cref="IndexInput"/> implementation that uses an array + /// of <see cref="ByteBuffer"/>s to represent a file. + /// <para/> + /// Because Java's <see cref="ByteBuffer"/> uses an <see cref="int"/> to address the /// values, it's necessary to access a file greater /// <see cref="int.MaxValue"/> in size using multiple byte buffers. - /// <p> + /// <para/> /// For efficiency, this class requires that the buffers - /// are a power-of-two (<code>chunkSizePower</code>). + /// are a power-of-two (<c>chunkSizePower</c>). /// </summary> public abstract class ByteBufferIndexInput : IndexInput { @@ -65,7 +66,7 @@ namespace Lucene.Net.Store internal ByteBufferIndexInput(string resourceDescription, ByteBuffer[] buffers, long length, int chunkSizePower, bool trackClones) : base(resourceDescription) { - //this.buffers = buffers; + //this.buffers = buffers; // LUCENENET: this is set in SetBuffers() this.length = length; this.chunkSizePower = chunkSizePower; this.chunkSizeMask = (1L << chunkSizePower) - 1L; @@ -104,14 +105,14 @@ namespace Lucene.Net.Store curBufIndex++; if (curBufIndex >= buffers.Length) { - throw new System.IO.EndOfStreamException("read past EOF: " + this); + throw new EndOfStreamException("read past EOF: " + this); } curBuf = buffers[curBufIndex]; curBuf.Position = 0; } while (!curBuf.HasRemaining); return curBuf.Get(); } - catch (System.NullReferenceException) + catch (NullReferenceException) { throw new ObjectDisposedException(this.GetType().GetTypeInfo().FullName, "Already closed: " + this); } @@ -134,7 +135,7 @@ namespace Lucene.Net.Store curBufIndex++; if (curBufIndex >= buffers.Length) { - throw new System.IO.EndOfStreamException("read past EOF: " + this); + throw new EndOfStreamException("read past EOF: " + this); } curBuf = buffers[curBufIndex]; curBuf.Position = 0; @@ -142,7 +143,7 @@ namespace Lucene.Net.Store } curBuf.Get(b, offset, len); } - catch (System.NullReferenceException) + catch (NullReferenceException) { throw new ObjectDisposedException(this.GetType().GetTypeInfo().FullName, "Already closed: " + this); } @@ -161,7 +162,7 @@ namespace Lucene.Net.Store { return base.ReadInt16(); } - catch (System.NullReferenceException) + catch (NullReferenceException) { throw new ObjectDisposedException(this.GetType().GetTypeInfo().FullName, "Already closed: " + this); } @@ -180,7 +181,7 @@ namespace Lucene.Net.Store { return base.ReadInt32(); } - catch (System.NullReferenceException) + catch (NullReferenceException) { throw new ObjectDisposedException(this.GetType().GetTypeInfo().FullName, "Already closed: " + this); } @@ -199,7 +200,7 @@ namespace Lucene.Net.Store { return base.ReadInt64(); } - catch (System.NullReferenceException) + catch (NullReferenceException) { throw new ObjectDisposedException(this.GetType().GetTypeInfo().FullName, "Already closed: " + this); } @@ -211,7 +212,7 @@ namespace Lucene.Net.Store { return (((long)curBufIndex) << chunkSizePower) + curBuf.Position - offset; } - catch (System.NullReferenceException) + catch (NullReferenceException) { throw new ObjectDisposedException(this.GetType().GetTypeInfo().FullName, "Already closed: " + this); } @@ -222,7 +223,7 @@ namespace Lucene.Net.Store // necessary in case offset != 0 and pos < 0, but pos >= -offset if (pos < 0L) { - throw new System.ArgumentException("Seeking to negative position: " + this); + throw new ArgumentException("Seeking to negative position: " + this); } pos += offset; // we use >> here to preserve negative, so we will catch AIOOBE, @@ -236,15 +237,15 @@ namespace Lucene.Net.Store this.curBufIndex = bi; this.curBuf = b; } - catch (System.IndexOutOfRangeException) + catch (IndexOutOfRangeException) { - throw new System.IO.EndOfStreamException("seek past EOF: " + this); + throw new EndOfStreamException("seek past EOF: " + this); } - catch (System.ArgumentException) + catch (ArgumentException) { - throw new System.IO.EndOfStreamException("seek past EOF: " + this); + throw new EndOfStreamException("seek past EOF: " + this); } - catch (System.NullReferenceException) + catch (NullReferenceException) { throw new ObjectDisposedException(this.GetType().GetTypeInfo().FullName, "Already closed: " + this); } @@ -262,7 +263,7 @@ namespace Lucene.Net.Store { clone.Seek(GetFilePointer()); } - catch (System.IO.IOException ioe) + catch (IOException ioe) { throw new Exception("Should never happen: " + this, ioe); } @@ -285,7 +286,7 @@ namespace Lucene.Net.Store { clone.Seek(0L); } - catch (System.IO.IOException ioe) + catch (IOException ioe) { throw new Exception("Should never happen: " + this, ioe); } @@ -301,7 +302,7 @@ namespace Lucene.Net.Store } if (offset < 0 || length < 0 || offset + length > this.length) { - throw new System.ArgumentException("slice() " + sliceDescription + " out of bounds: offset=" + offset + ",length=" + length + ",fileLength=" + this.length + ": " + this); + throw new ArgumentException("slice() " + sliceDescription + " out of bounds: offset=" + offset + ",length=" + length + ",fileLength=" + this.length + ": " + this); } // include our own offset into the final offset: @@ -326,8 +327,8 @@ namespace Lucene.Net.Store /// <summary> /// Returns a sliced view from a set of already-existing buffers: - /// the last buffer's limit() will be correct, but - /// you must deal with offset separately (the first buffer will not be adjusted) + /// the last buffer's <see cref="Support.Buffer.Limit"/> will be correct, but + /// you must deal with <paramref name="offset"/> separately (the first buffer will not be adjusted) /// </summary> private ByteBuffer[] BuildSlice(ByteBuffer[] buffers, long offset, long length) { http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/CheckSumIndexInput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/CheckSumIndexInput.cs b/src/Lucene.Net.Core/Store/CheckSumIndexInput.cs index 12dbe4f..16dcc2f 100644 --- a/src/Lucene.Net.Core/Store/CheckSumIndexInput.cs +++ b/src/Lucene.Net.Core/Store/CheckSumIndexInput.cs @@ -20,15 +20,15 @@ namespace Lucene.Net.Store */ /// <summary> - /// Extension of IndexInput, computing checksum as it goes. - /// Callers can retrieve the checksum via <seealso cref="#getChecksum()"/>. + /// Extension of <see cref="IndexInput"/>, computing checksum as it goes. + /// Callers can retrieve the checksum via <see cref="Checksum"/>. /// </summary> public abstract class ChecksumIndexInput : IndexInput { /// <summary> - /// resourceDescription should be a non-null, opaque string - /// describing this resource; it's returned from - /// <seealso cref="#toString"/>. + /// <paramref name="resourceDescription"/> should be a non-null, opaque string + /// describing this resource; it's returned from + /// <see cref="object.ToString()"/>. /// </summary> protected ChecksumIndexInput(string resourceDescription) : base(resourceDescription) @@ -40,9 +40,9 @@ namespace Lucene.Net.Store public abstract long Checksum { get; } /// <summary> - /// {@inheritDoc} - /// - /// <seealso cref="ChecksumIndexInput"/> can only seek forward and seeks are expensive + /// Sets current position in this file, where the next read will occur. + /// <para/> + /// <see cref="ChecksumIndexInput"/> can only seek forward and seeks are expensive /// since they imply to read bytes in-between the current position and the /// target position in order to update the checksum. /// </summary> http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/CompoundFileDirectory.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/CompoundFileDirectory.cs b/src/Lucene.Net.Core/Store/CompoundFileDirectory.cs index 136ad47..9a07672 100644 --- a/src/Lucene.Net.Core/Store/CompoundFileDirectory.cs +++ b/src/Lucene.Net.Core/Store/CompoundFileDirectory.cs @@ -2,6 +2,7 @@ using Lucene.Net.Support; using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; namespace Lucene.Net.Store @@ -30,42 +31,42 @@ namespace Lucene.Net.Store /// <summary> /// Class for accessing a compound stream. - /// this class implements a directory, but is limited to only read operations. + /// This class implements a directory, but is limited to only read operations. /// Directory methods that would normally modify data throw an exception. - /// <p> + /// <para/> /// All files belonging to a segment have the same name with varying extensions. - /// The extensions correspond to the different file formats used by the <seealso cref="Codec"/>. + /// The extensions correspond to the different file formats used by the <see cref="Codecs.Codec"/>. /// When using the Compound File format these files are collapsed into a - /// single <tt>.cfs</tt> file (except for the <seealso cref="LiveDocsFormat"/>, with a - /// corresponding <tt>.cfe</tt> file indexing its sub-files. - /// <p> + /// single <c>.cfs</c> file (except for the <see cref="Codecs.LiveDocsFormat"/>, with a + /// corresponding <c>.cfe</c> file indexing its sub-files. + /// <para/> /// Files: - /// <ul> - /// <li><tt>.cfs</tt>: An optional "virtual" file consisting of all the other - /// index files for systems that frequently run out of file handles. - /// <li><tt>.cfe</tt>: The "virtual" compound file's entry table holding all - /// entries in the corresponding .cfs file. - /// </ul> - /// <p>Description:</p> - /// <ul> - /// <li>Compound (.cfs) --> Header, FileData <sup>FileCount</sup></li> - /// <li>Compound Entry Table (.cfe) --> Header, FileCount, <FileName, - /// DataOffset, DataLength> <sup>FileCount</sup>, Footer</li> - /// <li>Header --> <seealso cref="CodecUtil#writeHeader CodecHeader"/></li> - /// <li>FileCount --> <seealso cref="DataOutput#writeVInt VInt"/></li> - /// <li>DataOffset,DataLength --> <seealso cref="DataOutput#writeLong UInt64"/></li> - /// <li>FileName --> <seealso cref="DataOutput#writeString String"/></li> - /// <li>FileData --> raw file data</li> - /// <li>Footer --> <seealso cref="CodecUtil#writeFooter CodecFooter"/></li> - /// </ul> - /// <p>Notes:</p> - /// <ul> - /// <li>FileCount indicates how many files are contained in this compound file. - /// The entry table that follows has that many entries. - /// <li>Each directory entry contains a long pointer to the start of this file's data - /// section, the files length, and a String with that file's name. - /// </ul> - /// + /// <list type="bullet"> + /// <item><c>.cfs</c>: An optional "virtual" file consisting of all the other + /// index files for systems that frequently run out of file handles.</item> + /// <item><c>.cfe</c>: The "virtual" compound file's entry table holding all + /// entries in the corresponding .cfs file.</item> + /// </list> + /// <para>Description:</para> + /// <list type="bullet"> + /// <item>Compound (.cfs) --> Header, FileData <sup>FileCount</sup></item> + /// <item>Compound Entry Table (.cfe) --> Header, FileCount, <FileName, + /// DataOffset, DataLength> <sup>FileCount</sup>, Footer</item> + /// <item>Header --> <see cref="CodecUtil.WriteHeader"/></item> + /// <item>FileCount --> <see cref="DataOutput.WriteVInt32"/></item> + /// <item>DataOffset,DataLength --> <see cref="DataOutput.WriteInt64"/></item> + /// <item>FileName --> <see cref="DataOutput.WriteString"/></item> + /// <item>FileData --> raw file data</item> + /// <item>Footer --> <see cref="CodecUtil.WriteFooter"/></item> + /// </list> + /// <para>Notes:</para> + /// <list type="bullet"> + /// <item>FileCount indicates how many files are contained in this compound file. + /// The entry table that follows has that many entries.</item> + /// <item>Each directory entry contains a long pointer to the start of this file's data + /// section, the files length, and a <see cref="string"/> with that file's name.</item> + /// </list> + /// <para/> /// @lucene.experimental /// </summary> public sealed class CompoundFileDirectory : BaseDirectory @@ -88,7 +89,7 @@ namespace Lucene.Net.Store private readonly IndexInputSlicer handle; /// <summary> - /// Create a new CompoundFileDirectory. + /// Create a new <see cref="CompoundFileDirectory"/>. /// </summary> public CompoundFileDirectory(Directory directory, string fileName, IOContext context, bool openForWrite) { @@ -136,7 +137,7 @@ namespace Lucene.Net.Store /// Helper method that reads CFS entries from an input stream </summary> private static IDictionary<string, FileEntry> ReadEntries(IndexInputSlicer handle, Directory dir, string name) { - System.IO.IOException priorE = null; + IOException priorE = null; IndexInput stream = null; ChecksumIndexInput entriesStream = null; // read the first VInt. If it is negative, it's the version number @@ -160,7 +161,9 @@ namespace Lucene.Net.Store throw new CorruptIndexException("Illegal/impossible header for CFS file: " + secondByte + "," + thirdByte + "," + fourthByte); } int version = CodecUtil.CheckHeaderNoMagic(stream, CompoundFileWriter.DATA_CODEC, CompoundFileWriter.VERSION_START, CompoundFileWriter.VERSION_CURRENT); - string entriesFileName = IndexFileNames.SegmentFileName(IndexFileNames.StripExtension(name), "", IndexFileNames.COMPOUND_FILE_ENTRIES_EXTENSION); + string entriesFileName = IndexFileNames.SegmentFileName( + IndexFileNames.StripExtension(name), "", + IndexFileNames.COMPOUND_FILE_ENTRIES_EXTENSION); entriesStream = dir.OpenChecksumInput(entriesFileName, IOContext.READ_ONCE); CodecUtil.CheckHeader(entriesStream, CompoundFileWriter.ENTRY_CODEC, CompoundFileWriter.VERSION_START, CompoundFileWriter.VERSION_CURRENT); int numEntries = entriesStream.ReadVInt32(); @@ -169,16 +172,11 @@ namespace Lucene.Net.Store { FileEntry fileEntry = new FileEntry(); string id = entriesStream.ReadString(); - - //If the key was already present - if (mapping.ContainsKey(id)) + FileEntry previous = mapping.Put(id, fileEntry); + if (previous != null) { throw new CorruptIndexException("Duplicate cfs entry id=" + id + " in CFS: " + entriesStream); } - else - { - mapping[id] = fileEntry; - } fileEntry.Offset = entriesStream.ReadInt64(); fileEntry.Length = entriesStream.ReadInt64(); } @@ -200,7 +198,7 @@ namespace Lucene.Net.Store } return mapping; } - catch (System.IO.IOException ioe) + catch (IOException ioe) { priorE = ioe; } @@ -221,7 +219,8 @@ namespace Lucene.Net.Store { if (firstInt < CompoundFileWriter.FORMAT_NO_SEGMENT_PREFIX) { - throw new CorruptIndexException("Incompatible format version: " + firstInt + " expected >= " + CompoundFileWriter.FORMAT_NO_SEGMENT_PREFIX + " (resource: " + stream + ")"); + throw new CorruptIndexException("Incompatible format version: " + + firstInt + " expected >= " + CompoundFileWriter.FORMAT_NO_SEGMENT_PREFIX + " (resource: " + stream + ")"); } // It's a post-3.1 index, read the count. count = stream.ReadVInt32(); @@ -261,15 +260,11 @@ namespace Lucene.Net.Store entry = new FileEntry(); entry.Offset = offset; - FileEntry previous; - if (entries.TryGetValue(id, out previous)) + FileEntry previous = entries.Put(id, entry); + if (previous != null) { throw new CorruptIndexException("Duplicate cfs entry id=" + id + " in CFS: " + stream); } - else - { - entries[id] = entry; - } } // set the length of the final entry @@ -327,9 +322,9 @@ namespace Lucene.Net.Store Debug.Assert(!openForWrite); string id = IndexFileNames.StripSegmentName(name); FileEntry entry; - if (!entries.TryGetValue(id, out entry)) + if (!entries.TryGetValue(id, out entry) || entry == null) { - throw new Exception("No sub-file with id " + id + " found (fileName=" + name + " files: " + Arrays.ToString(entries.Keys) + ")"); + throw new FileNotFoundException("No sub-file with id " + id + " found (fileName=" + name + " files: " + Arrays.ToString(entries.Keys) + ")"); } return handle.OpenSlice(name, entry.Offset, entry.Length); } @@ -373,23 +368,23 @@ namespace Lucene.Net.Store /// <summary> /// Not implemented </summary> - /// <exception cref="UnsupportedOperationException"> always: not supported by CFS </exception> + /// <exception cref="NotSupportedException"> always: not supported by CFS </exception> public override void DeleteFile(string name) { - throw new System.NotSupportedException(); + throw new NotSupportedException(); } /// <summary> /// Not implemented </summary> - /// <exception cref="UnsupportedOperationException"> always: not supported by CFS </exception> + /// <exception cref="NotSupportedException"> always: not supported by CFS </exception> public void RenameFile(string from, string to) { - throw new System.NotSupportedException(); + throw new NotSupportedException(); } /// <summary> /// Returns the length of a file in the directory. </summary> - /// <exception cref="System.IO.IOException"> if the file does not exist </exception> + /// <exception cref="IOException"> if the file does not exist </exception> public override long FileLength(string name) { EnsureOpen(); @@ -400,7 +395,7 @@ namespace Lucene.Net.Store FileEntry e = entries[IndexFileNames.StripSegmentName(name)]; if (e == null) { - throw new Exception(name); + throw new FileNotFoundException(name); } return e.Length; } @@ -413,15 +408,15 @@ namespace Lucene.Net.Store public override void Sync(ICollection<string> names) { - throw new System.NotSupportedException(); + throw new NotSupportedException(); } /// <summary> /// Not implemented </summary> - /// <exception cref="UnsupportedOperationException"> always: not supported by CFS </exception> + /// <exception cref="NotSupportedException"> always: not supported by CFS </exception> public override Lock MakeLock(string name) { - throw new System.NotSupportedException(); + throw new NotSupportedException(); } public override IndexInputSlicer CreateSlicer(string name, IOContext context) @@ -432,7 +427,7 @@ namespace Lucene.Net.Store FileEntry entry = entries[id]; if (entry == null) { - throw new Exception("No sub-file with id " + id + " found (fileName=" + name + " files: " + Arrays.ToString(entries.Keys) + ")"); + throw new FileNotFoundException("No sub-file with id " + id + " found (fileName=" + name + " files: " + Arrays.ToString(entries.Keys) + ")"); } return new IndexInputSlicerAnonymousInnerClassHelper(this, entry); } @@ -441,9 +436,9 @@ namespace Lucene.Net.Store { private readonly CompoundFileDirectory outerInstance; - private Lucene.Net.Store.CompoundFileDirectory.FileEntry entry; + private FileEntry entry; - public IndexInputSlicerAnonymousInnerClassHelper(CompoundFileDirectory outerInstance, Lucene.Net.Store.CompoundFileDirectory.FileEntry entry) + public IndexInputSlicerAnonymousInnerClassHelper(CompoundFileDirectory outerInstance, FileEntry entry) : base(outerInstance) { this.outerInstance = outerInstance; @@ -459,7 +454,7 @@ namespace Lucene.Net.Store return outerInstance.handle.OpenSlice(sliceDescription, entry.Offset + offset, length); } - [Obsolete] + [Obsolete("Only for reading CFS files from 3.x indexes.")] public override IndexInput OpenFullSlice() { return OpenSlice("full-slice", 0, entry.Length); http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/CompoundFileWriter.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/CompoundFileWriter.cs b/src/Lucene.Net.Core/Store/CompoundFileWriter.cs index 062ff81..1defb98 100644 --- a/src/Lucene.Net.Core/Store/CompoundFileWriter.cs +++ b/src/Lucene.Net.Core/Store/CompoundFileWriter.cs @@ -2,6 +2,7 @@ using Lucene.Net.Support; using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; using System.Reflection; @@ -30,9 +31,10 @@ namespace Lucene.Net.Store /// <summary> /// Combines multiple files into a single compound file. + /// <para/> + /// @lucene.internal /// </summary> - /// <seealso cref= CompoundFileDirectory - /// @lucene.internal </seealso> + /// <seealso cref="CompoundFileDirectory"/> internal sealed class CompoundFileWriter : IDisposable { private sealed class FileEntry @@ -60,7 +62,6 @@ namespace Lucene.Net.Store // versioning for the .cfs file internal const string DATA_CODEC = "CompoundFileWriterData"; - internal const int VERSION_START = 0; internal const int VERSION_CHECKSUM = 1; internal const int VERSION_CURRENT = VERSION_CHECKSUM; @@ -71,10 +72,8 @@ namespace Lucene.Net.Store private readonly Directory directory; private readonly IDictionary<string, FileEntry> entries = new Dictionary<string, FileEntry>(); private readonly ISet<string> seenIDs = new HashSet<string>(); - // all entries that are written to a sep. file but not yet moved into CFS private readonly LinkedList<FileEntry> pendingEntries = new LinkedList<FileEntry>(); - private bool closed = false; private IndexOutput dataOut; private readonly AtomicBoolean outputTaken = new AtomicBoolean(false); @@ -85,17 +84,17 @@ namespace Lucene.Net.Store /// Create the compound stream in the specified file. The file name is the /// entire name (no extensions are added). /// </summary> - /// <exception cref="NullPointerException"> - /// if <code>dir</code> or <code>name</code> is null </exception> + /// <exception cref="NullReferenceException"> + /// if <paramref name="dir"/> or <paramref name="name"/> is <c>null</c> </exception> internal CompoundFileWriter(Directory dir, string name) { if (dir == null) { - throw new System.NullReferenceException("directory cannot be null"); + throw new NullReferenceException("directory cannot be null"); // LUCENENET TODO: ArgumentNullException? } if (name == null) { - throw new System.NullReferenceException("name cannot be null"); + throw new NullReferenceException("name cannot be null"); // LUCENENET TODO: ArgumentNullException? } directory = dir; entryTableName = IndexFileNames.SegmentFileName(IndexFileNames.StripExtension(name), "", IndexFileNames.COMPOUND_FILE_ENTRIES_EXTENSION); @@ -119,7 +118,7 @@ namespace Lucene.Net.Store { if (!success) { - IOUtils.CloseWhileHandlingException((IDisposable)dataOut); + IOUtils.CloseWhileHandlingException(dataOut); } } } @@ -148,10 +147,10 @@ namespace Lucene.Net.Store } /// <summary> - /// Closes all resources and writes the entry table + /// Disposes all resources and writes the entry table /// </summary> /// <exception cref="InvalidOperationException"> - /// if close() had been called before or if no file has been added to + /// if <see cref="Dispose"/> had been called before or if no file has been added to /// this object </exception> public void Dispose() { @@ -159,7 +158,7 @@ namespace Lucene.Net.Store { return; } - System.IO.IOException priorException = null; + IOException priorException = null; IndexOutput entryTableOut = null; // TODO this code should clean up after itself // (remove partial .cfs/.cfe) @@ -175,7 +174,7 @@ namespace Lucene.Net.Store Debug.Assert(dataOut != null); CodecUtil.WriteFooter(dataOut); } - catch (System.IO.IOException e) + catch (IOException e) { priorException = e; } @@ -188,7 +187,7 @@ namespace Lucene.Net.Store entryTableOut = directory.CreateOutput(entryTableName, IOContext.DEFAULT); WriteEntryTable(entries.Values, entryTableOut); } - catch (System.IO.IOException e) + catch (IOException e) { priorException = e; } @@ -224,7 +223,7 @@ namespace Lucene.Net.Store long diff = endPtr - startPtr; if (diff != length) { - throw new System.IO.IOException("Difference in the output file offsets " + diff + " does not match the original file length " + length); + throw new IOException("Difference in the output file offsets " + diff + " does not match the original file length " + length); } fileEntry.Offset = startPtr; success = true; @@ -268,7 +267,7 @@ namespace Lucene.Net.Store Debug.Assert(name != null, "name must not be null"); if (entries.ContainsKey(name)) { - throw new System.ArgumentException("File " + name + " already exists"); + throw new ArgumentException("File " + name + " already exists"); } FileEntry entry = new FileEntry(); entry.File = name; @@ -318,8 +317,8 @@ namespace Lucene.Net.Store { while (pendingEntries.Count > 0) { - FileEntry entry = pendingEntries.First(); - pendingEntries.RemoveFirst(); ; + FileEntry entry = pendingEntries.First.Value; + pendingEntries.Remove(entry); ; CopyFileEntry(GetOutput(), entry); entries[entry.File] = entry; } @@ -337,7 +336,7 @@ namespace Lucene.Net.Store FileEntry fileEntry = entries[name]; if (fileEntry == null) { - throw new Exception(name + " does not exist"); + throw new FileNotFoundException(name + " does not exist"); } return fileEntry.Length; } http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/DataInput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/DataInput.cs b/src/Lucene.Net.Core/Store/DataInput.cs index f6799c6..7b1be2a 100644 --- a/src/Lucene.Net.Core/Store/DataInput.cs +++ b/src/Lucene.Net.Core/Store/DataInput.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Text; namespace Lucene.Net.Store @@ -26,30 +27,31 @@ namespace Lucene.Net.Store /// Abstract base class for performing read operations of Lucene's low-level /// data types. /// - /// <p>{@code DataInput} may only be used from one thread, because it is not + /// <para/><see cref="DataInput"/> may only be used from one thread, because it is not /// thread safe (it keeps internal state like file position). To allow - /// multithreaded use, every {@code DataInput} instance must be cloned before - /// used in another thread. Subclasses must therefore implement <seealso cref="#clone()"/>, - /// returning a new {@code DataInput} which operates on the same underlying + /// multithreaded use, every <see cref="DataInput"/> instance must be cloned before + /// used in another thread. Subclasses must therefore implement <see cref="Clone()"/>, + /// returning a new <see cref="DataInput"/> which operates on the same underlying /// resource, but positioned independently. /// </summary> public abstract class DataInput { private const int SKIP_BUFFER_SIZE = 1024; - /* this buffer is used to skip over bytes with the default implementation of - * skipBytes. The reason why we need to use an instance member instead of - * sharing a single instance across threads is that some delegating - * implementations of DataInput might want to reuse the provided buffer in - * order to eg. update the checksum. If we shared the same buffer across - * threads, then another thread might update the buffer while the checksum is - * being computed, making it invalid. See LUCENE-5583 for more information. - */ + /// <summary> + /// This buffer is used to skip over bytes with the default implementation of + /// skipBytes. The reason why we need to use an instance member instead of + /// sharing a single instance across threads is that some delegating + /// implementations of DataInput might want to reuse the provided buffer in + /// order to eg.update the checksum. If we shared the same buffer across + /// threads, then another thread might update the buffer while the checksum is + /// being computed, making it invalid. See LUCENE-5583 for more information. + /// </summary> private byte[] skipBuffer; /// <summary> /// Reads and returns a single byte. </summary> - /// <seealso cref= DataOutput#writeByte(byte) </seealso> + /// <seealso cref="DataOutput.WriteByte(byte)"/> public abstract byte ReadByte(); /// <summary> @@ -57,21 +59,21 @@ namespace Lucene.Net.Store /// <param name="b"> the array to read bytes into </param> /// <param name="offset"> the offset in the array to start storing bytes </param> /// <param name="len"> the number of bytes to read </param> - /// <seealso cref= DataOutput#writeBytes(byte[],int) </seealso> + /// <seealso cref="DataOutput.WriteBytes(byte[], int)"/> public abstract void ReadBytes(byte[] b, int offset, int len); /// <summary> /// Reads a specified number of bytes into an array at the /// specified offset with control over whether the read /// should be buffered (callers who have their own buffer - /// should pass in "false" for useBuffer). Currently only - /// <seealso cref="BufferedIndexInput"/> respects this parameter. </summary> + /// should pass in "false" for <paramref name="useBuffer"/>). Currently only + /// <see cref="BufferedIndexInput"/> respects this parameter. </summary> /// <param name="b"> the array to read bytes into </param> /// <param name="offset"> the offset in the array to start storing bytes </param> /// <param name="len"> the number of bytes to read </param> /// <param name="useBuffer"> set to false if the caller will handle /// buffering. </param> - /// <seealso cref= DataOutput#writeBytes(byte[],int) </seealso> + /// <seealso cref="DataOutput.WriteBytes(byte[],int)"/> public virtual void ReadBytes(byte[] b, int offset, int len, bool useBuffer) { // Default to ignoring useBuffer entirely @@ -79,52 +81,43 @@ namespace Lucene.Net.Store } /// <summary> - /// Reads two bytes and returns a short. + /// Reads two bytes and returns a <see cref="short"/>. /// <para/> /// LUCENENET NOTE: Important - always cast to ushort (System.UInt16) before using to ensure /// the value is positive! /// <para/> /// NOTE: this was readShort() in Lucene /// </summary> - /// <seealso cref= DataOutput#writeByte(byte) </seealso> + /// <seealso cref="DataOutput.WriteInt16(short)"/> public virtual short ReadInt16() { return (short)(ushort)(((ReadByte() & 0xFF) << 8) | (ReadByte() & 0xFF)); } /// <summary> - /// Reads four bytes and returns an int. + /// Reads four bytes and returns an <see cref="int"/>. /// <para/> /// NOTE: this was readInt() in Lucene /// </summary> - /// <seealso cref= DataOutput#writeInt(int) </seealso> + /// <seealso cref="DataOutput.WriteInt32(int)"/> public virtual int ReadInt32() { - return ((ReadByte() & 0xFF) << 24) | ((ReadByte() & 0xFF) << 16) | ((ReadByte() & 0xFF) << 8) | (ReadByte() & 0xFF); + return ((ReadByte() & 0xFF) << 24) | ((ReadByte() & 0xFF) << 16) + | ((ReadByte() & 0xFF) << 8) | (ReadByte() & 0xFF); } /// <summary> - /// Reads an int stored in variable-length format. Reads between one and + /// Reads an <see cref="int"/> stored in variable-length format. Reads between one and /// five bytes. Smaller values take fewer bytes. Negative numbers are not /// supported. /// <para/> - /// The format is described further in <seealso cref="DataOutput#writeVInt(int)"/>. + /// The format is described further in <see cref="DataOutput.WriteVInt32(int)"/>. /// <para/> /// NOTE: this was readVInt() in Lucene /// </summary> - /// <seealso cref= DataOutput#writeVInt(int) </seealso> + /// <seealso cref="DataOutput.WriteVInt32(int)"/> public virtual int ReadVInt32() { - // .NET Port: Going back to original code instead of Java code below due to sbyte/byte diff - /*byte b = ReadByte(); - int i = b & 0x7F; - for (int shift = 7; (b & 0x80) != 0; shift += 7) - { - b = ReadByte(); - i |= (b & 0x7F) << shift; - } - return i;*/ - byte b = ReadByte(); if ((sbyte)b >= 0) { @@ -156,45 +149,43 @@ namespace Lucene.Net.Store { return i; } - throw new System.IO.IOException("Invalid vInt32 detected (too many bits)"); + throw new IOException("Invalid VInt32 detected (too many bits)"); } /// <summary> - /// Reads eight bytes and returns a long. + /// Reads eight bytes and returns a <see cref="long"/>. /// <para/> /// NOTE: this was readLong() in Lucene /// </summary> - /// <seealso cref= DataOutput#writeLong(long) </seealso> + /// <seealso cref="DataOutput.WriteInt64(long)"/> public virtual long ReadInt64() { - long halfA = ((long)ReadInt32()) << 32; - long halfB = (ReadInt32() & 0xFFFFFFFFL); - long ret = halfA | halfB; - return ret; + return (((long)ReadInt32()) << 32) | (ReadInt32() & 0xFFFFFFFFL); } /// <summary> - /// Reads a long stored in variable-length format. Reads between one and + /// Reads a <see cref="long"/> stored in variable-length format. Reads between one and /// nine bytes. Smaller values take fewer bytes. Negative numbers are not /// supported. /// <para/> - /// The format is described further in <seealso cref="DataOutput#writeVInt(int)"/>. + /// The format is described further in <seealso cref="DataOutput.WriteVInt32(int)"/>. /// <para/> /// NOTE: this was readVLong() in Lucene /// </summary> - /// <seealso cref= DataOutput#writeVLong(long) </seealso> + /// <seealso cref="DataOutput.WriteVInt64(long)"/> public virtual long ReadVInt64() { - // .NET Port: going back to old style code - /*byte b = ReadByte(); + /* This is the original code of this method, + * but a Hotspot bug (see LUCENE-2975) corrupts the for-loop if + * readByte() is inlined. So the loop was unwinded! + byte b = readByte(); long i = b & 0x7F; - for (int shift = 7; (b & 0x80) != 0; shift += 7) - { - b = ReadByte(); - i |= (b & 0x7FL) << shift; + for (int shift = 7; (b & 0x80) != 0; shift += 7) { + b = readByte(); + i |= (b & 0x7FL) << shift; } - return i;*/ - + return i; + */ byte b = ReadByte(); if ((sbyte)b >= 0) { @@ -249,16 +240,16 @@ namespace Lucene.Net.Store { return i; } - throw new System.IO.IOException("Invalid vLong detected (negative values disallowed)"); + throw new IOException("Invalid VInt64 detected (negative values disallowed)"); } /// <summary> - /// Reads a string. </summary> - /// <seealso cref= DataOutput#writeString(String) </seealso> + /// Reads a <see cref="string"/>. </summary> + /// <seealso cref="DataOutput.WriteString(string)"/> public virtual string ReadString() { - var length = ReadVInt32(); - var bytes = new byte[length]; + int length = ReadVInt32(); + byte[] bytes = new byte[length]; ReadBytes(bytes, 0, length); return Encoding.UTF8.GetString(bytes); @@ -267,30 +258,21 @@ namespace Lucene.Net.Store /// <summary> /// Returns a clone of this stream. /// - /// <p>Clones of a stream access the same data, and are positioned at the same + /// <para/>Clones of a stream access the same data, and are positioned at the same /// point as the stream they were cloned from. /// - /// <p>Expert: Subclasses must ensure that clones may be positioned at + /// <para/>Expert: Subclasses must ensure that clones may be positioned at /// different points in the input from each other and from the stream they /// were cloned from. /// </summary> public virtual object Clone() { - DataInput clone = null; - try - { - clone = (DataInput)base.MemberwiseClone(); - } - catch (Exception) - { - } - - return clone; + return base.MemberwiseClone(); } /// <summary> - /// Reads a Map<String,String> previously written - /// with <seealso cref="DataOutput#writeStringStringMap(Map)"/>. + /// Reads a IDictionary<string,string> previously written + /// with <see cref="DataOutput.WriteStringStringMap(IDictionary{string, string})"/>. /// </summary> public virtual IDictionary<string, string> ReadStringStringMap() { @@ -307,8 +289,8 @@ namespace Lucene.Net.Store } /// <summary> - /// Reads a Set<String> previously written - /// with <seealso cref="DataOutput#writeStringSet(Set)"/>. + /// Reads a ISet<string> previously written + /// with <see cref="DataOutput.WriteStringSet(ISet{string})"/>. /// </summary> public virtual ISet<string> ReadStringSet() { @@ -323,16 +305,16 @@ namespace Lucene.Net.Store } /// <summary> - /// Skip over <code>numBytes</code> bytes. The contract on this method is that it + /// Skip over <paramref name="numBytes"/> bytes. The contract on this method is that it /// should have the same behavior as reading the same number of bytes into a - /// buffer and discarding its content. Negative values of <code>numBytes</code> + /// buffer and discarding its content. Negative values of <paramref name="numBytes"/> /// are not supported. /// </summary> public virtual void SkipBytes(long numBytes) { if (numBytes < 0) { - throw new System.ArgumentException("numBytes must be >= 0, got " + numBytes); + throw new ArgumentException("numBytes must be >= 0, got " + numBytes); } if (skipBuffer == null) { http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7def889c/src/Lucene.Net.Core/Store/DataOutput.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Core/Store/DataOutput.cs b/src/Lucene.Net.Core/Store/DataOutput.cs index 55960d2..dc90c90 100644 --- a/src/Lucene.Net.Core/Store/DataOutput.cs +++ b/src/Lucene.Net.Core/Store/DataOutput.cs @@ -27,19 +27,19 @@ namespace Lucene.Net.Store /// Abstract base class for performing write operations of Lucene's low-level /// data types. /// - /// <p>{@code DataOutput} may only be used from one thread, because it is not + /// <para/><see cref="DataOutput"/> may only be used from one thread, because it is not /// thread safe (it keeps internal state like file position). /// </summary> public abstract class DataOutput { /// <summary> /// Writes a single byte. - /// <p> + /// <para/> /// The most primitive data type is an eight-bit byte. Files are /// accessed as sequences of bytes. All other data types are defined /// as sequences of bytes, so file formats are byte-order independent. /// </summary> - /// <seealso cref= IndexInput#readByte() </seealso> + /// <seealso cref="IndexInput.ReadByte()"/> public abstract void WriteByte(byte b); /// <summary> @@ -58,17 +58,17 @@ namespace Lucene.Net.Store /// <param name="b"> the bytes to write </param> /// <param name="offset"> the offset in the byte array </param> /// <param name="length"> the number of bytes to write </param> - /// <seealso cref= DataInput#readBytes(byte[],int,int) </seealso> + /// <seealso cref="DataInput.ReadBytes(byte[], int, int)"/> public abstract void WriteBytes(byte[] b, int offset, int length); /// <summary> - /// Writes an int as four bytes. + /// Writes an <see cref="int"/> as four bytes. /// <para/> /// 32-bit unsigned integer written as four bytes, high-order bytes first. /// <para/> /// NOTE: this was writeInt() in Lucene /// </summary> - /// <seealso cref= DataInput#readInt() </seealso> + /// <seealso cref="DataInput.ReadInt32()"/> public virtual void WriteInt32(int i) { WriteByte((byte)(sbyte)(i >> 24)); @@ -82,7 +82,7 @@ namespace Lucene.Net.Store /// <para/> /// NOTE: this was writeShort() in Lucene /// </summary> - /// <seealso cref= DataInput#readShort() </seealso> + /// <seealso cref="DataInput.ReadInt16()"/> public virtual void WriteInt16(short i) { WriteByte((byte)(sbyte)((ushort)i >> 8)); @@ -90,113 +90,110 @@ namespace Lucene.Net.Store } /// <summary> - /// Writes an int in a variable-length format. Writes between one and + /// Writes an <see cref="int"/> in a variable-length format. Writes between one and /// five bytes. Smaller values take fewer bytes. Negative numbers are /// supported, but should be avoided. - /// <p>VByte is a variable-length format for positive integers is defined where the + /// <para>VByte is a variable-length format for positive integers is defined where the /// high-order bit of each byte indicates whether more bytes remain to be read. The /// low-order seven bits are appended as increasingly more significant bits in the /// resulting integer value. Thus values from zero to 127 may be stored in a single - /// byte, values from 128 to 16,383 may be stored in two bytes, and so on.</p> - /// <p>VByte Encoding Example</p> - /// <table cellspacing="0" cellpadding="2" border="0"> - /// <col width="64*"> - /// <col width="64*"> - /// <col width="64*"> - /// <col width="64*"> - /// <tr valign="top"> - /// <th align="left" width="25%">Value</th> - /// <th align="left" width="25%">Byte 1</th> - /// <th align="left" width="25%">Byte 2</th> - /// <th align="left" width="25%">Byte 3</th> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">0</td> - /// <td width="25%"><kbd>00000000</kbd></td> - /// <td width="25%"></td> - /// <td width="25%"></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">1</td> - /// <td width="25%"><kbd>00000001</kbd></td> - /// <td width="25%"></td> - /// <td width="25%"></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">2</td> - /// <td width="25%"><kbd>00000010</kbd></td> - /// <td width="25%"></td> - /// <td width="25%"></td> - /// </tr> - /// <tr> - /// <td valign="top" width="25%">...</td> - /// <td valign="bottom" width="25%"></td> - /// <td valign="bottom" width="25%"></td> - /// <td valign="bottom" width="25%"></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">127</td> - /// <td width="25%"><kbd>01111111</kbd></td> - /// <td width="25%"></td> - /// <td width="25%"></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">128</td> - /// <td width="25%"><kbd>10000000</kbd></td> - /// <td width="25%"><kbd>00000001</kbd></td> - /// <td width="25%"></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">129</td> - /// <td width="25%"><kbd>10000001</kbd></td> - /// <td width="25%"><kbd>00000001</kbd></td> - /// <td width="25%"></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">130</td> - /// <td width="25%"><kbd>10000010</kbd></td> - /// <td width="25%"><kbd>00000001</kbd></td> - /// <td width="25%"></td> - /// </tr> - /// <tr> - /// <td valign="top" width="25%">...</td> - /// <td width="25%"></td> - /// <td width="25%"></td> - /// <td width="25%"></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">16,383</td> - /// <td width="25%"><kbd>11111111</kbd></td> - /// <td width="25%"><kbd>01111111</kbd></td> - /// <td width="25%"></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">16,384</td> - /// <td width="25%"><kbd>10000000</kbd></td> - /// <td width="25%"><kbd>10000000</kbd></td> - /// <td width="25%"><kbd>00000001</kbd></td> - /// </tr> - /// <tr valign="bottom"> - /// <td width="25%">16,385</td> - /// <td width="25%"><kbd>10000001</kbd></td> - /// <td width="25%"><kbd>10000000</kbd></td> - /// <td width="25%"><kbd>00000001</kbd></td> - /// </tr> - /// <tr> - /// <td valign="top" width="25%">...</td> - /// <td valign="bottom" width="25%"></td> - /// <td valign="bottom" width="25%"></td> - /// <td valign="bottom" width="25%"></td> - /// </tr> - /// </table> - /// <p>this provides compression while still being efficient to decode.</p> + /// byte, values from 128 to 16,383 may be stored in two bytes, and so on.</para> + /// <para>VByte Encoding Example</para> + /// <list type="table"> + /// <listheader> + /// <term>Value</term> + /// <term>Byte 1</term> + /// <term>Byte 2</term> + /// <term>Byte 3</term> + /// </listheader> + /// <item> + /// <term>0</term> + /// <term>00000000</term> + /// <term></term> + /// <term></term> + /// </item> + /// <item> + /// <term>1</term> + /// <term>00000001</term> + /// <term></term> + /// <term></term> + /// </item> + /// <item> + /// <term>2</term> + /// <term>00000010</term> + /// <term></term> + /// <term></term> + /// </item> + /// <item> + /// <term>...</term> + /// <term></term> + /// <term></term> + /// <term></term> + /// </item> + /// <item> + /// <term>127</term> + /// <term>01111111</term> + /// <term></term> + /// <term></term> + /// </item> + /// <item> + /// <term>128</term> + /// <term>10000000</term> + /// <term>00000001</term> + /// <term></term> + /// </item> + /// <item> + /// <term>129</term> + /// <term>10000001</term> + /// <term>00000001</term> + /// <term></term> + /// </item> + /// <item> + /// <term>130</term> + /// <term>10000010</term> + /// <term>00000001</term> + /// <term></term> + /// </item> + /// <item> + /// <term>...</term> + /// <term></term> + /// <term></term> + /// <term></term> + /// </item> + /// <item> + /// <term>16,383</term> + /// <term>11111111</term> + /// <term>01111111</term> + /// <term></term> + /// </item> + /// <item> + /// <term>16,384</term> + /// <term>10000000</term> + /// <term>10000000</term> + /// <term>00000001</term> + /// </item> + /// <item> + /// <term>16,385</term> + /// <term>10000001</term> + /// <term>10000000</term> + /// <term>00000001</term> + /// </item> + /// <item> + /// <term>...</term> + /// <term></term> + /// <term></term> + /// <term></term> + /// </item> + /// </list> + /// + /// <para>this provides compression while still being efficient to decode.</para> /// <para/> /// NOTE: this was writeVInt() in Lucene /// </summary> /// <param name="i"> Smaller values take fewer bytes. Negative numbers are /// supported, but should be avoided. </param> /// <exception cref="System.IO.IOException"> If there is an I/O error writing to the underlying medium. </exception> - /// <seealso cref= DataInput#readVInt() </seealso> + /// <seealso cref="DataInput.ReadVInt32()"/> public void WriteVInt32(int i) { while ((i & ~0x7F) != 0) @@ -208,13 +205,13 @@ namespace Lucene.Net.Store } /// <summary> - /// Writes a long as eight bytes. + /// Writes a <see cref="long"/> as eight bytes. /// <para/> /// 64-bit unsigned integer written as eight bytes, high-order bytes first. /// <para/> /// NOTE: this was writeLong() in Lucene /// </summary> - /// <seealso cref= DataInput#readLong() </seealso> + /// <seealso cref="DataInput.ReadLong()"/> public virtual void WriteInt64(long i) { WriteInt32((int)(i >> 32)); @@ -222,15 +219,15 @@ namespace Lucene.Net.Store } /// <summary> - /// Writes an long in a variable-length format. Writes between one and nine + /// Writes an <see cref="long"/> in a variable-length format. Writes between one and nine /// bytes. Smaller values take fewer bytes. Negative numbers are not /// supported. /// <para/> - /// The format is described further in <seealso cref="DataOutput#writeVInt(int)"/>. + /// The format is described further in <see cref="DataOutput.WriteVInt32(int)"/>. /// <para/> /// NOTE: this was writeVLong() in Lucene /// </summary> - /// <seealso cref= DataInput#readVLong() </seealso> + /// <seealso cref="DataInput.ReadVInt64()"/> public void WriteVInt64(long i) { Debug.Assert(i >= 0L); @@ -244,15 +241,15 @@ namespace Lucene.Net.Store /// <summary> /// Writes a string. - /// <p> + /// <para/> /// Writes strings as UTF-8 encoded bytes. First the length, in bytes, is - /// written as a <seealso cref="#writeVInt VInt"/>, followed by the bytes. + /// written as a <see cref="WriteVInt32"/>, followed by the bytes. /// </summary> - /// <seealso cref= DataInput#readString() </seealso> + /// <seealso cref="DataInput.ReadString()"/> public virtual void WriteString(string s) { var utf8Result = new BytesRef(10); - UnicodeUtil.UTF16toUTF8(s.ToCharArray(), 0, s.Length, utf8Result); + UnicodeUtil.UTF16toUTF8(s, 0, s.Length, utf8Result); WriteVInt32(utf8Result.Length); WriteBytes(utf8Result.Bytes, 0, utf8Result.Length); } @@ -288,13 +285,13 @@ namespace Lucene.Net.Store } /// <summary> - /// Writes a String map. - /// <p> - /// First the size is written as an <seealso cref="#writeInt(int) Int32"/>, + /// Writes a <see cref="T:IDictionary{string, string}"/>. + /// <para/> + /// First the size is written as an <see cref="WriteInt32(int)"/>, /// followed by each key-value pair written as two consecutive - /// <seealso cref="#writeString(String) String"/>s. + /// <see cref="WriteString(string)"/>s. /// </summary> - /// <param name="map"> Input map. May be null (equivalent to an empty map) </param> + /// <param name="map"> Input <see cref="T:IDictionary{string, string}"/>. May be <c>null</c> (equivalent to an empty dictionary) </param> public virtual void WriteStringStringMap(IDictionary<string, string> map) { if (map == null) @@ -313,14 +310,14 @@ namespace Lucene.Net.Store } /// <summary> - /// Writes a String set. - /// <p> - /// First the size is written as an <seealso cref="#writeInt(int) Int32"/>, + /// Writes a <see cref="string"/> set. + /// <para/> + /// First the size is written as an <see cref="WriteInt32(int)"/>, /// followed by each value written as a - /// <seealso cref="#writeString(String) String"/>. + /// <see cref="WriteString(string)"/>. /// </summary> - /// <param name="set"> Input set. May be null (equivalent to an empty set) </param> - public virtual void WriteStringSet(ICollection<string> set) + /// <param name="set"> Input <see cref="T:ISet{string}"/>. May be <c>null</c> (equivalent to an empty set) </param> + public virtual void WriteStringSet(ICollection<string> set) // LUCENENET TODO: API change back to ISet<string> { if (set == null) {
