You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ar...@apache.org on 2008/06/25 04:50:13 UTC
svn commit: r671401 [1/2] -
/incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/
Author: aroush
Date: Tue Jun 24 19:50:12 2008
New Revision: 671401
URL: http://svn.apache.org/viewvc?rev=671401&view=rev
Log:
Release: Apache Lucene.Net.2.3.1 build 001 "Alpha"
Added:
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/AlreadyClosedException.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockObtainFailedException.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockReleaseFailedException.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockStressTest.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockVerifyServer.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/VerifyingLockFactory.cs
Modified:
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexInput.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexOutput.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Directory.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/FSDirectory.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexInput.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexOutput.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Lock.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockFactory.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/MMapDirectory.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/NativeFSLockFactory.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Package.html
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMDirectory.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMFile.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMInputStream.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMOutputStream.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/SimpleFSLockFactory.cs
incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/SingleInstanceLockFactory.cs
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/AlreadyClosedException.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/AlreadyClosedException.cs?rev=671401&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/AlreadyClosedException.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/AlreadyClosedException.cs Tue Jun 24 19:50:12 2008
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Lucene.Net.Store
+{
+
+ /// <summary> This exception is thrown when there is an attempt to
+ /// access something that has already been closed.
+ /// </summary>
+ [Serializable]
+ public class AlreadyClosedException : System.SystemException
+ {
+ public AlreadyClosedException(System.String message) : base(message)
+ {
+ }
+ }
+}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexInput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/BufferedIndexInput.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexInput.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexInput.cs Tue Jun 24 19:50:12 2008
@@ -23,18 +23,17 @@
/// <summary>Base implementation class for buffered {@link IndexInput}. </summary>
public abstract class BufferedIndexInput : IndexInput, System.ICloneable
{
- internal static readonly int BUFFER_SIZE;
+
+ /// <summary>Default buffer size </summary>
+ public const int BUFFER_SIZE = 1024;
+
+ private int bufferSize = BUFFER_SIZE;
private byte[] buffer;
private long bufferStart = 0; // position in file of buffer
private int bufferLength = 0; // end of valid bytes
private int bufferPosition = 0; // next byte to read
-
- public static int BUFFER_SIZE_ForNUnitTest
- {
- get { return BUFFER_SIZE; }
- }
public override byte ReadByte()
{
@@ -43,11 +42,70 @@
return buffer[bufferPosition++];
}
+ public BufferedIndexInput()
+ {
+ }
+
+ /// <summary>Inits BufferedIndexInput with a specific bufferSize </summary>
+ public BufferedIndexInput(int bufferSize)
+ {
+ CheckBufferSize(bufferSize);
+ this.bufferSize = bufferSize;
+ }
+
+ /// <summary>Change the buffer size used by this IndexInput </summary>
+ public virtual void SetBufferSize(int newSize)
+ {
+ System.Diagnostics.Debug.Assert(buffer == null || bufferSize == buffer.Length);
+ if (newSize != bufferSize)
+ {
+ CheckBufferSize(newSize);
+ bufferSize = newSize;
+ if (buffer != null)
+ {
+ // Resize the existing buffer and carefully save as
+ // many bytes as possible starting from the current
+ // bufferPosition
+ byte[] newBuffer = new byte[newSize];
+ int leftInBuffer = bufferLength - bufferPosition;
+ int numToCopy;
+ if (leftInBuffer > newSize)
+ numToCopy = newSize;
+ else
+ numToCopy = leftInBuffer;
+ Array.Copy(buffer, bufferPosition, newBuffer, 0, numToCopy);
+ bufferStart += bufferPosition;
+ bufferPosition = 0;
+ bufferLength = numToCopy;
+ buffer = newBuffer;
+ }
+ }
+ }
+
+ /// <seealso cref="setBufferSize">
+ /// </seealso>
+ public virtual int GetBufferSize()
+ {
+ return bufferSize;
+ }
+
+ private void CheckBufferSize(int bufferSize)
+ {
+ if (bufferSize <= 0)
+ throw new System.ArgumentException("bufferSize must be greater than 0 (got " + bufferSize + ")");
+ }
+
public override void ReadBytes(byte[] b, int offset, int len)
{
+ ReadBytes(b, offset, len, true);
+ }
+
+ public override void ReadBytes(byte[] b, int offset, int len, bool useBuffer)
+ {
+
if (len <= (bufferLength - bufferPosition))
{
- // the buffer contains enough data to satistfy this request
+ // the buffer contains enough data to satisfy this request
if (len > 0)
// to allow b to be null if len is 0...
Array.Copy(buffer, bufferPosition, b, offset, len);
@@ -65,9 +123,10 @@
bufferPosition += available;
}
// and now, read the remaining 'len' bytes:
- if (len < BUFFER_SIZE)
+ if (useBuffer && len < bufferSize)
{
- // If the amount left to read is small enough, do it in the usual
+ // If the amount left to read is small enough, and
+ // we are allowed to use our buffer, do it in the usual
// buffered way: fill the buffer and copy from it:
Refill();
if (bufferLength < len)
@@ -84,10 +143,13 @@
}
else
{
- // The amount left to read is larger than the buffer - there's no
- // performance reason not to read it all at once. Note that unlike
- // the previous code of this function, there is no need to do a seek
- // here, because there's no need to reread what we had in the buffer.
+ // The amount left to read is larger than the buffer
+ // or we've been asked to not use our buffer -
+ // there's no performance reason not to read it all
+ // at once. Note that unlike the previous code of
+ // this function, there is no need to do a seek
+ // here, because there's no need to reread what we
+ // had in the buffer.
long after = bufferStart + bufferPosition + len;
if (after > Length())
throw new System.IO.IOException("read past EOF");
@@ -102,16 +164,19 @@
private void Refill()
{
long start = bufferStart + bufferPosition;
- long end = start + BUFFER_SIZE;
+ long end = start + bufferSize;
if (end > Length())
- // don't read past EOF
+ // don't read past EOF
end = Length();
bufferLength = (int) (end - start);
if (bufferLength <= 0)
throw new System.IO.IOException("read past EOF");
if (buffer == null)
- buffer = new byte[BUFFER_SIZE]; // allocate buffer lazily
+ {
+ buffer = new byte[bufferSize]; // allocate buffer lazily
+ SeekInternal(bufferStart);
+ }
ReadInternal(buffer, 0, bufferLength);
bufferStart = start;
@@ -127,7 +192,7 @@
/// </param>
/// <param name="length">the number of bytes to read
/// </param>
- public abstract void ReadInternal(byte[] b, int offset, int length);
+ protected internal abstract void ReadInternal(byte[] b, int offset, int length);
public override long GetFilePointer()
{
@@ -138,7 +203,7 @@
{
if (pos >= bufferStart && pos < (bufferStart + bufferLength))
bufferPosition = (int) (pos - bufferStart);
- // seek within buffer
+ // seek within buffer
else
{
bufferStart = pos;
@@ -151,26 +216,20 @@
/// <summary>Expert: implements seek. Sets current position in this file, where the
/// next {@link #ReadInternal(byte[],int,int)} will occur.
/// </summary>
- /// <seealso cref="#ReadInternal(byte[],int,int)">
+ /// <seealso cref="ReadInternal(byte[],int,int)">
/// </seealso>
- public abstract void SeekInternal(long pos);
+ protected internal abstract void SeekInternal(long pos);
public override System.Object Clone()
{
BufferedIndexInput clone = (BufferedIndexInput) base.Clone();
- if (buffer != null)
- {
- clone.buffer = new byte[BUFFER_SIZE];
- Array.Copy(buffer, 0, clone.buffer, 0, bufferLength);
- }
+ clone.buffer = null;
+ clone.bufferLength = 0;
+ clone.bufferPosition = 0;
+ clone.bufferStart = GetFilePointer();
return clone;
}
-
- static BufferedIndexInput()
- {
- BUFFER_SIZE = BufferedIndexOutput.BUFFER_SIZE;
- }
}
}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexOutput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/BufferedIndexOutput.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexOutput.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/BufferedIndexOutput.cs Tue Jun 24 19:50:12 2008
@@ -23,7 +23,7 @@
/// <summary>Base implementation class for buffered {@link IndexOutput}. </summary>
public abstract class BufferedIndexOutput : IndexOutput
{
- internal const int BUFFER_SIZE = 1024;
+ internal const int BUFFER_SIZE = 16384;
private byte[] buffer = new byte[BUFFER_SIZE];
private long bufferStart = 0; // position in file of buffer
@@ -46,14 +46,14 @@
/// </param>
/// <seealso cref="IndexInput.ReadBytes(byte[],int,int)">
/// </seealso>
- public override void WriteBytes(byte[] b, int length)
+ public override void WriteBytes(byte[] b, int offset, int length)
{
int bytesLeft = BUFFER_SIZE - bufferPosition;
// is there enough space in the buffer?
if (bytesLeft >= length)
{
// we add the data to the end of the buffer
- Array.Copy(b, 0, buffer, bufferPosition, length);
+ Array.Copy(b, offset, buffer, bufferPosition, length);
bufferPosition += length;
// if the buffer is full, flush it
if (BUFFER_SIZE - bufferPosition == 0)
@@ -68,7 +68,7 @@
if (bufferPosition > 0)
Flush();
// and write data at once
- FlushBuffer(b, length);
+ FlushBuffer(b, offset, length);
bufferStart += length;
}
else
@@ -79,7 +79,7 @@
while (pos < length)
{
pieceLength = (length - pos < bytesLeft)?length - pos:bytesLeft;
- Array.Copy(b, pos, buffer, bufferPosition, pieceLength);
+ Array.Copy(b, pos + offset, buffer, bufferPosition, pieceLength);
pos += pieceLength;
bufferPosition += pieceLength;
// if the buffer is full, flush it
@@ -109,7 +109,21 @@
/// </param>
/// <param name="len">the number of bytes to write
/// </param>
- public abstract void FlushBuffer(byte[] b, int len);
+ private void FlushBuffer(byte[] b, int len)
+ {
+ FlushBuffer(b, 0, len);
+ }
+
+ /// <summary>Expert: implements buffer write. Writes bytes at the current position in
+ /// the output.
+ /// </summary>
+ /// <param name="b">the bytes to write
+ /// </param>
+ /// <param name="offset">the offset in the byte array
+ /// </param>
+ /// <param name="len">the number of bytes to write
+ /// </param>
+ public abstract void FlushBuffer(byte[] b, int offset, int len);
/// <summary>Closes this stream to further operations. </summary>
public override void Close()
@@ -120,7 +134,7 @@
/// <summary>Returns the current position in this file, where the next write will
/// occur.
/// </summary>
- /// <seealso cref="#Seek(long)">
+ /// <seealso cref="Seek(long)">
/// </seealso>
public override long GetFilePointer()
{
@@ -128,7 +142,7 @@
}
/// <summary>Sets current position in this file, where the next write will occur.</summary>
- /// <seealso cref="#GetFilePointer()">
+ /// <seealso cref="GetFilePointer()">
/// </seealso>
public override void Seek(long pos)
{
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Directory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/Directory.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Directory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Directory.cs Tue Jun 24 19:50:12 2008
@@ -48,7 +48,12 @@
[NonSerialized]
protected internal LockFactory lockFactory;
- /// <summary>Returns an array of strings, one for each file in the directory. </summary>
+ /// <summary>Returns an array of strings, one for each file in the
+ /// directory. This method may return null (for example for
+ /// {@link FSDirectory} if the underlying directory doesn't
+ /// exist in the filesystem or there are permissions
+ /// problems).
+ /// </summary>
public abstract System.String[] List();
/// <summary>Returns true iff a file with the given name exists. </summary>
@@ -84,6 +89,18 @@
/// <summary>Returns a stream reading an existing file. </summary>
public abstract IndexInput OpenInput(System.String name);
+ /// <summary>Returns a stream reading an existing file, with the
+ /// specified read buffer size. The particular Directory
+ /// implementation may ignore the buffer size. Currently
+ /// the only Directory implementations that respect this
+ /// parameter are {@link FSDirectory} and {@link
+ /// Lucene.Net.Index.CompoundFileReader}.
+ /// </summary>
+ public virtual IndexInput OpenInput(System.String name, int bufferSize)
+ {
+ return OpenInput(name);
+ }
+
/// <summary>Construct a {@link Lock}.</summary>
/// <param name="name">the name of the lock file
/// </param>
@@ -95,7 +112,7 @@
/// specified lock. Only call this at a time when you are
/// certain this lock is no longer in use.
/// </summary>
- /// <param name="lockName">name of the lock to be cleared.
+ /// <param name="name">name of the lock to be cleared.
/// </param>
public virtual void ClearLock(System.String name)
{
@@ -160,6 +177,12 @@
public static void Copy(Directory src, Directory dest, bool closeDirSrc)
{
System.String[] files = src.List();
+
+ if (files == null)
+ {
+ throw new System.IO.IOException("cannot read directory " + src + ": list() returned null");
+ }
+
byte[] buf = new byte[BufferedIndexOutput.BUFFER_SIZE];
for (int i = 0; i < files.Length; i++)
{
@@ -176,7 +199,7 @@
long readCount = 0;
while (readCount < len)
{
- int toRead = readCount + BufferedIndexOutput.BUFFER_SIZE > len?(int) (len - readCount):BufferedIndexOutput.BUFFER_SIZE;
+ int toRead = readCount + BufferedIndexOutput.BUFFER_SIZE > len ? (int) (len - readCount) : BufferedIndexOutput.BUFFER_SIZE;
is_Renamed.ReadBytes(buf, 0, toRead);
os.WriteBytes(buf, toRead);
readCount += toRead;
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/FSDirectory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/FSDirectory.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/FSDirectory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/FSDirectory.cs Tue Jun 24 19:50:12 2008
@@ -260,7 +260,7 @@
{
System.String[] files = SupportClass.FileSupport.GetLuceneIndexFiles(directory.FullName, IndexFileNameFilter.GetFilter());
if (files == null)
- throw new System.IO.IOException("Cannot read directory " + directory.FullName);
+ throw new System.IO.IOException("cannot read directory " + directory.FullName + ": list() returned null");
for (int i = 0; i < files.Length; i++)
{
System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, files[i]));
@@ -605,12 +605,18 @@
return new FSIndexOutput(file);
}
- /// <summary>Returns a stream reading an existing file. </summary>
+ // Inherit javadoc
public override IndexInput OpenInput(System.String name)
{
return new FSIndexInput(new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name)));
}
+ // Inherit javadoc
+ public override IndexInput OpenInput(System.String name, int bufferSize)
+ {
+ return new FSIndexInput(new System.IO.FileInfo(directory.FullName + "\\" + name), bufferSize);
+ }
+
/// <summary> So we can do some byte-to-hexchar conversion below</summary>
private static readonly char[] HEX_DIGITS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
@@ -669,194 +675,196 @@
{
return this.GetType().FullName + "@" + directory;
}
-
- static FSDirectory()
+
+ protected internal class FSIndexInput : BufferedIndexInput, System.ICloneable
{
+
+ private class Descriptor : System.IO.BinaryReader
{
- try
+ // remember if the file is open, so that we don't try to close it
+ // more than once
+ private bool isOpen;
+ internal long position;
+ internal long length;
+
+ public Descriptor(FSIndexInput enclosingInstance, System.IO.FileInfo file, System.IO.FileAccess mode)
+ : base(new System.IO.FileStream(file.FullName, System.IO.FileMode.Open, mode, System.IO.FileShare.ReadWrite))
+ {
+ isOpen = true;
+ length = file.Length;
+ }
+
+ public override void Close()
{
- System.String name = SupportClass.AppSettings.Get("Lucene.Net.FSDirectory.class", typeof(FSDirectory).FullName);
- IMPL = System.Type.GetType(name);
+ if (isOpen)
+ {
+ isOpen = false;
+ base.Close();
+ }
}
- catch (System.Security.SecurityException)
+
+ ~Descriptor()
{
try
{
- IMPL = System.Type.GetType(typeof(FSDirectory).FullName);
+ Close();
}
- catch (System.Exception e)
+ finally
{
- throw new System.SystemException("cannot load default FSDirectory class: " + e.ToString(), e);
}
}
- catch (System.Exception e)
- {
- throw new System.SystemException("cannot load FSDirectory class: " + e.ToString(), e);
- }
- }
+ }
+
+ private Descriptor file;
+ internal bool isClone;
+
+ public bool isClone_ForNUnitTest
+ {
+ get { return isClone; }
+ }
+
+ public FSIndexInput(System.IO.FileInfo path) : this(path, BufferedIndexInput.BUFFER_SIZE)
{
- try
- {
- DIGESTER = System.Security.Cryptography.MD5.Create();
- }
- catch (System.Exception e)
+ }
+
+ public FSIndexInput(System.IO.FileInfo path, int bufferSize) : base(bufferSize)
+ {
+ file = new Descriptor(this, path, System.IO.FileAccess.Read);
+ }
+
+ /// <summary>IndexInput methods </summary>
+ protected internal override void ReadInternal(byte[] b, int offset, int len)
+ {
+ lock (file)
{
- throw new System.SystemException(e.ToString(), e);
+ long position = GetFilePointer();
+ if (position != file.position)
+ {
+ file.BaseStream.Seek(position, System.IO.SeekOrigin.Begin);
+ file.position = position;
+ }
+ int total = 0;
+ do
+ {
+ int i = file.Read(b, offset + total, len - total);
+ if (i <= 0)
+ throw new System.IO.IOException("read past EOF");
+ file.position += i;
+ total += i;
+ }
+ while (total < len);
}
}
- }
- }
-
-
- public class FSIndexInput : BufferedIndexInput, System.ICloneable
- {
- /// <summary>Method used for testing. Returns true if the underlying
- /// file descriptor is valid.
- /// </summary>
- public virtual bool IsFDValid()
- {
- return (file.BaseStream != null);
+
+ public override void Close()
+ {
+ // only close the file if this is not a clone
+ if (!isClone)
+ file.Close();
+ System.GC.SuppressFinalize(this);
+ }
+
+ protected internal override void SeekInternal(long position)
+ {
+ }
+
+ public override long Length()
+ {
+ return file.length;
+ }
+
+ public override System.Object Clone()
+ {
+ FSIndexInput clone = (FSIndexInput) base.Clone();
+ clone.isClone = true;
+ return clone;
+ }
+
+ /// <summary>Method used for testing. Returns true if the underlying
+ /// file descriptor is valid.
+ /// </summary>
+ public virtual bool IsFDValid()
+ {
+ return (file.BaseStream != null);
+ }
}
- private class Descriptor : System.IO.BinaryReader
+ protected internal class FSIndexOutput : BufferedIndexOutput
{
+ internal System.IO.BinaryWriter file = null;
+
// remember if the file is open, so that we don't try to close it
// more than once
private bool isOpen;
- internal long position;
- internal long length;
-
- public Descriptor(FSIndexInput enclosingInstance, System.IO.FileInfo file, System.IO.FileAccess mode)
- : base(new System.IO.FileStream(file.FullName, System.IO.FileMode.Open, mode, System.IO.FileShare.ReadWrite))
- {
+
+ public FSIndexOutput(System.IO.FileInfo path)
+ {
+ file = new System.IO.BinaryWriter(new System.IO.FileStream(path.FullName, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite));
isOpen = true;
- length = file.Length;
}
-
+
+ /// <summary>output methods: </summary>
+ public override void FlushBuffer(byte[] b, int offset, int size)
+ {
+ file.Write(b, offset, size);
+ }
public override void Close()
{
+ // only close the file if it has not been closed yet
if (isOpen)
{
- isOpen = false;
base.Close();
+ file.Close();
+ isOpen = false;
+ System.GC.SuppressFinalize(this);
}
}
-
- ~Descriptor()
+
+ /// <summary>Random-access methods </summary>
+ public override void Seek(long pos)
+ {
+ base.Seek(pos);
+ file.BaseStream.Seek(pos, System.IO.SeekOrigin.Begin);
+ }
+ public override long Length()
+ {
+ return file.BaseStream.Length;
+ }
+ }
+ static FSDirectory()
+ {
{
try
{
- Close();
+ System.String name = SupportClass.AppSettings.Get("Lucene.Net.FSDirectory.class", typeof(FSDirectory).FullName);
+ IMPL = System.Type.GetType(name);
}
- finally
+ catch (System.Security.SecurityException)
{
+ try
+ {
+ IMPL = System.Type.GetType(typeof(FSDirectory).FullName);
+ }
+ catch (System.Exception e)
+ {
+ throw new System.SystemException("cannot load default FSDirectory class: " + e.ToString(), e);
+ }
}
- }
- }
-
- private Descriptor file;
- internal bool isClone;
-
- public bool isClone_ForNUnitTest
- {
- get { return isClone; }
- }
-
- public FSIndexInput(System.IO.FileInfo path)
- {
- file = new Descriptor(this, path, System.IO.FileAccess.Read);
- }
-
- /// <summary>IndexInput methods </summary>
- public override void ReadInternal(byte[] b, int offset, int len)
- {
- lock (file)
+ catch (System.Exception e)
+ {
+ throw new System.SystemException("cannot load FSDirectory class: " + e.ToString(), e);
+ }
+ }
{
- long position = GetFilePointer();
- if (position != file.position)
+ try
{
- file.BaseStream.Seek(position, System.IO.SeekOrigin.Begin);
- file.position = position;
+ DIGESTER = System.Security.Cryptography.MD5.Create();
}
- int total = 0;
- do
+ catch (System.Exception e)
{
- int i = file.Read(b, offset + total, len - total);
- if (i <= 0)
- throw new System.IO.IOException("read past EOF");
- file.position += i;
- total += i;
+ throw new System.SystemException(e.ToString(), e);
}
- while (total < len);
- }
- }
-
- public override void Close()
- {
- // only close the file if this is not a clone
- if (!isClone)
- file.Close();
- System.GC.SuppressFinalize(this);
- }
-
- public override void SeekInternal(long position)
- {
- }
-
- public override long Length()
- {
- return file.length;
- }
-
- public override System.Object Clone()
- {
- FSIndexInput clone = (FSIndexInput) base.Clone();
- clone.isClone = true;
- return clone;
- }
- }
-
-
- class FSIndexOutput : BufferedIndexOutput
- {
- internal System.IO.BinaryWriter file = null;
-
- // remember if the file is open, so that we don't try to close it
- // more than once
- private bool isOpen;
-
- public FSIndexOutput(System.IO.FileInfo path)
- {
- file = new System.IO.BinaryWriter(new System.IO.FileStream(path.FullName, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite));
- isOpen = true;
- }
-
- /// <summary>output methods: </summary>
- public override void FlushBuffer(byte[] b, int size)
- {
- file.Write(b, 0, size);
- }
- public override void Close()
- {
- // only close the file if it has not been closed yet
- if (isOpen)
- {
- base.Close();
- file.Close();
- isOpen = false;
- System.GC.SuppressFinalize(this);
}
}
-
- /// <summary>Random-access methods </summary>
- public override void Seek(long pos)
- {
- base.Seek(pos);
- file.BaseStream.Seek(pos, System.IO.SeekOrigin.Begin);
- }
- public override long Length()
- {
- return file.BaseStream.Length;
- }
}
}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexInput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/IndexInput.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexInput.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexInput.cs Tue Jun 24 19:50:12 2008
@@ -45,6 +45,29 @@
/// </seealso>
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
+ /// {@link 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="IndexOutput.WriteBytes(byte[],int)">
+ /// </seealso>
+ public virtual void ReadBytes(byte[] b, int offset, int len, bool useBuffer)
+ {
+ // Default to ignoring useBuffer entirely
+ ReadBytes(b, offset, len);
+ }
+
/// <summary>Reads four bytes and returns an int.</summary>
/// <seealso cref="IndexOutput.WriteInt(int)">
/// </seealso>
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexOutput.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/IndexOutput.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexOutput.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/IndexOutput.cs Tue Jun 24 19:50:12 2008
@@ -42,7 +42,21 @@
/// </param>
/// <seealso cref="IndexInput.ReadBytes(byte[],int,int)">
/// </seealso>
- public abstract void WriteBytes(byte[] b, int length);
+ public virtual void WriteBytes(byte[] b, int length)
+ {
+ WriteBytes(b, 0, length);
+ }
+
+ /// <summary>Writes an array of bytes.</summary>
+ /// <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="IndexInput.ReadBytes(byte[],int,int)">
+ /// </seealso>
+ public abstract void WriteBytes(byte[] b, int offset, int length);
/// <summary>Writes an int as four bytes.</summary>
/// <seealso cref="IndexInput.ReadInt()">
@@ -137,6 +151,59 @@
}
}
+ /// <summary>Writes a sequence of UTF-8 encoded characters from a char[].</summary>
+ /// <param name="s">the source of the characters
+ /// </param>
+ /// <param name="start">the first character in the sequence
+ /// </param>
+ /// <param name="length">the number of characters in the sequence
+ /// </param>
+ /// <seealso cref="IndexInput.ReadChars(char[],int,int)">
+ /// </seealso>
+ public virtual void WriteChars(char[] s, int start, int length)
+ {
+ int end = start + length;
+ for (int i = start; i < end; i++)
+ {
+ int code = (int) s[i];
+ if (code >= 0x01 && code <= 0x7F)
+ WriteByte((byte) code);
+ else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0)
+ {
+ WriteByte((byte) (0xC0 | (code >> 6)));
+ WriteByte((byte) (0x80 | (code & 0x3F)));
+ }
+ else
+ {
+ WriteByte((byte) (0xE0 | (SupportClass.Number.URShift(code, 12))));
+ WriteByte((byte) (0x80 | ((code >> 6) & 0x3F)));
+ WriteByte((byte) (0x80 | (code & 0x3F)));
+ }
+ }
+ }
+
+ private static int COPY_BUFFER_SIZE = 16384;
+ private byte[] copyBuffer;
+
+ /// <summary>Copy numBytes bytes from input to ourself. </summary>
+ public virtual void CopyBytes(IndexInput input, long numBytes)
+ {
+ long left = numBytes;
+ if (copyBuffer == null)
+ copyBuffer = new byte[COPY_BUFFER_SIZE];
+ while (left > 0)
+ {
+ int toCopy;
+ if (left > COPY_BUFFER_SIZE)
+ toCopy = COPY_BUFFER_SIZE;
+ else
+ toCopy = (int) left;
+ input.ReadBytes(copyBuffer, 0, toCopy);
+ WriteBytes(copyBuffer, 0, toCopy);
+ left -= toCopy;
+ }
+ }
+
/// <summary>Forces any buffered output to be written. </summary>
public abstract void Flush();
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Lock.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/Lock.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Lock.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Lock.cs Tue Jun 24 19:50:12 2008
@@ -29,16 +29,24 @@
/// }.run();
/// </pre>
///
+ ///
/// </summary>
- /// <author> Doug Cutting
- /// </author>
- /// <version> $Id: Lock.java 472959 2006-11-09 16:21:50Z yonik $
+ /// <version> $Id: Lock.java 595448 2007-11-15 20:42:54Z mikemccand $
/// </version>
- /// <seealso cref="Directory#MakeLock(String)">
+ /// <seealso cref="Directory.MakeLock(String)">
/// </seealso>
public abstract class Lock
{
+
+ /// <summary>How long {@link #Obtain(long)} waits, in milliseconds,
+ /// in between attempts to acquire the lock.
+ /// </summary>
public static long LOCK_POLL_INTERVAL = 1000;
+
+ /// <summary>Pass this value to {@link #Obtain(long)} to try
+ /// forever to obtain the lock.
+ /// </summary>
+ public const long LOCK_OBTAIN_WAIT_FOREVER = - 1;
/// <summary>Attempts to obtain exclusive access and immediately return
/// upon success or failure.
@@ -53,34 +61,48 @@
/// </summary>
protected internal System.Exception failureReason;
- /// <summary>Attempts to obtain an exclusive lock within amount
- /// of time given. Currently polls once per second until
- /// lockWaitTimeout is passed.
+ /// <summary>Attempts to obtain an exclusive lock within amount of
+ /// time given. Polls once per {@link #LOCK_POLL_INTERVAL}
+ /// (currently 1000) milliseconds until lockWaitTimeout is
+ /// passed.
/// </summary>
- /// <param name="lockWaitTimeout">length of time to wait in ms
+ /// <param name="lockWaitTimeout">length of time to wait in
+ /// milliseconds or {@link
+ /// #LOCK_OBTAIN_WAIT_FOREVER} to retry forever
/// </param>
/// <returns> true if lock was obtained
/// </returns>
- /// <throws> IOException if lock wait times out or obtain() throws an IOException </throws>
+ /// <throws> LockObtainFailedException if lock wait times out </throws>
+ /// <throws> IllegalArgumentException if lockWaitTimeout is </throws>
+ /// <summary> out of bounds
+ /// </summary>
+ /// <throws> IOException if obtain() throws IOException </throws>
public virtual bool Obtain(long lockWaitTimeout)
{
failureReason = null;
bool locked = Obtain();
- int maxSleepCount = (int) (lockWaitTimeout / LOCK_POLL_INTERVAL);
- int sleepCount = 0;
+ if (lockWaitTimeout < 0 && lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER)
+ throw new System.ArgumentException("lockWaitTimeout should be LOCK_OBTAIN_WAIT_FOREVER or a non-negative number (got " + lockWaitTimeout + ")");
+
+ long maxSleepCount = lockWaitTimeout / LOCK_POLL_INTERVAL;
+ long sleepCount = 0;
while (!locked)
{
- if (sleepCount++ == maxSleepCount)
+ if (lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER && sleepCount++ >= maxSleepCount)
{
System.String reason = "Lock obtain timed out: " + this.ToString();
if (failureReason != null)
{
reason += (": " + failureReason);
}
- System.IO.IOException e = new System.IO.IOException(reason);
+ LockObtainFailedException e;
if (failureReason != null)
{
- e = new System.IO.IOException(reason, failureReason);
+ e = new LockObtainFailedException(reason, failureReason);
+ }
+ else
+ {
+ e = new LockObtainFailedException(reason);
}
throw e;
}
@@ -126,8 +148,12 @@
/// <summary>Calls {@link #doBody} while <i>lock</i> is obtained. Blocks if lock
/// cannot be obtained immediately. Retries to obtain lock once per second
/// until it is obtained, or until it has tried ten times. Lock is released when
- /// {@link #doBody} exits.
+ /// {@link #doBody} exits.
+ /// </summary>
+ /// <throws> LockObtainFailedException if lock could not </throws>
+ /// <summary> be obtained
/// </summary>
+ /// <throws> IOException if {@link Lock#obtain} throws IOException </throws>
public virtual System.Object Run()
{
bool locked = false;
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockFactory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/LockFactory.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockFactory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockFactory.cs Tue Jun 24 19:50:12 2008
@@ -20,9 +20,21 @@
namespace Lucene.Net.Store
{
- /// <summary> Base class for Locking implementation. {@link Directory} uses
- /// instances of this class to implement locking.
+ /// <summary> <p>Base class for Locking implementation. {@link Directory} uses
+ /// instances of this class to implement locking.</p>
+ ///
+ /// <p>Note that there are some useful tools to verify that
+ /// your LockFactory is working correctly: {@link
+ /// VerifyingLockFactory}, {@link LockStressTest}, {@link
+ /// LockVerifyServer}.</p>
+ ///
/// </summary>
+ /// <seealso cref="LockVerifyServer">
+ /// </seealso>
+ /// <seealso cref="LockStressTest">
+ /// </seealso>
+ /// <seealso cref="VerifyingLockFactory">
+ /// </seealso>
public abstract class LockFactory
{
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockObtainFailedException.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/LockObtainFailedException.cs?rev=671401&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockObtainFailedException.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockObtainFailedException.cs Tue Jun 24 19:50:12 2008
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Lucene.Net.Store
+{
+
+ /// <summary> This exception is thrown when the <code>write.lock</code>
+ /// could not be acquired. This
+ /// happens when a writer tries to open an index
+ /// that another writer already has open.
+ /// </summary>
+ /// <seealso cref="Lock.obtain(long).">
+ /// </seealso>
+ [Serializable]
+ public class LockObtainFailedException : System.IO.IOException
+ {
+ public LockObtainFailedException(System.String message) : base(message)
+ {
+ }
+
+ public LockObtainFailedException(System.String message, Exception cause) : base(message, cause)
+ {
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockReleaseFailedException.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/LockReleaseFailedException.cs?rev=671401&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockReleaseFailedException.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockReleaseFailedException.cs Tue Jun 24 19:50:12 2008
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Lucene.Net.Store
+{
+
+ /// <summary> This exception is thrown when the <code>write.lock</code>
+ /// could not be released.
+ /// </summary>
+ /// <seealso cref="Lock.release().">
+ /// </seealso>
+ [Serializable]
+ public class LockReleaseFailedException : System.IO.IOException
+ {
+ public LockReleaseFailedException(System.String message) : base(message)
+ {
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockStressTest.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/LockStressTest.cs?rev=671401&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockStressTest.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockStressTest.cs Tue Jun 24 19:50:12 2008
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Lucene.Net.Store
+{
+
+ /// <summary> Simple standalone tool that forever acquires & releases a
+ /// lock using a specific LockFactory. Run without any args
+ /// to see usage.
+ ///
+ /// </summary>
+ /// <seealso cref="VerifyingLockFactory">
+ /// </seealso>
+ /// <seealso cref="LockVerifyServer">
+ /// </seealso>
+
+ public class LockStressTest
+ {
+
+ [STAThread]
+ public static void Main(System.String[] args)
+ {
+
+ if (args.Length != 6)
+ {
+ System.Console.Out.WriteLine("\nUsage: java Lucene.Net.Store.LockStressTest myID verifierHostOrIP verifierPort lockFactoryClassName lockDirName sleepTime\n" + "\n" + " myID = int from 0 .. 255 (should be unique for test process)\n" + " verifierHostOrIP = host name or IP address where LockVerifyServer is running\n" + " verifierPort = port that LockVerifyServer is listening on\n" + " lockFactoryClassName = primary LockFactory class that we will use\n" + " lockDirName = path to the lock directory (only set for Simple/NativeFSLockFactory\n" + " sleepTimeMS = milliseconds to pause betweeen each lock obtain/release\n" + "\n" + "You should run multiple instances of this process, each with its own\n" + "unique ID, and each pointing to the same lock directory, to verify\n" + "that locking is working correctly.\n" + "\n" + "Make sure you are first running LockVerifyServer.\n" + "\n");
+ System.Environment.Exit(1);
+ }
+
+ int myID = System.Int32.Parse(args[0]);
+
+ if (myID < 0 || myID > 255)
+ {
+ System.Console.Out.WriteLine("myID must be a unique int 0..255");
+ System.Environment.Exit(1);
+ }
+
+ System.String verifierHost = args[1];
+ int verifierPort = System.Int32.Parse(args[2]);
+ System.String lockFactoryClassName = args[3];
+ System.String lockDirName = args[4];
+ int sleepTimeMS = System.Int32.Parse(args[5]);
+
+ System.Type c;
+ try
+ {
+ c = System.Type.GetType(lockFactoryClassName);
+ }
+ catch (System.Exception e)
+ {
+ throw new System.IO.IOException("unable to find LockClass " + lockFactoryClassName);
+ }
+
+ LockFactory lockFactory;
+ try
+ {
+ lockFactory = (LockFactory) System.Activator.CreateInstance(c);
+ }
+ catch (System.UnauthorizedAccessException e)
+ {
+ throw new System.IO.IOException("IllegalAccessException when instantiating LockClass " + lockFactoryClassName);
+ }
+ catch (System.InvalidCastException e)
+ {
+ throw new System.IO.IOException("unable to cast LockClass " + lockFactoryClassName + " instance to a LockFactory");
+ }
+ catch (System.Exception e)
+ {
+ throw new System.IO.IOException("InstantiationException when instantiating LockClass " + lockFactoryClassName);
+ }
+
+ System.IO.FileInfo lockDir = new System.IO.FileInfo(lockDirName);
+
+ if (lockFactory is NativeFSLockFactory)
+ {
+ ((NativeFSLockFactory) lockFactory).SetLockDir(lockDir);
+ }
+ else if (lockFactory is SimpleFSLockFactory)
+ {
+ ((SimpleFSLockFactory) lockFactory).SetLockDir(lockDir);
+ }
+
+ lockFactory.SetLockPrefix("test");
+
+ LockFactory verifyLF = new VerifyingLockFactory((byte) myID, lockFactory, verifierHost, verifierPort);
+
+ Lock l = verifyLF.MakeLock("test.lock");
+
+ while (true)
+ {
+
+ bool obtained = false;
+
+ try
+ {
+ obtained = l.Obtain(10);
+ }
+ catch (LockObtainFailedException e)
+ {
+ System.Console.Out.Write("x");
+ }
+
+ if (obtained)
+ {
+ System.Console.Out.Write("l");
+ l.Release();
+ }
+ System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64) 10000 * sleepTimeMS));
+ }
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockVerifyServer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/LockVerifyServer.cs?rev=671401&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockVerifyServer.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/LockVerifyServer.cs Tue Jun 24 19:50:12 2008
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Lucene.Net.Store
+{
+
+ /// <summary> Simple standalone server that must be running when you
+ /// use {@link VerifyingLockFactory}. This server simply
+ /// verifies at most one process holds the lock at a time.
+ /// Run without any args to see usage.
+ ///
+ /// </summary>
+ /// <seealso cref="VerifyingLockFactory">
+ /// </seealso>
+ /// <seealso cref="LockStressTest">
+ /// </seealso>
+
+ public class LockVerifyServer
+ {
+
+ private static System.String GetTime(long startTime)
+ {
+ return "[" + (((System.DateTime.Now.Ticks - 621355968000000000) / 10000 - startTime) / 1000) + "s] "; // {{Aroush-2.3.1}} Is this OK?!
+ }
+
+ [STAThread]
+ public static void Main(System.String[] args)
+ {
+
+ if (args.Length != 1)
+ {
+ System.Console.Out.WriteLine("\nUsage: java Lucene.Net.Store.LockVerifyServer port\n");
+ System.Environment.Exit(1);
+ }
+
+ int port = System.Int32.Parse(args[0]);
+
+ System.Net.Sockets.TcpListener temp_tcpListener;
+ temp_tcpListener = new System.Net.Sockets.TcpListener(System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList[0], port);
+ temp_tcpListener.Server.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket, System.Net.Sockets.SocketOptionName.ReuseAddress, 1);
+ temp_tcpListener.Start();
+ System.Net.Sockets.TcpListener s = temp_tcpListener;
+ System.Console.Out.WriteLine("\nReady on port " + port + "...");
+
+ int lockedID = 0;
+ long startTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
+
+ while (true)
+ {
+ System.Net.Sockets.TcpClient cs = s.AcceptTcpClient();
+ System.IO.Stream out_Renamed = cs.GetStream();
+ System.IO.Stream in_Renamed = cs.GetStream();
+
+ int id = in_Renamed.ReadByte();
+ int command = in_Renamed.ReadByte();
+
+ bool err = false;
+
+ if (command == 1)
+ {
+ // Locked
+ if (lockedID != 0)
+ {
+ err = true;
+ System.Console.Out.WriteLine(GetTime(startTime) + " ERROR: id " + id + " got lock, but " + lockedID + " already holds the lock");
+ }
+ lockedID = id;
+ }
+ else if (command == 0)
+ {
+ if (lockedID != id)
+ {
+ err = true;
+ System.Console.Out.WriteLine(GetTime(startTime) + " ERROR: id " + id + " released the lock, but " + lockedID + " is the one holding the lock");
+ }
+ lockedID = 0;
+ }
+ else
+ throw new System.SystemException("unrecognized command " + command);
+
+ System.Console.Out.Write(".");
+
+ if (err)
+ out_Renamed.WriteByte((System.Byte) 1);
+ else
+ out_Renamed.WriteByte((System.Byte) 0);
+
+ out_Renamed.Close();
+ in_Renamed.Close();
+ cs.Close();
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/MMapDirectory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/MMapDirectory.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/MMapDirectory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/MMapDirectory.cs Tue Jun 24 19:50:12 2008
@@ -123,7 +123,7 @@
byte[] data = new byte[rafc.Length];
raf.Read(data, 0, (int) rafc.Length);
- int bufSize = (length > (bufferStart + maxBufSize))?maxBufSize:(int) (length - bufferStart);
+ int bufSize = (length > (bufferStart + maxBufSize)) ? maxBufSize : (int) (length - bufferStart);
this.buffers[bufNr] = new System.IO.MemoryStream(data); // rafc.map(MapMode.READ_ONLY, bufferStart, bufSize); // {{Aroush-1.9}}
this.bufSizes[bufNr] = bufSize;
bufferStart += bufSize;
@@ -224,5 +224,10 @@
raf.Close();
}
}
+
+ public override IndexInput OpenInput(System.String name, int bufferSize)
+ {
+ return OpenInput(name);
+ }
}
}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/NativeFSLockFactory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/NativeFSLockFactory.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/NativeFSLockFactory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/NativeFSLockFactory.cs Tue Jun 24 19:50:12 2008
@@ -23,35 +23,31 @@
namespace Lucene.Net.Store
{
- /// <summary> Implements {@link LockFactory} using native OS file locks
- /// (available through java.nio.*). Note that for certain
- /// filesystems native locks are possible but must be
- /// explicity configured and enabled (and may be disabled by
- /// default). For example, for NFS servers there sometimes
- /// must be a separate lockd process running, and other
- /// configuration may be required such as running the server
- /// in kernel mode. Other filesystems may not even support
- /// native OS locks in which case you must use a different
- /// {@link LockFactory} implementation.
+ /// <summary> <p>Implements {@link LockFactory} using native OS file
+ /// locks. Note that because this LockFactory relies on
+ /// java.nio.* APIs for locking, any problems with those APIs
+ /// will cause locking to fail. Specifically, on certain NFS
+ /// environments the java.nio.* locks will fail (the lock can
+ /// incorrectly be double acquired) whereas {@link
+ /// SimpleFSLockFactory} worked perfectly in those same
+ /// environments. For NFS based access to an index, it's
+ /// recommended that you try {@link SimpleFSLockFactory}
+ /// first and work around the one limitation that a lock file
+ /// could be left when the JVM exits abnormally.</p>
///
- /// <p>The advantage of this lock factory over
- /// {@link SimpleFSLockFactory} is that the locks should be
- /// "correct", whereas {@link SimpleFSLockFactory} uses
- /// java.io.File.createNewFile which
- /// <a target="_top" href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#createNewFile()">has warnings</a> about not
- /// using it for locking. Furthermore, if the JVM crashes,
- /// the OS will free any held locks, whereas
- /// {@link SimpleFSLockFactory} will keep the locks held, requiring
- /// manual removal before re-running Lucene.</p>
+ /// <p>The primary benefit of {@link NativeFSLockFactory} is
+ /// that lock files will be properly removed (by the OS) if
+ /// the JVM has an abnormal exit.</p>
///
/// <p>Note that, unlike {@link SimpleFSLockFactory}, the existence of
/// leftover lock files in the filesystem on exiting the JVM
/// is fine because the OS will free the locks held against
/// these files even though the files still remain.</p>
///
- /// <p>Native locks file names have the substring "-n-", which
- /// you can use to differentiate them from lock files created
- /// by {@link SimpleFSLockFactory}.</p>
+ /// <p>If you suspect that this or any other LockFactory is
+ /// not working properly in your environment, you can easily
+ /// test it by using {@link VerifyingLockFactory}, {@link
+ /// LockVerifyServer} and {@link LockStressTest}.</p>
///
/// </summary>
/// <seealso cref="LockFactory">
@@ -91,6 +87,16 @@
l.Release();
}
+ /// <summary> Create a NativeFSLockFactory instance, with null (unset)
+ /// lock directory. This is package-private and is only
+ /// used by FSDirectory when creating this LockFactory via
+ /// the System property
+ /// Lucene.Net.Store.FSDirectoryLockFactoryClass.
+ /// </summary>
+ internal NativeFSLockFactory() : this((System.IO.FileInfo) null)
+ {
+ }
+
/// <summary> Create a NativeFSLockFactory instance, storing lock
/// files into the specified lockDirName:
///
@@ -109,66 +115,45 @@
/// </param>
public NativeFSLockFactory(System.IO.FileInfo lockDir)
{
-
+ SetLockDir(lockDir);
+ }
+
+ /// <summary> Set the lock directory. This is package-private and is
+ /// only used externally by FSDirectory when creating this
+ /// LockFactory via the System property
+ /// Lucene.Net.Store.FSDirectoryLockFactoryClass.
+ /// </summary>
+ internal virtual void SetLockDir(System.IO.FileInfo lockDir)
+ {
this.lockDir = lockDir;
-
- // Ensure that lockDir exists and is a directory.
- bool tmpBool;
- if (System.IO.File.Exists(lockDir.FullName))
- tmpBool = true;
- else
- tmpBool = System.IO.Directory.Exists(lockDir.FullName);
- if (!tmpBool)
+ if (lockDir != null)
{
- try
- {
- System.IO.Directory.CreateDirectory(lockDir.FullName);
- }
- catch
- {
- throw new System.IO.IOException("Cannot create directory: " + lockDir.FullName);
- }
- }
- else if (!System.IO.Directory.Exists(lockDir.FullName))
- {
- throw new System.IO.IOException("Found regular file where directory expected: " + lockDir.FullName);
+ // Ensure that lockDir exists and is a directory.
+ bool tmpBool;
+ if (System.IO.File.Exists(lockDir.FullName))
+ tmpBool = true;
+ else
+ tmpBool = System.IO.Directory.Exists(lockDir.FullName);
+ if (!tmpBool)
+ {
+ try
+ {
+ System.IO.Directory.CreateDirectory(lockDir.FullName);
+ }
+ catch
+ {
+ throw new System.IO.IOException("Cannot create directory: " + lockDir.FullName);
+ }
+ }
+ else if (!System.IO.Directory.Exists(lockDir.FullName))
+ {
+ throw new System.IO.IOException("Found regular file where directory expected: " + lockDir.FullName);
+ }
+
+ AcquireTestLock();
}
-
- AcquireTestLock();
}
- /// <summary>
- /// </summary>
- internal NativeFSLockFactory()
- {
- lockDir = null;
- }
-
- /// <summary>
- /// Set the lock directory. This is package-private and is
- /// only used externally by FSDirectory when creating this
- /// LockFactory via the System property
- /// org.apache.lucene.store.FSDirectoryLockFactoryClass.
- /// </summary>
- /// <param name="lockDir"></param>
- internal void SetLockDir(System.IO.FileInfo lockDir)
- {
- this.lockDir = lockDir;
- if (lockDir != null)
- {
- // Ensure that lockDir exists and is a directory.
- if (!lockDir.Exists)
- {
- if (System.IO.Directory.CreateDirectory(lockDir.FullName) == null)
- throw new System.IO.IOException("Cannot create directory: " + lockDir.FullName);
- }
- else if (!new System.IO.DirectoryInfo(lockDir.FullName).Exists)
- {
- throw new System.IO.IOException("Found regular file where directory expected: " + lockDir.FullName);
- }
- }
- }
-
public override Lock MakeLock(System.String lockName)
{
lock (this)
@@ -409,66 +394,61 @@
{
lock (this)
{
- try
+ if (IsLocked())
{
- if (IsLocked())
+ try
+ {
+ channel.Unlock(0, channel.Length);
+ }
+ finally
{
+ lock_Renamed = false;
try
{
- channel.Unlock(0, channel.Length);
+ channel.Close();
}
finally
{
- lock_Renamed = false;
+ channel = null;
try
{
- channel.Close();
+ f.Close();
}
finally
{
- channel = null;
- try
+ f = null;
+ lock (LOCK_HELD)
{
- f.Close();
- }
- finally
- {
- f = null;
- lock (LOCK_HELD)
- {
- LOCK_HELD.Remove(path.FullName);
- }
+ LOCK_HELD.Remove(path.FullName);
}
}
}
- bool tmpBool;
- if (System.IO.File.Exists(path.FullName))
- {
- System.IO.File.Delete(path.FullName);
- tmpBool = true;
- }
- else if (System.IO.Directory.Exists(path.FullName))
- {
- System.IO.Directory.Delete(path.FullName);
- tmpBool = true;
- }
- else
- tmpBool = false;
- bool generatedAux = tmpBool;
}
- }
- catch (System.IO.IOException e)
- {
- // Not sure how to better message/handle this without
- // changing API?
- throw new System.SystemException("", e);
+ bool tmpBool;
+ if (System.IO.File.Exists(path.FullName))
+ {
+ System.IO.File.Delete(path.FullName);
+ tmpBool = true;
+ }
+ else if (System.IO.Directory.Exists(path.FullName))
+ {
+ System.IO.Directory.Delete(path.FullName);
+ tmpBool = true;
+ }
+ else
+ tmpBool = false;
+ if (!tmpBool)
+ throw new LockReleaseFailedException("failed to delete " + path);
}
}
}
public override bool IsLocked()
{
- return lock_Renamed;
+ lock (this)
+ {
+ return lock_Renamed;
+ }
}
public override System.String ToString()
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Package.html
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/Package.html?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Package.html (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/Package.html Tue Jun 24 19:50:12 2008
@@ -1,10 +1,10 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <meta name="Author" content="Doug Cutting">
-</head>
-<body>
-Binary i/o API, used for all index data.
-</body>
-</html>
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Doug Cutting">
+</head>
+<body>
+Binary i/o API, used for all index data.
+</body>
+</html>
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMDirectory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/RAMDirectory.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMDirectory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMDirectory.cs Tue Jun 24 19:50:12 2008
@@ -25,7 +25,7 @@
/// but can be changed with {@link #setLockFactory}.
///
/// </summary>
- /// <version> $Id: RAMDirectory.java 503911 2007-02-05 22:49:42Z dnaber $
+ /// <version> $Id: RAMDirectory.java 581625 2007-10-03 15:24:12Z mikemccand $
/// </version>
[Serializable]
public class RAMDirectory : Directory
@@ -89,7 +89,7 @@
/// <param name="dir">a <code>File</code> specifying the index directory
///
/// </param>
- /// <seealso cref="#RAMDirectory(Directory)">
+ /// <seealso cref="RAMDirectory(Directory)">
/// </seealso>
public RAMDirectory(System.IO.FileInfo dir):this(FSDirectory.GetDirectory(dir), true)
{
@@ -101,7 +101,7 @@
/// <param name="dir">a <code>String</code> specifying the full index directory path
///
/// </param>
- /// <seealso cref="#RAMDirectory(Directory)">
+ /// <seealso cref="RAMDirectory(Directory)">
/// </seealso>
public RAMDirectory(System.String dir) : this(FSDirectory.GetDirectory(dir), true)
{
@@ -112,6 +112,7 @@
{
lock (this)
{
+ EnsureOpen();
System.String[] result = new System.String[fileMap.Count];
int i = 0;
System.Collections.IEnumerator it = fileMap.Keys.GetEnumerator();
@@ -126,6 +127,7 @@
/// <summary>Returns true iff the named file exists in this directory. </summary>
public override bool FileExists(System.String name)
{
+ EnsureOpen();
RAMFile file;
lock (this)
{
@@ -138,6 +140,7 @@
/// <throws> IOException if the file does not exist </throws>
public override long FileModified(System.String name)
{
+ EnsureOpen();
RAMFile file;
lock (this)
{
@@ -152,6 +155,7 @@
/// <throws> IOException if the file does not exist </throws>
public override void TouchFile(System.String name)
{
+ EnsureOpen();
RAMFile file;
lock (this)
{
@@ -181,6 +185,7 @@
/// <throws> IOException if the file does not exist </throws>
public override long FileLength(System.String name)
{
+ EnsureOpen();
RAMFile file;
lock (this)
{
@@ -193,12 +198,13 @@
/// <summary>Return total size in bytes of all files in this
/// directory. This is currently quantized to
- /// BufferedIndexOutput.BUFFER_SIZE.
+ /// RAMOutputStream.BUFFER_SIZE.
/// </summary>
public long SizeInBytes()
{
lock (this)
{
+ EnsureOpen();
return sizeInBytes;
}
}
@@ -209,6 +215,7 @@
{
lock (this)
{
+ EnsureOpen();
RAMFile file = (RAMFile) fileMap[name];
if (file != null)
{
@@ -229,6 +236,7 @@
{
lock (this)
{
+ EnsureOpen();
RAMFile fromFile = (RAMFile) fileMap[from];
if (fromFile == null)
throw new System.IO.FileNotFoundException(from);
@@ -246,6 +254,7 @@
/// <summary>Creates a new, empty file in the directory with the given name. Returns a stream writing this file. </summary>
public override IndexOutput CreateOutput(System.String name)
{
+ EnsureOpen();
RAMFile file = new RAMFile(this);
lock (this)
{
@@ -263,6 +272,7 @@
/// <summary>Returns a stream reading an existing file. </summary>
public override IndexInput OpenInput(System.String name)
{
+ EnsureOpen();
RAMFile file;
lock (this)
{
@@ -278,5 +288,14 @@
{
fileMap = null;
}
+
+ /// <throws> AlreadyClosedException if this IndexReader is closed </throws>
+ protected internal void EnsureOpen()
+ {
+ if (fileMap == null)
+ {
+ throw new AlreadyClosedException("this RAMDirectory is closed");
+ }
+ }
}
}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMFile.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/RAMFile.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMFile.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMFile.cs Tue Jun 24 19:50:12 2008
@@ -26,8 +26,7 @@
private const long serialVersionUID = 1L;
- // Direct read-only access to state supported for streams since a writing stream implies no other concurrent streams
- internal System.Collections.ArrayList buffers = new System.Collections.ArrayList();
+ private System.Collections.ArrayList buffers = new System.Collections.ArrayList();
internal long length;
internal RAMDirectory directory;
internal long sizeInBytes; // Only maintained if in a directory; updates synchronized on directory
@@ -81,18 +80,49 @@
internal byte[] AddBuffer(int size)
{
- byte[] buffer = new byte[size];
- if (directory != null)
- lock (directory)
- {
- // Ensure addition of buffer and adjustment to directory size are atomic wrt directory
+ lock (this)
+ {
+ byte[] buffer = new byte[size];
+ if (directory != null)
+ lock (directory)
+ {
+ // Ensure addition of buffer and adjustment to directory size are atomic wrt directory
+ buffers.Add(buffer);
+ directory.sizeInBytes += size;
+ sizeInBytes += size;
+ }
+ else
buffers.Add(buffer);
- directory.sizeInBytes += size;
- sizeInBytes += size;
- }
- else
- buffers.Add(buffer);
- return buffer;
+ return buffer;
+ }
+ }
+
+ internal byte[] GetBuffer(int index)
+ {
+ lock (this)
+ {
+ return (byte[]) buffers[index];
+ }
+ }
+
+ internal int NumBuffers()
+ {
+ lock (this)
+ {
+ return buffers.Count;
+ }
+ }
+
+ /// <summary> Expert: allocate a new buffer.
+ /// Subclasses can allocate differently.
+ /// </summary>
+ /// <param name="size">size of allocated buffer.
+ /// </param>
+ /// <returns> allocated buffer.
+ /// </returns>
+ internal virtual byte[] NewBuffer(int size)
+ {
+ return new byte[size];
}
// Only valid if in a directory
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMInputStream.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/RAMInputStream.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMInputStream.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMInputStream.cs Tue Jun 24 19:50:12 2008
@@ -20,78 +20,122 @@
namespace Lucene.Net.Store
{
- /// <summary> Licensed to the Apache Software Foundation (ASF) under one or more
- /// contributor license agreements. See the NOTICE file distributed with
- /// this work for additional information regarding copyright ownership.
- /// The ASF licenses this file to You under the Apache License, Version 2.0
- /// (the "License"); you may not use this file except in compliance with
- /// the License. You may obtain a copy of the License at
- ///
- /// http://www.apache.org/licenses/LICENSE-2.0
- ///
- /// Unless required by applicable law or agreed to in writing, software
- /// distributed under the License is distributed on an "AS IS" BASIS,
- /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- /// See the License for the specific language governing permissions and
- /// limitations under the License.
- /// </summary>
-
/// <summary> A memory-resident {@link IndexInput} implementation.
///
/// </summary>
- /// <version> $Id: RAMInputStream.java 478014 2006-11-22 02:47:49Z yonik $
+ /// <version> $Id: RAMInputStream.java 598693 2007-11-27 17:01:21Z mikemccand $
/// </version>
- class RAMInputStream : BufferedIndexInput, System.ICloneable
+ public class RAMInputStream : IndexInput, System.ICloneable
{
+ internal static readonly int BUFFER_SIZE;
+
private RAMFile file;
- private long pointer = 0;
private long length;
- public RAMInputStream(RAMFile f)
+ private byte[] currentBuffer;
+ private int currentBufferIndex;
+
+ private int bufferPosition;
+ private long bufferStart;
+ private int bufferLength;
+
+ internal RAMInputStream(RAMFile f)
{
file = f;
length = file.length;
+ if (length / BUFFER_SIZE >= System.Int32.MaxValue)
+ {
+ throw new System.IO.IOException("Too large RAMFile! " + length);
+ }
+
+ // make sure that we switch to the
+ // first needed buffer lazily
+ currentBufferIndex = - 1;
+ currentBuffer = null;
+ }
+
+ public override void Close()
+ {
+ // nothing to do here
+ }
+
+ public override long Length()
+ {
+ return length;
}
- public override void ReadInternal(byte[] dest, int destOffset, int len)
+ public override byte ReadByte()
{
- int remainder = len;
- long start = pointer;
- while (remainder != 0)
- {
- int bufferNumber = (int) (start / BUFFER_SIZE);
- int bufferOffset = (int) (start % BUFFER_SIZE);
- int bytesInBuffer = BUFFER_SIZE - bufferOffset;
- int bytesToCopy = bytesInBuffer >= remainder ? remainder : bytesInBuffer;
- byte[] buffer = (byte[]) file.buffers[bufferNumber];
- Array.Copy(buffer, bufferOffset, dest, destOffset, bytesToCopy);
- destOffset += bytesToCopy;
- start += bytesToCopy;
- remainder -= bytesToCopy;
+ if (bufferPosition >= bufferLength)
+ {
+ currentBufferIndex++;
+ SwitchCurrentBuffer();
}
- pointer += len;
+ return currentBuffer[bufferPosition++];
}
- public override void Close()
+ public override void ReadBytes(byte[] b, int offset, int len)
{
+ while (len > 0)
+ {
+ if (bufferPosition >= bufferLength)
+ {
+ currentBufferIndex++;
+ SwitchCurrentBuffer();
+ }
+
+ int remainInBuffer = bufferLength - bufferPosition;
+ int bytesToCopy = len < remainInBuffer ? len : remainInBuffer;
+ Array.Copy(currentBuffer, bufferPosition, b, offset, bytesToCopy);
+ offset += bytesToCopy;
+ len -= bytesToCopy;
+ bufferPosition += bytesToCopy;
+ }
}
- public override void SeekInternal(long pos)
+ private void SwitchCurrentBuffer()
{
- pointer = pos;
+ if (currentBufferIndex >= file.NumBuffers())
+ {
+ // end of file reached, no more buffers left
+ throw new System.IO.IOException("Read past EOF");
+ }
+ else
+ {
+ currentBuffer = file.GetBuffer(currentBufferIndex);
+ bufferPosition = 0;
+ bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
+ long buflen = length - bufferStart;
+ bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE : (int) buflen;
+ }
}
- public override long Length()
+ public override long GetFilePointer()
{
- return length;
+ return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition;
}
-
- // {{Aroush-1.9}} Do we need this Clone()?!
- /* virtual public System.Object Clone()
+
+ public override void Seek(long pos)
{
- return null;
+ if (currentBuffer == null || pos < bufferStart || pos >= bufferStart + BUFFER_SIZE)
+ {
+ currentBufferIndex = (int) (pos / BUFFER_SIZE);
+ SwitchCurrentBuffer();
+ }
+ bufferPosition = (int) (pos % BUFFER_SIZE);
}
+
+ // {{Aroush-1.9}} Do we need this Clone()?!
+ /* override public System.Object Clone()
+ {
+ return null;
+ }
*/
+
+ static RAMInputStream()
+ {
+ BUFFER_SIZE = RAMOutputStream.BUFFER_SIZE;
+ }
}
}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMOutputStream.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/RAMOutputStream.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMOutputStream.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/RAMOutputStream.cs Tue Jun 24 19:50:12 2008
@@ -23,22 +23,35 @@
/// <summary> A memory-resident {@link IndexOutput} implementation.
///
/// </summary>
- /// <version> $Id: RAMOutputStream.java 488330 2006-12-18 16:45:29Z mikemccand $
+ /// <version> $Id: RAMOutputStream.java 598693 2007-11-27 17:01:21Z mikemccand $
/// </version>
- public class RAMOutputStream : BufferedIndexOutput
+ public class RAMOutputStream:IndexOutput
{
+ internal const int BUFFER_SIZE = 1024;
+
private RAMFile file;
- private long pointer = 0;
+
+ private byte[] currentBuffer;
+ private int currentBufferIndex;
+
+ private int bufferPosition;
+ private long bufferStart;
+ private int bufferLength;
/// <summary>Construct an empty output buffer. </summary>
- public RAMOutputStream() : this(new RAMFile())
+ public RAMOutputStream():this(new RAMFile())
{
}
public /*internal*/ RAMOutputStream(RAMFile f)
{
file = f;
+
+ // make sure that we switch to the
+ // first needed buffer lazily
+ currentBufferIndex = - 1;
+ currentBuffer = null;
}
/// <summary>Copy the current contents of this buffer to the named output. </summary>
@@ -57,7 +70,7 @@
// at the last buffer
length = (int) (end - pos);
}
- out_Renamed.WriteBytes((byte[]) file.buffers[buffer++], length);
+ out_Renamed.WriteBytes((byte[]) file.GetBuffer(buffer++), length);
pos = nextPos;
}
}
@@ -78,47 +91,92 @@
file.SetLength(0);
}
- public override void FlushBuffer(byte[] src, int len)
+ public override void Close()
{
- byte[] buffer;
- int bufferPos = 0;
- while (bufferPos != len)
- {
- int bufferNumber = (int) (pointer / BUFFER_SIZE);
- int bufferOffset = (int) (pointer % BUFFER_SIZE);
- int bytesInBuffer = BUFFER_SIZE - bufferOffset;
- int remainInSrcBuffer = len - bufferPos;
- int bytesToCopy = bytesInBuffer >= remainInSrcBuffer ? remainInSrcBuffer : bytesInBuffer;
-
- if (bufferNumber == file.buffers.Count)
- buffer = file.AddBuffer(BUFFER_SIZE);
- else
- buffer = (byte[]) file.buffers[bufferNumber];
-
- Array.Copy(src, bufferPos, buffer, bufferOffset, bytesToCopy);
- bufferPos += bytesToCopy;
- pointer += bytesToCopy;
+ Flush();
+ }
+
+ public override void Seek(long pos)
+ {
+ // set the file length in case we seek back
+ // and flush() has not been called yet
+ SetFileLength();
+ if (pos < bufferStart || pos >= bufferStart + bufferLength)
+ {
+ currentBufferIndex = (int) (pos / BUFFER_SIZE);
+ SwitchCurrentBuffer();
}
- if (pointer > file.length)
- file.SetLength(pointer);
-
- file.SetLastModified(System.DateTime.Now.Ticks);
+ bufferPosition = (int) (pos % BUFFER_SIZE);
}
- public override void Close()
+ public override long Length()
{
- base.Close();
+ return file.length;
}
- public override void Seek(long pos)
+ public override void WriteByte(byte b)
{
- base.Seek(pos);
- pointer = pos;
+ if (bufferPosition == bufferLength)
+ {
+ currentBufferIndex++;
+ SwitchCurrentBuffer();
+ }
+ currentBuffer[bufferPosition++] = b;
}
- public override long Length()
+
+ public override void WriteBytes(byte[] b, int offset, int len)
{
- return file.length;
+ while (len > 0)
+ {
+ if (bufferPosition == bufferLength)
+ {
+ currentBufferIndex++;
+ SwitchCurrentBuffer();
+ }
+
+ int remainInBuffer = currentBuffer.Length - bufferPosition;
+ int bytesToCopy = len < remainInBuffer ? len : remainInBuffer;
+ Array.Copy(b, offset, currentBuffer, bufferPosition, bytesToCopy);
+ offset += bytesToCopy;
+ len -= bytesToCopy;
+ bufferPosition += bytesToCopy;
+ }
+ }
+
+ private void SwitchCurrentBuffer()
+ {
+ if (currentBufferIndex == file.NumBuffers())
+ {
+ currentBuffer = file.AddBuffer(BUFFER_SIZE);
+ }
+ else
+ {
+ currentBuffer = (byte[]) file.GetBuffer(currentBufferIndex);
+ }
+ bufferPosition = 0;
+ bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
+ bufferLength = currentBuffer.Length;
+ }
+
+ private void SetFileLength()
+ {
+ long pointer = bufferStart + bufferPosition;
+ if (pointer > file.length)
+ {
+ file.SetLength(pointer);
+ }
+ }
+
+ public override void Flush()
+ {
+ file.SetLastModified((System.DateTime.Now.Ticks - 621355968000000000) / 10000);
+ SetFileLength();
+ }
+
+ public override long GetFilePointer()
+ {
+ return currentBufferIndex < 0?0:bufferStart + bufferPosition;
}
}
}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/SimpleFSLockFactory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/SimpleFSLockFactory.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/SimpleFSLockFactory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/SimpleFSLockFactory.cs Tue Jun 24 19:50:12 2008
@@ -20,11 +20,32 @@
namespace Lucene.Net.Store
{
- /// <summary> Implements {@link LockFactory} using {@link File#createNewFile()}. This is
- /// currently the default LockFactory used for {@link FSDirectory} if no
- /// LockFactory instance is otherwise provided.
+ /// <summary> <p>Implements {@link LockFactory} using {@link
+ /// File#createNewFile()}. This is the default LockFactory
+ /// for {@link FSDirectory}.</p>
///
- /// Note that there are known problems with this locking implementation on NFS.
+ /// <p><b>NOTE:</b> the <a target="_top"
+ /// href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#createNewFile()">javadocs
+ /// for <code>File.createNewFile</code></a> contain a vague
+ /// yet spooky warning about not using the API for file
+ /// locking. This warning was added due to <a target="_top"
+ /// href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4676183">this
+ /// bug</a>, and in fact the only known problem with using
+ /// this API for locking is that the Lucene write lock may
+ /// not be released when the JVM exits abnormally.</p>
+ /// <p>When this happens, a {@link LockObtainFailedException}
+ /// is hit when trying to create a writer, in which case you
+ /// need to explicitly clear the lock file first. You can
+ /// either manually remove the file, or use the {@link
+ /// Lucene.Net.Index.IndexReader#Unlock(Directory)}
+ /// API. But, first be certain that no writer is in fact
+ /// writing to the index otherwise you can easily corrupt
+ /// your index.</p>
+ ///
+ /// <p>If you suspect that this or any other LockFactory is
+ /// not working properly in your environment, you can easily
+ /// test it by using {@link VerifyingLockFactory}, {@link
+ /// LockVerifyServer} and {@link LockStressTest}.</p>
///
/// </summary>
/// <seealso cref="LockFactory">
@@ -40,12 +61,22 @@
private System.IO.FileInfo lockDir;
+ /// <summary> Create a SimpleFSLockFactory instance, with null (unset)
+ /// lock directory. This is package-private and is only
+ /// used by FSDirectory when creating this LockFactory via
+ /// the System property
+ /// Lucene.Net.Store.FSDirectoryLockFactoryClass.
+ /// </summary>
+ internal SimpleFSLockFactory() : this((System.IO.FileInfo) null)
+ {
+ }
+
/// <summary> Instantiate using the provided directory (as a File instance).</summary>
/// <param name="lockDir">where lock files should be created.
/// </param>
public SimpleFSLockFactory(System.IO.FileInfo lockDir)
{
- Init(lockDir);
+ SetLockDir(lockDir);
}
/// <summary> Instantiate using the provided directory name (String).</summary>
@@ -54,42 +85,15 @@
public SimpleFSLockFactory(System.String lockDirName)
{
lockDir = new System.IO.FileInfo(lockDirName);
- Init(lockDir);
+ SetLockDir(lockDir);
}
-
- /// <summary>
- /// </summary>
- internal SimpleFSLockFactory()
- {
- lockDir = null;
- }
-
- /// <summary>
- /// Set the lock directory. This is package-private and is
- /// only used externally by FSDirectory when creating this
- /// LockFactory via the System property
- /// org.apache.lucene.store.FSDirectoryLockFactoryClass.
- /// </summary>
- /// <param name="lockDir"></param>
- internal void SetLockDir(System.IO.FileInfo lockDir)
- {
- this.lockDir = lockDir;
- if (lockDir != null)
- {
- // Ensure that lockDir exists and is a directory.
- if (!lockDir.Exists)
- {
- if (System.IO.Directory.CreateDirectory(lockDir.FullName) == null)
- throw new System.IO.IOException("Cannot create directory: " + lockDir.FullName);
- }
- else if (!new System.IO.DirectoryInfo(lockDir.FullName).Exists)
- {
- throw new System.IO.IOException("Found regular file where directory expected: " + lockDir.FullName);
- }
- }
- }
- protected internal virtual void Init(System.IO.FileInfo lockDir)
+ /// <summary> Set the lock directory. This is package-private and is
+ /// only used externally by FSDirectory when creating this
+ /// LockFactory via the System property
+ /// Lucene.Net.Store.FSDirectoryLockFactoryClass.
+ /// </summary>
+ internal virtual void SetLockDir(System.IO.FileInfo lockDir)
{
this.lockDir = lockDir;
}
@@ -203,18 +207,24 @@
{
bool tmpBool;
if (System.IO.File.Exists(lockFile.FullName))
+ tmpBool = true;
+ else
+ tmpBool = System.IO.Directory.Exists(lockFile.FullName);
+ bool tmpBool2;
+ if (System.IO.File.Exists(lockFile.FullName))
{
System.IO.File.Delete(lockFile.FullName);
- tmpBool = true;
+ tmpBool2 = true;
}
else if (System.IO.Directory.Exists(lockFile.FullName))
{
System.IO.Directory.Delete(lockFile.FullName);
- tmpBool = true;
+ tmpBool2 = true;
}
else
- tmpBool = false;
- bool generatedAux = tmpBool;
+ tmpBool2 = false;
+ if (tmpBool && !tmpBool2)
+ throw new LockReleaseFailedException("failed to delete " + lockFile);
}
public override bool IsLocked()
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/SingleInstanceLockFactory.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Store/SingleInstanceLockFactory.cs?rev=671401&r1=671400&r2=671401&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/SingleInstanceLockFactory.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Store/SingleInstanceLockFactory.cs Tue Jun 24 19:50:12 2008
@@ -31,7 +31,7 @@
/// <seealso cref="LockFactory">
/// </seealso>
- public class SingleInstanceLockFactory:LockFactory
+ public class SingleInstanceLockFactory : LockFactory
{
private System.Collections.Hashtable locks = new System.Collections.Hashtable();
@@ -57,7 +57,7 @@
}
- class SingleInstanceLock:Lock
+ class SingleInstanceLock : Lock
{
internal System.String lockName;