lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From synhers...@apache.org
Subject [01/50] [abbrv] lucenenet git commit: Added missing Core.Util.OfflineSorter members (+ tests) required by Hunspell.
Date Tue, 23 Aug 2016 23:17:54 GMT
Repository: lucenenet
Updated Branches:
  refs/heads/analysis-work 76c4a537d -> 4deebe8fe


Added missing Core.Util.OfflineSorter members (+ tests) required by Hunspell.


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/572ad694
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/572ad694
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/572ad694

Branch: refs/heads/analysis-work
Commit: 572ad694199d3c7a4832ae12abcbd11d6c960e7d
Parents: 294f1c2
Author: Shad Storhaug <shad@shadstorhaug.com>
Authored: Thu Aug 18 17:20:57 2016 +0700
Committer: Shad Storhaug <shad@shadstorhaug.com>
Committed: Sat Aug 20 11:33:56 2016 +0700

----------------------------------------------------------------------
 src/Lucene.Net.Core/Lucene.Net.csproj           |    1 +
 .../Compatibility/BinaryReaderDataInput.cs      |   34 +
 src/Lucene.Net.Core/Util/OfflineSorter.cs       | 1161 +++++++++---------
 src/Lucene.Net.Tests/Lucene.Net.Tests.csproj    |    1 +
 .../core/Util/TestOfflineSorter.cs              |  143 ++-
 5 files changed, 698 insertions(+), 642 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/572ad694/src/Lucene.Net.Core/Lucene.Net.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Lucene.Net.csproj b/src/Lucene.Net.Core/Lucene.Net.csproj
index 8d33617..26c8906 100644
--- a/src/Lucene.Net.Core/Lucene.Net.csproj
+++ b/src/Lucene.Net.Core/Lucene.Net.csproj
@@ -618,6 +618,7 @@
     <Compile Include="Support\Character.cs" />
     <Compile Include="Support\Arrays.cs" />
     <Compile Include="Support\CharacterIterator.cs" />
+    <Compile Include="Support\Compatibility\BinaryReaderDataInput.cs" />
     <Compile Include="Support\Compatibility\BinaryWriterDataOutput.cs" />
     <Compile Include="Support\Compatibility\Collections.cs" />
     <Compile Include="Support\ConcurrentHashMapWrapper.cs" />

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/572ad694/src/Lucene.Net.Core/Support/Compatibility/BinaryReaderDataInput.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Support/Compatibility/BinaryReaderDataInput.cs b/src/Lucene.Net.Core/Support/Compatibility/BinaryReaderDataInput.cs
new file mode 100644
index 0000000..d355df0
--- /dev/null
+++ b/src/Lucene.Net.Core/Support/Compatibility/BinaryReaderDataInput.cs
@@ -0,0 +1,34 @@
+´╗┐using Lucene.Net.Store;
+using System;
+using System.IO;
+
+namespace Lucene.Net.Support.Compatibility
+{
+    public class BinaryReaderDataInput : DataInput, IDisposable
+    {
+        private readonly BinaryReader br;
+        public BinaryReaderDataInput(BinaryReader br)
+        {
+            this.br = br;
+        }
+       
+        public override byte ReadByte()
+        {
+            return br.ReadByte();
+        }
+
+        public override void ReadBytes(byte[] b, int offset, int len)
+        {
+            byte[] temp = br.ReadBytes(len);
+            for (int i = offset; i < (offset + len) && i < temp.Length; i++)
+            {
+                b[i] = temp[i];
+            }
+        }
+
+        public void Dispose()
+        {
+            br.Dispose();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/572ad694/src/Lucene.Net.Core/Util/OfflineSorter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/OfflineSorter.cs b/src/Lucene.Net.Core/Util/OfflineSorter.cs
index db0a86b..4f3084b 100644
--- a/src/Lucene.Net.Core/Util/OfflineSorter.cs
+++ b/src/Lucene.Net.Core/Util/OfflineSorter.cs
@@ -34,487 +34,488 @@ namespace Lucene.Net.Util
     /// </summary>
     public sealed class OfflineSorter
     {
-        // LUCENENET TODO: keep this code as it will be used by subprojects once ported
-        //        private bool InstanceFieldsInitialized = false;
-        //
-        //        private void InitializeInstanceFields()
-        //        {
-        //            Buffer = new BytesRefArray(BufferBytesUsed);
-        //        }
-        //
-        //        /// <summary>
-        //        /// Convenience constant for megabytes </summary>
-        //        public const long MB = 1024 * 1024;
-        //        /// <summary>
-        //        /// Convenience constant for gigabytes </summary>
-        //        public static readonly long GB = MB * 1024;
-        //
-        //        /// <summary>
-        //        /// Minimum recommended buffer size for sorting.
-        //        /// </summary>
-        //        public const long MIN_BUFFER_SIZE_MB = 32;
-        //
-        //        /// <summary>
-        //        /// Absolute minimum required buffer size for sorting.
-        //        /// </summary>
-        //        public static readonly long ABSOLUTE_MIN_SORT_BUFFER_SIZE = MB / 2;
-        //        private const string MIN_BUFFER_SIZE_MSG = "At least 0.5MB RAM buffer is needed";
-        //
-        //        /// <summary>
-        //        /// Maximum number of temporary files before doing an intermediate merge.
-        //        /// </summary>
-        //        public const int MAX_TEMPFILES = 128;
-        //
-        //        /// <summary>
-        //        /// A bit more descriptive unit for constructors.
-        //        /// </summary>
-        //        /// <seealso cref= #automatic() </seealso>
-        //        /// <seealso cref= #megabytes(long) </seealso>
-        //        public sealed class BufferSize
-        //        {
-        //            internal readonly int Bytes;
-        //
-        //            internal BufferSize(long bytes)
-        //            {
-        //                if (bytes > int.MaxValue)
-        //                {
-        //                    throw new System.ArgumentException("Buffer too large for Java (" + (int.MaxValue / MB) + "mb max): " + bytes);
-        //                }
-        //
-        //                if (bytes < ABSOLUTE_MIN_SORT_BUFFER_SIZE)
-        //                {
-        //                    throw new System.ArgumentException(MIN_BUFFER_SIZE_MSG + ": " + bytes);
-        //                }
-        //
-        //                this.Bytes = (int)bytes;
-        //            }
-        //
-        //            /// <summary>
-        //            /// Creates a <seealso cref="BufferSize"/> in MB. The given
-        //            /// values must be &gt; 0 and &lt; 2048.
-        //            /// </summary>
-        //            public static BufferSize Megabytes(long mb)
-        //            {
-        //                return new BufferSize(mb * MB);
-        //            }
-        //
-        //            /// <summary>
-        //            /// Approximately half of the currently available free heap, but no less
-        //            /// than <seealso cref="#ABSOLUTE_MIN_SORT_BUFFER_SIZE"/>. However if current heap allocation
-        //            /// is insufficient or if there is a large portion of unallocated heap-space available
-        //            /// for sorting consult with max allowed heap size.
-        //            /// </summary>
-        //            public static BufferSize Automatic()
-        //            {
-        //                var proc = Process.GetCurrentProcess();
-        //
-        //                // take sizes in "conservative" order
-        //                long max = proc.PeakVirtualMemorySize64; // max allocated; java has it as Runtime.maxMemory();
-        //                long total = proc.VirtualMemorySize64; // currently allocated; java has it as Runtime.totalMemory();
-        //                long free = rt.freeMemory(); // unused portion of currently allocated
-        //                long totalAvailableBytes = max - total + free;
-        //
-        //                // by free mem (attempting to not grow the heap for this)
-        //                long sortBufferByteSize = free / 2;
-        //                const long minBufferSizeBytes = MIN_BUFFER_SIZE_MB * MB;
-        //                if (sortBufferByteSize < minBufferSizeBytes || totalAvailableBytes > 10 * minBufferSizeBytes) // lets see if we need/should to grow the heap
-        //                {
-        //                    if (totalAvailableBytes / 2 > minBufferSizeBytes) // there is enough mem for a reasonable buffer
-        //                    {
-        //                        sortBufferByteSize = totalAvailableBytes / 2; // grow the heap
-        //                    }
-        //                    else
-        //                    {
-        //                        //heap seems smallish lets be conservative fall back to the free/2
-        //                        sortBufferByteSize = Math.Max(ABSOLUTE_MIN_SORT_BUFFER_SIZE, sortBufferByteSize);
-        //                    }
-        //                }
-        //                return new BufferSize(Math.Min((long)int.MaxValue, sortBufferByteSize));
-        //            }
-        //        }
-        //
-        //        /// <summary>
-        //        /// Sort info (debugging mostly).
-        //        /// </summary>
-        //        public class SortInfo
-        //        {
-        //            internal bool InstanceFieldsInitialized = false;
-        //
-        //            internal virtual void InitializeInstanceFields()
-        //            {
-        //                BufferSize = OuterInstance.RamBufferSize.Bytes;
-        //            }
-        //
-        //            private readonly OfflineSorter OuterInstance;
-        //
-        //            /// <summary>
-        //            /// number of temporary files created when merging partitions </summary>
-        //            public int TempMergeFiles;
-        //            /// <summary>
-        //            /// number of partition merges </summary>
-        //            public int MergeRounds;
-        //            /// <summary>
-        //            /// number of lines of data read </summary>
-        //            public int Lines;
-        //            /// <summary>
-        //            /// time spent merging sorted partitions (in milliseconds) </summary>
-        //            public long MergeTime;
-        //            /// <summary>
-        //            /// time spent sorting data (in milliseconds) </summary>
-        //            public long SortTime;
-        //            /// <summary>
-        //            /// total time spent (in milliseconds) </summary>
-        //            public long TotalTime;
-        //            /// <summary>
-        //            /// time spent in i/o read (in milliseconds) </summary>
-        //            public long ReadTime;
-        //            /// <summary>
-        //            /// read buffer size (in bytes) </summary>
-        //            public long BufferSize;
-        //
-        //            /// <summary>
-        //            /// create a new SortInfo (with empty statistics) for debugging </summary>
-        //            public SortInfo(OfflineSorter outerInstance)
-        //            {
-        //                this.OuterInstance = outerInstance;
-        //
-        //                if (!InstanceFieldsInitialized)
-        //                {
-        //                    InitializeInstanceFields();
-        //                    InstanceFieldsInitialized = true;
-        //                }
-        //            }
-        //
-        //            public override string ToString()
-        //            {
-        //                return string.Format("time=%.2f sec. total (%.2f reading, %.2f sorting, %.2f merging), lines=%d, temp files=%d, merges=%d, soft ram limit=%.2f MB", TotalTime / 1000.0d, ReadTime / 1000.0d, SortTime / 1000.0d, MergeTime / 1000.0d, Lines, TempMergeFiles, MergeRounds, (double)BufferSize / MB);
-        //            }
-        //        }
-        //
-        //        private readonly BufferSize RamBufferSize;
-        //
-        //        private readonly Counter BufferBytesUsed = Counter.NewCounter();
-        //        private BytesRefArray Buffer;
-        //        private SortInfo sortInfo;
-        //        private readonly int MaxTempFiles;
-        //        private readonly IComparer<BytesRef> comparator;
-        //
-        //        /// <summary>
-        //        /// Default comparator: sorts in binary (codepoint) order </summary>
-        //        public static readonly IComparer<BytesRef> DEFAULT_COMPARATOR = BytesRef.UTF8SortedAsUnicodeComparator.Instance;
-        //
-        //        /// <summary>
-        //        /// Defaults constructor.
-        //        /// </summary>
-        //        /// <seealso cref= #defaultTempDir() </seealso>
-        //        /// <seealso cref= BufferSize#automatic() </seealso>
-        //        public OfflineSorter()
-        //            : this(DEFAULT_COMPARATOR, BufferSize.Automatic(), DefaultTempDir(), MAX_TEMPFILES)
-        //        {
-        //            if (!InstanceFieldsInitialized)
-        //            {
-        //                InitializeInstanceFields();
-        //                InstanceFieldsInitialized = true;
-        //            }
-        //        }
-        //
-        //        /// <summary>
-        //        /// Defaults constructor with a custom comparator.
-        //        /// </summary>
-        //        /// <seealso cref= #defaultTempDir() </seealso>
-        //        /// <seealso cref= BufferSize#automatic() </seealso>
-        //        public OfflineSorter(IComparer<BytesRef> comparator)
-        //            : this(comparator, BufferSize.Automatic(), DefaultTempDir(), MAX_TEMPFILES)
-        //        {
-        //            if (!InstanceFieldsInitialized)
-        //            {
-        //                InitializeInstanceFields();
-        //                InstanceFieldsInitialized = true;
-        //            }
-        //        }
-        //
-        //        /// <summary>
-        //        /// All-details constructor.
-        //        /// </summary>
-        //        public OfflineSorter(IComparer<BytesRef> comparator, BufferSize ramBufferSize, /*DirectoryInfo tempDirectory,*/ int maxTempfiles)
-        //        {
-        //            if (!InstanceFieldsInitialized)
-        //            {
-        //                InitializeInstanceFields();
-        //                InstanceFieldsInitialized = true;
-        //            }
-        //            if (ramBufferSize.Bytes < ABSOLUTE_MIN_SORT_BUFFER_SIZE)
-        //            {
-        //                throw new System.ArgumentException(MIN_BUFFER_SIZE_MSG + ": " + ramBufferSize.Bytes);
-        //            }
-        //
-        //            if (maxTempfiles < 2)
-        //            {
-        //                throw new System.ArgumentException("maxTempFiles must be >= 2");
-        //            }
-        //
-        //            this.RamBufferSize = ramBufferSize;
-        //            this.MaxTempFiles = maxTempfiles;
-        //            this.comparator = comparator;
-        //        }
-        //
-        //        /// <summary>
-        //        /// Sort input to output, explicit hint for the buffer size. The amount of allocated
-        //        /// memory may deviate from the hint (may be smaller or larger).
-        //        /// </summary>
-        //        public SortInfo Sort(FileInfo input, FileInfo output)
-        //        {
-        //            sortInfo = new SortInfo(this) {TotalTime = DateTime.Now.Millisecond};
-        //
-        //            output.Delete();
-        //
-        //            var merges = new List<FileInfo>();
-        //            bool success2 = false;
-        //            try
-        //            {
-        //                var inputStream = new ByteSequencesReader(input);
-        //                bool success = false;
-        //                try
-        //                {
-        //                    int lines = 0;
-        //                    while ((lines = ReadPartition(inputStream)) > 0)
-        //                    {
-        //                        merges.Add(SortPartition(lines));
-        //                        sortInfo.TempMergeFiles++;
-        //                        sortInfo.Lines += lines;
-        //
-        //                        // Handle intermediate merges.
-        //                        if (merges.Count == MaxTempFiles)
-        //                        {
-        //                            var intermediate = new FileInfo(Path.GetTempFileName());
-        //                            try
-        //                            {
-        //                                MergePartitions(merges, intermediate);
-        //                            }
-        //                            finally
-        //                            {
-        //                                foreach (var file in merges)
-        //                                {
-        //                                    file.Delete();
-        //                                }
-        //                                merges.Clear();
-        //                                merges.Add(intermediate);
-        //                            }
-        //                            sortInfo.TempMergeFiles++;
-        //                        }
-        //                    }
-        //                    success = true;
-        //                }
-        //                finally
-        //                {
-        //                    if (success)
-        //                    {
-        //                        IOUtils.Close(inputStream);
-        //                    }
-        //                    else
-        //                    {
-        //                        IOUtils.CloseWhileHandlingException(inputStream);
-        //                    }
-        //                }
-        //
-        //                // One partition, try to rename or copy if unsuccessful.
-        //                if (merges.Count == 1)
-        //                {
-        //                    FileInfo single = merges[0];
-        //                    Copy(single, output);
-        //                    try
-        //                    {
-        //                        File.Delete(single.FullName);
-        //                    }
-        //                    catch (Exception)
-        //                    {
-        //                        // ignored
-        //                    }
-        //                }
-        //                else
-        //                {
-        //                    // otherwise merge the partitions with a priority queue.
-        //                    MergePartitions(merges, output);
-        //                }
-        //                success2 = true;
-        //            }
-        //            finally
-        //            {
-        //                foreach (FileInfo file in merges)
-        //                {
-        //                    file.Delete();
-        //                }
-        //                if (!success2)
-        //                {
-        //                    output.Delete();
-        //                }
-        //            }
-        //
-        //            sortInfo.TotalTime = (DateTime.Now.Millisecond - sortInfo.TotalTime);
-        //            return sortInfo;
-        //        }
-        //
-        //        /// <summary>
-        //        /// Returns the default temporary directory. By default, the System's temp folder. If not accessible
-        //        /// or not available, an IOException is thrown
-        //        /// </summary>
-        //        public static DirectoryInfo DefaultTempDir()
-        //        {
-        //            return new DirectoryInfo(Path.GetTempPath());
-        //        }
-        //
-        //        /// <summary>
-        //        /// Copies one file to another.
-        //        /// </summary>
-        //        private static void Copy(FileInfo file, FileInfo output)
-        //        {
-        //            File.Copy(file.FullName, output.FullName);
-        //        }
-        //
-        //        /// <summary>
-        //        /// Sort a single partition in-memory. </summary>
-        //        internal FileInfo SortPartition(int len)
-        //        {
-        //            var data = this.Buffer;
-        //            var tempFile = new FileInfo(Path.GetTempFileName());
-        //            //var tempFile1 = File.Create(new ());
-        //            //FileInfo tempFile = FileInfo.createTempFile("sort", "partition", TempDirectory);
-        //
-        //            long start = DateTime.Now.Millisecond;
-        //            sortInfo.SortTime += (DateTime.Now.Millisecond - start);
-        //
-        //            var @out = new ByteSequencesWriter(tempFile);
-        //            BytesRef spare;
-        //            try
-        //            {
-        //                BytesRefIterator iter = Buffer.Iterator(comparator);
-        //                while ((spare = iter.Next()) != null)
-        //                {
-        //                    Debug.Assert(spare.Length <= short.MaxValue);
-        //                    @out.Write(spare);
-        //                }
-        //
-        //                @out.Dispose();
-        //
-        //                // Clean up the buffer for the next partition.
-        //                data.Clear();
-        //                return tempFile;
-        //            }
-        //            finally
-        //            {
-        //                IOUtils.Close(@out);
-        //            }
-        //        }
-        //
-        //        /// <summary>
-        //        /// Merge a list of sorted temporary files (partitions) into an output file </summary>
-        //        internal void MergePartitions(IList<FileInfo> merges, FileInfo outputFile)
-        //        {
-        //            long start = DateTime.Now.Millisecond;
-        //
-        //            var @out = new ByteSequencesWriter(outputFile);
-        //
-        //            PriorityQueue<FileAndTop> queue = new PriorityQueueAnonymousInnerClassHelper(this, merges.Count);
-        //
-        //            var streams = new ByteSequencesReader[merges.Count];
-        //            try
-        //            {
-        //                // Open streams and read the top for each file
-        //                for (int i = 0; i < merges.Count; i++)
-        //                {
-        //                    streams[i] = new ByteSequencesReader(merges[i]);
-        //                    sbyte[] line = streams[i].Read();
-        //                    if (line != null)
-        //                    {
-        //                        queue.InsertWithOverflow(new FileAndTop(i, line));
-        //                    }
-        //                }
-        //
-        //                // Unix utility sort() uses ordered array of files to pick the next line from, updating
-        //                // it as it reads new lines. The PQ used here is a more elegant solution and has
-        //                // a nicer theoretical complexity bound :) The entire sorting process is I/O bound anyway
-        //                // so it shouldn't make much of a difference (didn't check).
-        //                FileAndTop top;
-        //                while ((top = queue.Top()) != null)
-        //                {
-        //                    @out.Write(top.Current);
-        //                    if (!streams[top.Fd].Read(top.Current))
-        //                    {
-        //                        queue.Pop();
-        //                    }
-        //                    else
-        //                    {
-        //                        queue.UpdateTop();
-        //                    }
-        //                }
-        //
-        //                SortInfo.MergeTime += DateTime.UtcNow.Ticks - start;
-        //                SortInfo.MergeRounds++;
-        //            }
-        //            finally
-        //            {
-        //                // The logic below is: if an exception occurs in closing out, it has a priority over exceptions
-        //                // happening in closing streams.
-        //                try
-        //                {
-        //                    IOUtils.Close(streams);
-        //                }
-        //                finally
-        //                {
-        //                    IOUtils.Close(@out);
-        //                }
-        //            }
-        //        }
-        //
-        //        private class PriorityQueueAnonymousInnerClassHelper : PriorityQueue<FileAndTop>
-        //        {
-        //            private readonly OfflineSorter OuterInstance;
-        //
-        //            public PriorityQueueAnonymousInnerClassHelper(OfflineSorter outerInstance, int size)
-        //                : base(size)
-        //            {
-        //                this.OuterInstance = outerInstance;
-        //            }
-        //
-        //            public override bool LessThan(FileAndTop a, FileAndTop b)
-        //            {
-        //                return OuterInstance.comparator.Compare(a.Current, b.Current) < 0;
-        //            }
-        //        }
-        //
-        //        /// <summary>
-        //        /// Read in a single partition of data </summary>
-        //        internal int ReadPartition(ByteSequencesReader reader)
-        //        {
-        //            long start = DateTime.Now.Millisecond;
-        //            var scratch = new BytesRef();
-        //            while ((scratch.Bytes = reader.Read()) != null)
-        //            {
-        //                scratch.Length = scratch.Bytes.Length;
-        //                Buffer.Append(scratch);
-        //                // Account for the created objects.
-        //                // (buffer slots do not account to buffer size.)
-        //                if (RamBufferSize.Bytes < BufferBytesUsed.Get())
-        //                {
-        //                    break;
-        //                }
-        //            }
-        //            sortInfo.ReadTime += (DateTime.Now.Millisecond - start);
-        //            return Buffer.Size();
-        //        }
-        //
-        //        internal class FileAndTop
-        //        {
-        //            internal readonly int Fd;
-        //            internal readonly BytesRef Current;
-        //
-        //            internal FileAndTop(int fd, sbyte[] firstLine)
-        //            {
-        //                this.Fd = fd;
-        //                this.Current = new BytesRef(firstLine);
-        //            }
-        //        }
-        //
+        private bool InstanceFieldsInitialized = false;
+
+        private void InitializeInstanceFields()
+        {
+            Buffer = new BytesRefArray(BufferBytesUsed);
+        }
+
+        /// <summary>
+        /// Convenience constant for megabytes </summary>
+        public const long MB = 1024 * 1024;
+        /// <summary>
+        /// Convenience constant for gigabytes </summary>
+        public static readonly long GB = MB * 1024;
+
+        /// <summary>
+        /// Minimum recommended buffer size for sorting.
+        /// </summary>
+        public const long MIN_BUFFER_SIZE_MB = 32;
+
+        /// <summary>
+        /// Absolute minimum required buffer size for sorting.
+        /// </summary>
+        public static readonly long ABSOLUTE_MIN_SORT_BUFFER_SIZE = MB / 2;
+        private const string MIN_BUFFER_SIZE_MSG = "At least 0.5MB RAM buffer is needed";
+
+        /// <summary>
+        /// Maximum number of temporary files before doing an intermediate merge.
+        /// </summary>
+        public const int MAX_TEMPFILES = 128;
+
+        /// <summary>
+        /// A bit more descriptive unit for constructors.
+        /// </summary>
+        /// <seealso cref= #automatic() </seealso>
+        /// <seealso cref= #megabytes(long) </seealso>
+        public sealed class BufferSize
+        {
+            internal readonly int Bytes;
+
+            internal BufferSize(long bytes)
+            {
+                if (bytes > int.MaxValue)
+                {
+                    throw new System.ArgumentException("Buffer too large for Java (" + (int.MaxValue / MB) + "mb max): " + bytes);
+                }
+
+                if (bytes < ABSOLUTE_MIN_SORT_BUFFER_SIZE)
+                {
+                    throw new System.ArgumentException(MIN_BUFFER_SIZE_MSG + ": " + bytes);
+                }
+
+                this.Bytes = (int)bytes;
+            }
+
+            /// <summary>
+            /// Creates a <seealso cref="BufferSize"/> in MB. The given
+            /// values must be &gt; 0 and &lt; 2048.
+            /// </summary>
+            public static BufferSize Megabytes(long mb)
+            {
+                return new BufferSize(mb * MB);
+            }
+
+            /// <summary>
+            /// Approximately half of the currently available free heap, but no less
+            /// than <seealso cref="#ABSOLUTE_MIN_SORT_BUFFER_SIZE"/>. However if current heap allocation
+            /// is insufficient or if there is a large portion of unallocated heap-space available
+            /// for sorting consult with max allowed heap size.
+            /// </summary>
+            public static BufferSize Automatic()
+            {
+                long max, total, free;
+                using (var proc = Process.GetCurrentProcess())
+                {
+                    // take sizes in "conservative" order
+                    max = proc.PeakVirtualMemorySize64; // max allocated; java has it as Runtime.maxMemory();
+                    total = proc.VirtualMemorySize64; // currently allocated; java has it as Runtime.totalMemory();
+                    free = proc.PrivateMemorySize64; // unused portion of currently allocated; java has it as Runtime.freeMemory();
+                }
+                long totalAvailableBytes = max - total + free;
+
+                // by free mem (attempting to not grow the heap for this)
+                long sortBufferByteSize = free / 2;
+                const long minBufferSizeBytes = MIN_BUFFER_SIZE_MB * MB;
+                if (sortBufferByteSize < minBufferSizeBytes || totalAvailableBytes > 10 * minBufferSizeBytes) // lets see if we need/should to grow the heap
+                {
+                    if (totalAvailableBytes / 2 > minBufferSizeBytes) // there is enough mem for a reasonable buffer
+                    {
+                        sortBufferByteSize = totalAvailableBytes / 2; // grow the heap
+                    }
+                    else
+                    {
+                        //heap seems smallish lets be conservative fall back to the free/2
+                        sortBufferByteSize = Math.Max(ABSOLUTE_MIN_SORT_BUFFER_SIZE, sortBufferByteSize);
+                    }
+                }
+                return new BufferSize(Math.Min((long)int.MaxValue, sortBufferByteSize));
+            }
+        }
+
+        /// <summary>
+        /// Sort info (debugging mostly).
+        /// </summary>
+        public class SortInfo
+        {
+            internal bool InstanceFieldsInitialized = false;
+
+            internal virtual void InitializeInstanceFields()
+            {
+                BufferSize = OuterInstance.RamBufferSize.Bytes;
+            }
+
+            private readonly OfflineSorter OuterInstance;
+
+            /// <summary>
+            /// number of temporary files created when merging partitions </summary>
+            public int TempMergeFiles;
+            /// <summary>
+            /// number of partition merges </summary>
+            public int MergeRounds;
+            /// <summary>
+            /// number of lines of data read </summary>
+            public int Lines;
+            /// <summary>
+            /// time spent merging sorted partitions (in milliseconds) </summary>
+            public long MergeTime;
+            /// <summary>
+            /// time spent sorting data (in milliseconds) </summary>
+            public long SortTime;
+            /// <summary>
+            /// total time spent (in milliseconds) </summary>
+            public long TotalTime;
+            /// <summary>
+            /// time spent in i/o read (in milliseconds) </summary>
+            public long ReadTime;
+            /// <summary>
+            /// read buffer size (in bytes) </summary>
+            public long BufferSize;
+
+            /// <summary>
+            /// create a new SortInfo (with empty statistics) for debugging </summary>
+            public SortInfo(OfflineSorter outerInstance)
+            {
+                this.OuterInstance = outerInstance;
+
+                if (!InstanceFieldsInitialized)
+                {
+                    InitializeInstanceFields();
+                    InstanceFieldsInitialized = true;
+                }
+            }
+
+            public override string ToString()
+            {
+                return string.Format("time=%.2f sec. total (%.2f reading, %.2f sorting, %.2f merging), lines=%d, temp files=%d, merges=%d, soft ram limit=%.2f MB", TotalTime / 1000.0d, ReadTime / 1000.0d, SortTime / 1000.0d, MergeTime / 1000.0d, Lines, TempMergeFiles, MergeRounds, (double)BufferSize / MB);
+            }
+        }
+
+        private readonly BufferSize RamBufferSize;
+
+        private readonly Counter BufferBytesUsed = Counter.NewCounter();
+        private BytesRefArray Buffer;
+        private SortInfo sortInfo;
+        private readonly int MaxTempFiles;
+        private readonly IComparer<BytesRef> comparator;
+
+        /// <summary>
+        /// Default comparator: sorts in binary (codepoint) order </summary>
+        public static readonly IComparer<BytesRef> DEFAULT_COMPARATOR = BytesRef.UTF8SortedAsUnicodeComparator.Instance;
+
+        /// <summary>
+        /// Defaults constructor.
+        /// </summary>
+        /// <seealso cref= #defaultTempDir() </seealso>
+        /// <seealso cref= BufferSize#automatic() </seealso>
+        public OfflineSorter()
+            : this(DEFAULT_COMPARATOR, BufferSize.Automatic(), DefaultTempDir(), MAX_TEMPFILES)
+        {
+            if (!InstanceFieldsInitialized)
+            {
+                InitializeInstanceFields();
+                InstanceFieldsInitialized = true;
+            }
+        }
+
+        /// <summary>
+        /// Defaults constructor with a custom comparator.
+        /// </summary>
+        /// <seealso cref= #defaultTempDir() </seealso>
+        /// <seealso cref= BufferSize#automatic() </seealso>
+        public OfflineSorter(IComparer<BytesRef> comparator)
+            : this(comparator, BufferSize.Automatic(), DefaultTempDir(), MAX_TEMPFILES)
+        {
+            if (!InstanceFieldsInitialized)
+            {
+                InitializeInstanceFields();
+                InstanceFieldsInitialized = true;
+            }
+        }
+
+        /// <summary>
+        /// All-details constructor.
+        /// </summary>
+        public OfflineSorter(IComparer<BytesRef> comparator, BufferSize ramBufferSize, DirectoryInfo tempDirectory, int maxTempfiles)
+        {
+            if (!InstanceFieldsInitialized)
+            {
+                InitializeInstanceFields();
+                InstanceFieldsInitialized = true;
+            }
+            if (ramBufferSize.Bytes < ABSOLUTE_MIN_SORT_BUFFER_SIZE)
+            {
+                throw new System.ArgumentException(MIN_BUFFER_SIZE_MSG + ": " + ramBufferSize.Bytes);
+            }
+
+            if (maxTempfiles < 2)
+            {
+                throw new System.ArgumentException("maxTempFiles must be >= 2");
+            }
+
+            this.RamBufferSize = ramBufferSize;
+            this.MaxTempFiles = maxTempfiles;
+            this.comparator = comparator;
+        }
+
+        /// <summary>
+        /// Sort input to output, explicit hint for the buffer size. The amount of allocated
+        /// memory may deviate from the hint (may be smaller or larger).
+        /// </summary>
+        public SortInfo Sort(FileInfo input, FileInfo output)
+        {
+            sortInfo = new SortInfo(this) { TotalTime = DateTime.Now.Millisecond };
+
+            output.Delete();
+
+            var merges = new List<FileInfo>();
+            bool success2 = false;
+            try
+            {
+                var inputStream = new ByteSequencesReader(input);
+                bool success = false;
+                try
+                {
+                    int lines = 0;
+                    while ((lines = ReadPartition(inputStream)) > 0)
+                    {
+                        merges.Add(SortPartition(lines));
+                        sortInfo.TempMergeFiles++;
+                        sortInfo.Lines += lines;
+
+                        // Handle intermediate merges.
+                        if (merges.Count == MaxTempFiles)
+                        {
+                            var intermediate = new FileInfo(Path.GetTempFileName());
+                            try
+                            {
+                                MergePartitions(merges, intermediate);
+                            }
+                            finally
+                            {
+                                foreach (var file in merges)
+                                {
+                                    file.Delete();
+                                }
+                                merges.Clear();
+                                merges.Add(intermediate);
+                            }
+                            sortInfo.TempMergeFiles++;
+                        }
+                    }
+                    success = true;
+                }
+                finally
+                {
+                    if (success)
+                    {
+                        IOUtils.Close(inputStream);
+                    }
+                    else
+                    {
+                        IOUtils.CloseWhileHandlingException(inputStream);
+                    }
+                }
+
+                // One partition, try to rename or copy if unsuccessful.
+                if (merges.Count == 1)
+                {
+                    FileInfo single = merges[0];
+                    Copy(single, output);
+                    try
+                    {
+                        File.Delete(single.FullName);
+                    }
+                    catch (Exception)
+                    {
+                        // ignored
+                    }
+                }
+                else
+                {
+                    // otherwise merge the partitions with a priority queue.
+                    MergePartitions(merges, output);
+                }
+                success2 = true;
+            }
+            finally
+            {
+                foreach (FileInfo file in merges)
+                {
+                    file.Delete();
+                }
+                if (!success2)
+                {
+                    output.Delete();
+                }
+            }
+
+            sortInfo.TotalTime = (DateTime.Now.Millisecond - sortInfo.TotalTime);
+            return sortInfo;
+        }
+
+        /// <summary>
+        /// Returns the default temporary directory. By default, the System's temp folder. If not accessible
+        /// or not available, an IOException is thrown
+        /// </summary>
+        public static DirectoryInfo DefaultTempDir()
+        {
+            return new DirectoryInfo(Path.GetTempPath());
+        }
+
+        /// <summary>
+        /// Copies one file to another.
+        /// </summary>
+        private static void Copy(FileInfo file, FileInfo output)
+        {
+            File.Copy(file.FullName, output.FullName);
+        }
+
+        /// <summary>
+        /// Sort a single partition in-memory. </summary>
+        internal FileInfo SortPartition(int len)
+        {
+            var data = this.Buffer;
+            var tempFile = new FileInfo(Path.GetTempFileName());
+            //var tempFile1 = File.Create(new ());
+            //FileInfo tempFile = FileInfo.createTempFile("sort", "partition", TempDirectory);
+
+            long start = DateTime.Now.Millisecond;
+            sortInfo.SortTime += (DateTime.Now.Millisecond - start);
+
+            var @out = new ByteSequencesWriter(tempFile);
+            BytesRef spare;
+            try
+            {
+                BytesRefIterator iter = Buffer.Iterator(comparator);
+                while ((spare = iter.Next()) != null)
+                {
+                    Debug.Assert(spare.Length <= short.MaxValue);
+                    @out.Write(spare);
+                }
+
+                @out.Dispose();
+
+                // Clean up the buffer for the next partition.
+                data.Clear();
+                return tempFile;
+            }
+            finally
+            {
+                IOUtils.Close(@out);
+            }
+        }
+
+        /// <summary>
+        /// Merge a list of sorted temporary files (partitions) into an output file </summary>
+        internal void MergePartitions(IList<FileInfo> merges, FileInfo outputFile)
+        {
+            long start = DateTime.Now.Millisecond;
+
+            var @out = new ByteSequencesWriter(outputFile);
+
+            PriorityQueue<FileAndTop> queue = new PriorityQueueAnonymousInnerClassHelper(this, merges.Count);
+
+            var streams = new ByteSequencesReader[merges.Count];
+            try
+            {
+                // Open streams and read the top for each file
+                for (int i = 0; i < merges.Count; i++)
+                {
+                    streams[i] = new ByteSequencesReader(merges[i]);
+                    byte[] line = streams[i].Read();
+                    if (line != null)
+                    {
+                        queue.InsertWithOverflow(new FileAndTop(i, line));
+                    }
+                }
+
+                // Unix utility sort() uses ordered array of files to pick the next line from, updating
+                // it as it reads new lines. The PQ used here is a more elegant solution and has
+                // a nicer theoretical complexity bound :) The entire sorting process is I/O bound anyway
+                // so it shouldn't make much of a difference (didn't check).
+                FileAndTop top;
+                while ((top = queue.Top()) != null)
+                {
+                    @out.Write(top.Current);
+                    if (!streams[top.Fd].Read(top.Current))
+                    {
+                        queue.Pop();
+                    }
+                    else
+                    {
+                        queue.UpdateTop();
+                    }
+                }
+
+                sortInfo.MergeTime += DateTime.UtcNow.Ticks - start;
+                sortInfo.MergeRounds++;
+            }
+            finally
+            {
+                // The logic below is: if an exception occurs in closing out, it has a priority over exceptions
+                // happening in closing streams.
+                try
+                {
+                    IOUtils.Close(streams);
+                }
+                finally
+                {
+                    IOUtils.Close(@out);
+                }
+            }
+        }
+
+        private class PriorityQueueAnonymousInnerClassHelper : PriorityQueue<FileAndTop>
+        {
+            private readonly OfflineSorter OuterInstance;
+
+            public PriorityQueueAnonymousInnerClassHelper(OfflineSorter outerInstance, int size)
+                : base(size)
+            {
+                this.OuterInstance = outerInstance;
+            }
+
+            public override bool LessThan(FileAndTop a, FileAndTop b)
+            {
+                return OuterInstance.comparator.Compare(a.Current, b.Current) < 0;
+            }
+        }
+
+        /// <summary>
+        /// Read in a single partition of data </summary>
+        internal int ReadPartition(ByteSequencesReader reader)
+        {
+            long start = DateTime.Now.Millisecond;
+            var scratch = new BytesRef();
+            while ((scratch.Bytes = reader.Read()) != null)
+            {
+                scratch.Length = scratch.Bytes.Length;
+                Buffer.Append(scratch);
+                // Account for the created objects.
+                // (buffer slots do not account to buffer size.)
+                if (RamBufferSize.Bytes < BufferBytesUsed.Get())
+                {
+                    break;
+                }
+            }
+            sortInfo.ReadTime += (DateTime.Now.Millisecond - start);
+            return Buffer.Size();
+        }
+
+        internal class FileAndTop
+        {
+            internal readonly int Fd;
+            internal readonly BytesRef Current;
+
+            internal FileAndTop(int fd, byte[] firstLine)
+            {
+                this.Fd = fd;
+                this.Current = new BytesRef(firstLine);
+            }
+        }
+
 
         /// <summary>
         /// Utility class to emit length-prefixed byte[] entries to an output stream for sorting.
@@ -526,8 +527,8 @@ namespace Lucene.Net.Util
 
             /// <summary>
             /// Constructs a ByteSequencesWriter to the provided File </summary>
-            public ByteSequencesWriter(string filePath)
-                : this(new BinaryWriterDataOutput(new BinaryWriter(new FileStream(filePath, FileMode.Open))))
+            public ByteSequencesWriter(FileInfo file)
+                : this(new BinaryWriterDataOutput(new BinaryWriter(new FileStream(file.FullName, FileMode.OpenOrCreate))))
             {
             }
 
@@ -582,102 +583,102 @@ namespace Lucene.Net.Util
                 }
             }
         }
-//
-//        /// <summary>
-//        /// Utility class to read length-prefixed byte[] entries from an input.
-//        /// Complementary to <seealso cref="ByteSequencesWriter"/>.
-//        /// </summary>
-//        public class ByteSequencesReader : IDisposable
-//        {
-//            internal readonly DataInput inputStream;
-//
-//            /// <summary>
-//            /// Constructs a ByteSequencesReader from the provided File </summary>
-//            public ByteSequencesReader(FileInfo file)
-//                : this(new DataInputStream(new BufferedInputStream(new FileInputStream(file))))
-//            {
-//            }
-//
-//            /// <summary>
-//            /// Constructs a ByteSequencesReader from the provided DataInput </summary>
-//            public ByteSequencesReader(DataInput inputStream)
-//            {
-//                this.inputStream = inputStream;
-//            }
-//
-//            /// <summary>
-//            /// Reads the next entry into the provided <seealso cref="BytesRef"/>. The internal
-//            /// storage is resized if needed.
-//            /// </summary>
-//            /// <returns> Returns <code>false</code> if EOF occurred when trying to read
-//            /// the header of the next sequence. Returns <code>true</code> otherwise. </returns>
-//            /// <exception cref="EOFException"> if the file ends before the full sequence is read. </exception>
-//            public virtual bool Read(BytesRef @ref)
-//            {
-//                short length;
-//                try
-//                {
-//                    length = inputStream.ReadShort();
-//                }
-//                catch (EOFException)
-//                {
-//                    return false;
-//                }
-//
-//                @ref.Grow(length);
-//                @ref.Offset = 0;
-//                @ref.Length = length;
-//                inputStream.ReadFully(@ref.Bytes, 0, length);
-//                return true;
-//            }
-//
-//            /// <summary>
-//            /// Reads the next entry and returns it if successful.
-//            /// </summary>
-//            /// <seealso cref= #read(BytesRef)
-//            /// </seealso>
-//            /// <returns> Returns <code>null</code> if EOF occurred before the next entry
-//            /// could be read. </returns>
-//            /// <exception cref="EOFException"> if the file ends before the full sequence is read. </exception>
-//            public virtual sbyte[] Read()
-//            {
-//                short length;
-//                try
-//                {
-//                    length = inputStream.ReadShort();
-//                }
-//                catch (EOFException e)
-//                {
-//                    return null;
-//                }
-//
-//                Debug.Assert(length >= 0, "Sanity: sequence length < 0: " + length);
-//                sbyte[] result = new sbyte[length];
-//                inputStream.ReadFully(result);
-//                return result;
-//            }
-//
-//            /// <summary>
-//            /// Closes the provided <seealso cref="DataInput"/> if it is <seealso cref="IDisposable"/>.
-//            /// </summary>
-//            public void Dispose()
-//            {
-//                var @is = inputStream as IDisposable;
-//                if (@is != null)
-//                {
-//                    @is.Dispose();
-//                }
-//            }
-//        }
-//
-//        /// <summary>
-//        /// Returns the comparator in use to sort entries </summary>
-//        public IComparer<BytesRef> Comparator
-//        {
-//            get
-//            {
-//                return comparator;
-//            }
-//        }
+
+        /// <summary>
+        /// Utility class to read length-prefixed byte[] entries from an input.
+        /// Complementary to <seealso cref="ByteSequencesWriter"/>.
+        /// </summary>
+        public class ByteSequencesReader : IDisposable
+        {
+            internal readonly DataInput inputStream;
+
+            /// <summary>
+            /// Constructs a ByteSequencesReader from the provided File </summary>
+            public ByteSequencesReader(FileInfo file)
+                : this(new BinaryReaderDataInput(new BinaryReader(new FileStream(file.FullName, FileMode.Open))))
+            {
+            }
+
+            /// <summary>
+            /// Constructs a ByteSequencesReader from the provided DataInput </summary>
+            public ByteSequencesReader(DataInput inputStream)
+            {
+                this.inputStream = inputStream;
+            }
+
+            /// <summary>
+            /// Reads the next entry into the provided <seealso cref="BytesRef"/>. The internal
+            /// storage is resized if needed.
+            /// </summary>
+            /// <returns> Returns <code>false</code> if EOF occurred when trying to read
+            /// the header of the next sequence. Returns <code>true</code> otherwise. </returns>
+            /// <exception cref="EOFException"> if the file ends before the full sequence is read. </exception>
+            public virtual bool Read(BytesRef @ref)
+            {
+                short length;
+                try
+                {
+                    length = inputStream.ReadShort();
+                }
+                catch (Exception)
+                {
+                    return false;
+                }
+
+                @ref.Grow(length);
+                @ref.Offset = 0;
+                @ref.Length = length;
+                inputStream.ReadBytes(@ref.Bytes, 0, length);
+                return true;
+            }
+
+            /// <summary>
+            /// Reads the next entry and returns it if successful.
+            /// </summary>
+            /// <seealso cref= #read(BytesRef)
+            /// </seealso>
+            /// <returns> Returns <code>null</code> if EOF occurred before the next entry
+            /// could be read. </returns>
+            /// <exception cref="EOFException"> if the file ends before the full sequence is read. </exception>
+            public virtual byte[] Read()
+            {
+                short length;
+                try
+                {
+                    length = inputStream.ReadShort();
+                }
+                catch (Exception e)
+                {
+                    return null;
+                }
+
+                Debug.Assert(length >= 0, "Sanity: sequence length < 0: " + length);
+                byte[] result = new byte[length];
+                inputStream.ReadBytes(result, 0, length);
+                return result;
+            }
+
+            /// <summary>
+            /// Closes the provided <seealso cref="DataInput"/> if it is <seealso cref="IDisposable"/>.
+            /// </summary>
+            public void Dispose()
+            {
+                var @is = inputStream as IDisposable;
+                if (@is != null)
+                {
+                    @is.Dispose();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Returns the comparator in use to sort entries </summary>
+        public IComparer<BytesRef> Comparator
+        {
+            get
+            {
+                return comparator;
+            }
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/572ad694/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj b/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj
index de4bb24..5c148a2 100644
--- a/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj
+++ b/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj
@@ -543,6 +543,7 @@
     <Compile Include="core\Util\TestNumericUtils.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="core\Util\TestOfflineSorter.cs" />
     <Compile Include="core\Util\TestOpenBitSet.cs">
       <SubType>Code</SubType>
     </Compile>

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/572ad694/src/Lucene.Net.Tests/core/Util/TestOfflineSorter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/core/Util/TestOfflineSorter.cs b/src/Lucene.Net.Tests/core/Util/TestOfflineSorter.cs
index 3f5530c..ffd1fc6 100644
--- a/src/Lucene.Net.Tests/core/Util/TestOfflineSorter.cs
+++ b/src/Lucene.Net.Tests/core/Util/TestOfflineSorter.cs
@@ -3,33 +3,33 @@ using System.Collections.Generic;
 using System.IO;
 using Lucene.Net.Support;
 using NUnit.Framework;
+using Lucene.Net.Attributes;
 
 namespace Lucene.Net.Util
 {
-    using NUnit.Framework;
     /*
-         * 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.
-         */
+    * 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.
+    */
 
 
     //LUCENE PORT NOTE: The corresponding file was left out of the port due to being experimental on not porting properly
-    /*
-    using BufferSize = Lucene.Net.Util.OfflineSorter.BufferSize;
-    using ByteSequencesWriter = Lucene.Net.Util.OfflineSorter.ByteSequencesWriter;
-    using SortInfo = Lucene.Net.Util.OfflineSorter.SortInfo;
+    
+    //using BufferSize = Lucene.Net.Util.OfflineSorter.BufferSize;
+    //using ByteSequencesWriter = Lucene.Net.Util.OfflineSorter.ByteSequencesWriter;
+    //using SortInfo = Lucene.Net.Util.OfflineSorter.SortInfo;
 
     /// <summary>
     /// Tests for on-disk merge sorting.
@@ -44,66 +44,79 @@ namespace Lucene.Net.Util
         {
             base.SetUp();
             TempDir = CreateTempDir("mergesort");
-            TestUtil.Rm(TempDir);
+            DeleteTestFiles();
             TempDir.Create();
         }
 
         [TearDown]
         public override void TearDown()
         {
+            DeleteTestFiles();
+            base.TearDown();
+        }
+
+        private void DeleteTestFiles()
+        {
             if (TempDir != null)
             {
-                TestUtil.Rm(TempDir);
+                if (Directory.Exists(TempDir.FullName))
+                {
+                    foreach (var file in TempDir.GetFiles())
+                    {
+                        file.Delete();
+                    }
+                    TempDir.Delete();
+                }
             }
-            base.TearDown();
         }
 
         [Test]
         public virtual void TestEmpty()
         {
-            CheckSort(new OfflineSorter(), new sbyte[][] { });
+            CheckSort(new OfflineSorter(), new byte[][] { });
         }
 
         [Test]
         public virtual void TestSingleLine()
         {
-            CheckSort(new OfflineSorter(), new sbyte[][] { "Single line only.".GetBytes(IOUtils.CHARSET_UTF_8) });
+            CheckSort(new OfflineSorter(), new byte[][] { "Single line only.".GetBytes(IOUtils.CHARSET_UTF_8) });
         }
 
         [Test]
         public virtual void TestIntermediateMerges()
         {
             // Sort 20 mb worth of data with 1mb buffer, binary merging.
-            OfflineSorter.SortInfo info = CheckSort(new OfflineSorter(OfflineSorter.DEFAULT_COMPARATOR, OfflineSorter.BufferSize.megabytes(1), OfflineSorter.defaultTempDir(), 2), GenerateRandom((int)OfflineSorter.MB * 20));
-            Assert.IsTrue(info.mergeRounds > 10);
+            OfflineSorter.SortInfo info = CheckSort(new OfflineSorter(OfflineSorter.DEFAULT_COMPARATOR, OfflineSorter.BufferSize.Megabytes(1), OfflineSorter.DefaultTempDir(), 2), GenerateRandom((int)OfflineSorter.MB * 20));
+            Assert.IsTrue(info.MergeRounds > 10);
         }
 
         [Test]
         public virtual void TestSmallRandom()
         {
             // Sort 20 mb worth of data with 1mb buffer.
-            OfflineSorter.SortInfo sortInfo = CheckSort(new OfflineSorter(OfflineSorter.DEFAULT_COMPARATOR, OfflineSorter.BufferSize.megabytes(1), OfflineSorter.defaultTempDir(), OfflineSorter.MAX_TEMPFILES), GenerateRandom((int)OfflineSorter.MB * 20));
-            Assert.AreEqual(1, sortInfo.mergeRounds);
+            OfflineSorter.SortInfo sortInfo = CheckSort(new OfflineSorter(OfflineSorter.DEFAULT_COMPARATOR, OfflineSorter.BufferSize.Megabytes(1), OfflineSorter.DefaultTempDir(), OfflineSorter.MAX_TEMPFILES), GenerateRandom((int)OfflineSorter.MB * 20));
+            Assert.AreEqual(1, sortInfo.MergeRounds);
         }
 
         [Test]
+        [Timeout(120000), LongRunningTest]
         public virtual void TestLargerRandom()
         {
             // Sort 100MB worth of data with 15mb buffer.
-            CheckSort(new OfflineSorter(OfflineSorter.DEFAULT_COMPARATOR, OfflineSorter.BufferSize.megabytes(16), OfflineSorter.defaultTempDir(), OfflineSorter.MAX_TEMPFILES), GenerateRandom((int)OfflineSorter.MB * 100));
+            CheckSort(new OfflineSorter(OfflineSorter.DEFAULT_COMPARATOR, OfflineSorter.BufferSize.Megabytes(16), OfflineSorter.DefaultTempDir(), OfflineSorter.MAX_TEMPFILES), GenerateRandom((int)OfflineSorter.MB * 100));
         }
 
-        private sbyte[][] GenerateRandom(int howMuchData)
+        private byte[][] GenerateRandom(int howMuchData)
         {
-            List<sbyte[]> data = new List<sbyte[]>();
+            List<byte[]> data = new List<byte[]>();
             while (howMuchData > 0)
             {
-                sbyte[] current = new sbyte[Random().Next(256)];
+                byte[] current = new byte[Random().Next(256)];
                 Random().NextBytes((byte[])(Array)current);
                 data.Add(current);
                 howMuchData -= current.Length;
             }
-            sbyte[][] bytes = data.ToArray();
+            byte[][] bytes = data.ToArray();
             return bytes;
         }
 
@@ -132,15 +145,15 @@ namespace Lucene.Net.Util
         /// <summary>
         /// Check sorting data on an instance of <seealso cref="OfflineSorter"/>.
         /// </summary>
-        private OfflineSorter.SortInfo CheckSort(OfflineSorter sort, sbyte[][] data)
+        private OfflineSorter.SortInfo CheckSort(OfflineSorter sort, byte[][] data)
         {
-            File unsorted = WriteAll("unsorted", data);
+            FileInfo unsorted = WriteAll("unsorted", data);
 
             Array.Sort(data, unsignedByteOrderComparator);
-            File golden = WriteAll("golden", data);
+            FileInfo golden = WriteAll("golden", data);
 
-            File sorted = new File(TempDir, "sorted");
-            OfflineSorter.SortInfo sortInfo = sort.sort(unsorted, sorted);
+            FileInfo sorted = new FileInfo(Path.Combine(TempDir.FullName, "sorted"));
+            OfflineSorter.SortInfo sortInfo = sort.Sort(unsorted, sorted);
             //System.out.println("Input size [MB]: " + unsorted.Length() / (1024 * 1024));
             //System.out.println(sortInfo);
 
@@ -151,33 +164,40 @@ namespace Lucene.Net.Util
         /// <summary>
         /// Make sure two files are byte-byte identical.
         /// </summary>
-        private void AssertFilesIdentical(File golden, File sorted)
+        private void AssertFilesIdentical(FileInfo golden, FileInfo sorted)
         {
-            Assert.AreEqual(golden.Length(), sorted.Length());
+            Assert.AreEqual(golden.Length, sorted.Length);
 
-            sbyte[] buf1 = new sbyte[64 * 1024];
-            sbyte[] buf2 = new sbyte[64 * 1024];
+            byte[] buf1 = new byte[64 * 1024];
+            byte[] buf2 = new byte[64 * 1024];
             int len;
-            DataInputStream is1 = new DataInputStream(new FileInputStream(golden));
-            DataInputStream is2 = new DataInputStream(new FileInputStream(sorted));
-            while ((len = is1.read(buf1)) > 0)
+            //DataInputStream is1 = new DataInputStream(new FileInputStream(golden));
+            //DataInputStream is2 = new DataInputStream(new FileInputStream(sorted));
+            using (Stream is1 = golden.Open(FileMode.Open, FileAccess.Read, FileShare.Delete))
             {
-                is2.readFully(buf2, 0, len);
-                for (int i = 0; i < len; i++)
+                using (Stream is2 = sorted.Open(FileMode.Open, FileAccess.Read, FileShare.Delete))
                 {
-                    Assert.AreEqual(buf1[i], buf2[i]);
+                    while ((len = is1.Read(buf1, 0, buf1.Length)) > 0)
+                    {
+                        is2.Read(buf2, 0, len);
+                        for (int i = 0; i < len; i++)
+                        {
+                            Assert.AreEqual(buf1[i], buf2[i]);
+                        }
+                    }
+                    //IOUtils.Close(is1, is2);
                 }
             }
-            IOUtils.Close(is1, is2);
         }
 
-        private File WriteAll(string name, sbyte[][] data)
+        private FileInfo WriteAll(string name, byte[][] data)
         {
-            File file = new File(TempDir, name);
+            FileInfo file = new FileInfo(Path.Combine(TempDir.FullName, name));
+            using (file.Create()) { }
             OfflineSorter.ByteSequencesWriter w = new OfflineSorter.ByteSequencesWriter(file);
-            foreach (sbyte[] datum in data)
+            foreach (byte[] datum in data)
             {
-                w.write(datum);
+                w.Write(datum);
             }
             w.Dispose();
             return file;
@@ -189,14 +209,14 @@ namespace Lucene.Net.Util
             int numIters = AtLeast(10000);
             for (int i = 0; i < numIters; i++)
             {
-                OfflineSorter.BufferSize.megabytes(1 + Random().Next(2047));
+                OfflineSorter.BufferSize.Megabytes(1 + Random().Next(2047));
             }
-            OfflineSorter.BufferSize.megabytes(2047);
-            OfflineSorter.BufferSize.megabytes(1);
+            OfflineSorter.BufferSize.Megabytes(2047);
+            OfflineSorter.BufferSize.Megabytes(1);
 
             try
             {
-                OfflineSorter.BufferSize.megabytes(2048);
+                OfflineSorter.BufferSize.Megabytes(2048);
                 Assert.Fail("max mb is 2047");
             }
             catch (System.ArgumentException e)
@@ -205,7 +225,7 @@ namespace Lucene.Net.Util
 
             try
             {
-                OfflineSorter.BufferSize.megabytes(0);
+                OfflineSorter.BufferSize.Megabytes(0);
                 Assert.Fail("min mb is 0.5");
             }
             catch (System.ArgumentException e)
@@ -214,13 +234,12 @@ namespace Lucene.Net.Util
 
             try
             {
-                OfflineSorter.BufferSize.megabytes(-1);
+                OfflineSorter.BufferSize.Megabytes(-1);
                 Assert.Fail("min mb is 0.5");
             }
             catch (System.ArgumentException e)
             {
             }
         }
-    }*/
-
+    }
 }
\ No newline at end of file


Mime
View raw message