// -----------------------------------------------------------------------
//
//
// 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.
//
//
// -----------------------------------------------------------------------
namespace Lucene.Net.Util
{
using System;
///
/// Utility class for manipulating arrays.
///
///
///
/// Java File:
/// lucene/src/java/org/apache/lucene/util/AttributeUtil.java
///
///
///
/// C# File:
/// src/Lucene.Net/Util/ArrayUtil.cs
///
///
///
/// C# Tests:
/// test/Lucene.Net.Test/Util/ArrayUtilTest.cs
///
///
///
public static class ArrayUtil
{
///
/// Creates the hash code of chars in range start that is inclusive, till the end.
///
///
/// This method is just called hashCode() in the java version.
///
/// The array.
/// The start which defaults to 0.
/// The end which defaults to the length of the array.
/// An instance of .
public static int CreateHashCode(this char[] array, int start = 0, int end = -1)
{
if (end == -1)
end = array.Length;
int code = 0;
for (int i = end - 1; i >= start; i--)
code = (code * 31) + array[i];
return code;
}
///
/// Creates the hash code of bytes in range start that is inclusive, till the end.
///
///
/// This method is just called hashCode() in the java version.
///
/// The array.
/// The start which defaults to 0.
/// The end which defaults to the length of the array.
/// An instance of .
public static int CreateHashCode(this byte[] array, int start = 0, int end = -1)
{
int code = 0;
if (end == -1)
end = array.Length;
for (int i = end - 1; i >= start; i--)
code = (code * 31) + array[i];
return code;
}
///
/// Returns an array size that is greater or equal to the .
/// This will generally over allocate exponentially to achieve amortized
/// linear-time cost as the array grows.
///
/// Size of the minimal target.
/// The bytes per element.
/// the size of the array.
public static int Oversize(int minimalTargetSize, int bytesPerElement)
{
if (minimalTargetSize < 0)
throw new ArgumentOutOfRangeException("minimalTargetSize", "the minimalTargetSize must be 0 or greater.");
if (minimalTargetSize == 0)
return minimalTargetSize;
// asymptotic exponential growth by 1/8th, favors
// spending a bit more CPU to not tie up too much wasted RAM
int extra = minimalTargetSize >> 3;
// for very small arrays, where constant overhead of
// realloc* is presumably relatively high, we grow faster.
// realloc - memory re-allocator.
if (extra < 3)
extra = 3;
int newSize = minimalTargetSize * extra;
if (newSize + 7 < 0)
return int.MaxValue;
if (IntPtr.Size == 8)
{
switch (bytesPerElement)
{
case 4:
// round up to multiple of 2
return (newSize + 1) & 0x7ffffffe;
case 2:
// round up to multiple of 4
return (newSize + 3) & 0x7ffffffc;
case 1:
// round up to multiple of 8
return (newSize + 7) & 0x7ffffff8;
default:
return newSize;
}
}
switch (bytesPerElement)
{
case 2:
// round up to multiple of 4
return (newSize + 1) & 0x7ffffffe;
case 1:
// round up to multiple of 8
return (newSize + 3) & 0x7ffffffc;
default:
return newSize;
}
}
///
/// Grows the specified by a minimum of 1.
///
/// The type of the array.
/// The source.
/// an array of .
public static T[] Grow(T[] source)
{
return Grow(source, source.Length + 1);
}
///
/// Grows the specified to the specified length.
///
/// The type of the array.
/// The source.
/// The length.
/// The bytes per element.
///
/// a new array if the length of the was less than or equal
/// to the specified , otherwise it returns the .
///
/// Thrown when is null.
///
/// Thrown when is less than 0.
///
public static T[] Grow(T[] source, int length, int bytesPerElement = 1)
{
if (source == null)
throw new ArgumentNullException("source");
if (length < 0)
throw new ArgumentException("length must be greater than or equal to 0");
if (source.Length >= length)
return source;
T[] destination = new T[Oversize(length, bytesPerElement)];
Array.Copy(source, 0, destination, 0, source.Length);
return destination;
}
///
/// Grows the specified array by 1.
///
/// The array.
/// a char[].
/// Thrown when is null.
public static char[] Grow(char[] source)
{
return Grow(source, source.Length + 1);
}
///
/// Grows the specified array to the minimum length specified.
///
/// The array.
/// The length.
/// an char[]
/// Thrown when is null.
///
/// Thrown when is less than 0.
///
public static char[] Grow(char[] source, int length)
{
return Grow(source, length, RamUsageEstimator.NumberOfBytesChar);
}
}
}