You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2020/02/09 06:16:25 UTC
[lucenenet] 33/35:
Lucene.Net.Support.IO.FileStreamExtensions::Read(): Moved to
StreamExtensions class and optimized to read bytes in bulk instead of one
byte at a time (fixes LUCENENET-643)
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
commit 5da2567ea771538a31566918066d01bde3b6af0f
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Fri Feb 7 12:38:54 2020 +0700
Lucene.Net.Support.IO.FileStreamExtensions::Read(): Moved to StreamExtensions class and optimized to read bytes in bulk instead of one byte at a time (fixes LUCENENET-643)
---
src/Lucene.Net/Store/NIOFSDirectory.cs | 4 +-
src/Lucene.Net/Support/IO/FileStreamExtensions.cs | 57 ------------
src/Lucene.Net/Support/IO/StreamExtensions.cs | 107 +++++++++++++++++++++-
3 files changed, 108 insertions(+), 60 deletions(-)
diff --git a/src/Lucene.Net/Store/NIOFSDirectory.cs b/src/Lucene.Net/Store/NIOFSDirectory.cs
index 8842766..d49625e 100644
--- a/src/Lucene.Net/Store/NIOFSDirectory.cs
+++ b/src/Lucene.Net/Store/NIOFSDirectory.cs
@@ -158,8 +158,8 @@ namespace Lucene.Net.Store
}
/// <summary>
- /// Reads bytes with the <see cref="FileStreamExtensions.Read(FileStream, ByteBuffer, long)"/>
- /// extension method for <see cref="FileStream"/>.
+ /// Reads bytes with the <see cref="StreamExtensions.Read(Stream, ByteBuffer, long)"/>
+ /// extension method for <see cref="Stream"/>.
/// </summary>
protected class NIOFSIndexInput : BufferedIndexInput
{
diff --git a/src/Lucene.Net/Support/IO/FileStreamExtensions.cs b/src/Lucene.Net/Support/IO/FileStreamExtensions.cs
deleted file mode 100644
index cec1efd..0000000
--- a/src/Lucene.Net/Support/IO/FileStreamExtensions.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using J2N.IO;
-using System.IO;
-
-namespace Lucene.Net.Support.IO
-{
- /*
- * 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.
- */
-
- internal static class FileStreamExtensions
- {
- private static object _fsReadLock = new object();
-
- //Reads bytes from the Filestream into the bytebuffer
- public static int Read(this FileStream file, ByteBuffer dst, long position)
- {
- lock (_fsReadLock)
- {
- // TODO: check this logic, could probably optimize
- if (position >= file.Length)
- return 0;
-
- var original = file.Position;
-
- file.Seek(position, SeekOrigin.Begin);
-
- int count = 0;
-
- for (int i = dst.Position; i < dst.Limit; i++)
- {
- int v = file.ReadByte();
- if (v == -1)
- break;
- dst.Put((byte) v);
- count++;
- }
-
- file.Seek(original, SeekOrigin.Begin);
-
- return count;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Lucene.Net/Support/IO/StreamExtensions.cs b/src/Lucene.Net/Support/IO/StreamExtensions.cs
index f8c8531..2a4d5ca 100644
--- a/src/Lucene.Net/Support/IO/StreamExtensions.cs
+++ b/src/Lucene.Net/Support/IO/StreamExtensions.cs
@@ -1,4 +1,6 @@
-using System.IO;
+using J2N.IO;
+using System;
+using System.IO;
namespace Lucene.Net.Support.IO
{
@@ -32,8 +34,94 @@ namespace Lucene.Net.Support.IO
/// </summary>
internal static class StreamExtensions
{
+ private static readonly object readLock = new object();
+
+
+ /// <summary>
+ /// Reads a sequence of bytes from a <see cref="Stream"/> to the given <see cref="ByteBuffer"/>, starting at the given position.
+ /// The <paramref name="stream"/> must be both seekable and readable.
+ /// </summary>
+ /// <param name="stream">The stream to read.</param>
+ /// <param name="destination">The <see cref="ByteBuffer"/> to write to.</param>
+ /// <param name="position">The file position at which the transfer is to begin; must be non-negative.</param>
+ /// <returns>The number of bytes read, possibly zero.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="stream"/> or <paramref name="destination"/> is <c>null</c></exception>
+ /// <exception cref="NotSupportedException">
+ /// <paramref name="stream"/> is not readable.
+ /// <para/>
+ /// -or-
+ /// <para/>
+ /// <paramref name="stream"/> is not seekable.
+ /// </exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="position"/> is less than 0.
+ /// <para/>
+ /// -or-
+ /// <para/>
+ /// <paramref name="position"/> is greater than the <see cref="Stream.Length"/> of the stream.
+ /// </exception>
+ /// <exception cref="IOException">An I/O error occurs.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="stream"/> has already been disposed.</exception>
+ /// <remarks>
+ /// This method is atomic when used by itself, but does not synchronize with the rest of the stream methods.
+ /// </remarks>
+ public static int Read(this Stream stream, ByteBuffer destination, long position)
+ {
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream));
+ if (destination == null)
+ throw new ArgumentNullException(nameof(destination));
+ if (position < 0)
+ throw new ArgumentOutOfRangeException(nameof(position));
+ if (!stream.CanSeek)
+ throw new NotSupportedException("Stream does not support seeking.");
+ if (!stream.CanRead)
+ throw new NotSupportedException("Stream does not support reading.");
+ if (position > stream.Length)
+ return 0;
+
+ int read = 0;
+ lock (readLock)
+ {
+ long originalPosition = stream.Position;
+ stream.Seek(position, SeekOrigin.Begin);
+
+ if (destination.HasArray)
+ {
+ // If the buffer has an array, we can write to it directly and save
+ // an extra copy operation.
+
+ // Read from the stream
+ read = stream.Read(destination.Array, destination.Position, destination.Remaining);
+ destination.Position += read;
+ }
+ else
+ {
+ // If the buffer has no array, we must use a local buffer
+ byte[] buffer = new byte[destination.Remaining];
+
+ // Read from the stream
+ read = stream.Read(buffer, 0, buffer.Length);
+
+ // Write to the byte buffer
+ destination.Put(buffer, 0, read);
+ }
+
+ // Per Java's FileChannel.Read(), we don't want to alter the position
+ // of the stream, so we return it as it was originally.
+ stream.Seek(originalPosition, SeekOrigin.Begin);
+ }
+
+ return read;
+ }
+
public static void Write(this Stream stream, char[] chars)
{
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream));
+ if (chars == null)
+ throw new ArgumentNullException(nameof(chars));
+
byte[] newBytes = new byte[chars.Length * 2];
for (int index = 0; index < chars.Length; index++)
{
@@ -46,6 +134,11 @@ namespace Lucene.Net.Support.IO
public static char[] ReadChars(this Stream stream, int count)
{
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream));
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count));
+
byte[] buff = new byte[2];
char[] newChars = new char[count];
for (int i = 0; i < count; i++)
@@ -58,6 +151,9 @@ namespace Lucene.Net.Support.IO
public static void Write(this Stream stream, int value)
{
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream));
+
byte[] buff = new byte[4];
buff[0] = (byte)(value);
buff[1] = (byte)(value >> 8);
@@ -68,6 +164,9 @@ namespace Lucene.Net.Support.IO
public static int ReadInt32(this Stream stream)
{
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream));
+
byte[] buff = new byte[4];
stream.Read(buff, 0, buff.Length);
return (buff[0] & 0xff) | ((buff[1] & 0xff) << 8) |
@@ -76,6 +175,9 @@ namespace Lucene.Net.Support.IO
public static void Write(this Stream stream, long value)
{
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream));
+
byte[] buff = new byte[8];
buff[0] = (byte)value;
buff[1] = (byte)(value >> 8);
@@ -90,6 +192,9 @@ namespace Lucene.Net.Support.IO
public static long ReadInt64(this Stream stream)
{
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream));
+
byte[] buff = new byte[8];
stream.Read(buff, 0, buff.Length);
uint lo = (uint)(buff[0] | buff[1] << 8 |