// ----------------------------------------------------------------------- // // // 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); } } }