diff --git a/src/Workspaces/CoreTest/Collections/SegmentedArrayHelperTests.cs b/src/Workspaces/CoreTest/Collections/SegmentedArrayHelperTests.cs new file mode 100644 index 0000000000000..dbd6b501c24a5 --- /dev/null +++ b/src/Workspaces/CoreTest/Collections/SegmentedArrayHelperTests.cs @@ -0,0 +1,98 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Shared.Collections; +using Roslyn.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.UnitTests.Collections +{ + public class SegmentedArrayHelperTests + { + [Theory] + [InlineData(1)] + [InlineData(2)] + [InlineData(3)] + [InlineData(4)] + [InlineData(5)] + [InlineData(6)] + [InlineData(7)] + [InlineData(8)] + [InlineData(9)] + [InlineData(10)] + [InlineData(16)] + [InlineData(32)] + public void CalculateSegmentSize(int elementSize) + { + var expected = elementSize switch + { + 1 => 65536, + 2 => 32768, + 3 => 16384, + 4 => 16384, + 5 => 16384, + 6 => 8192, + 7 => 8192, + 8 => 8192, + 9 => 8192, + 10 => 8192, + 16 => 4096, + 32 => 2048, + _ => throw ExceptionUtilities.Unreachable, + }; + + Assert.Equal(expected, SegmentedArrayHelper.CalculateSegmentSize(elementSize)); + } + + [Theory] + [InlineData(1024)] + [InlineData(2048)] + [InlineData(4096)] + [InlineData(8192)] + [InlineData(16384)] + [InlineData(32768)] + [InlineData(65536)] + public void CalculateSegmentShift(int segmentSize) + { + var expected = segmentSize switch + { + 1024 => 10, + 2048 => 11, + 4096 => 12, + 8192 => 13, + 16384 => 14, + 32768 => 15, + 65536 => 16, + _ => throw ExceptionUtilities.Unreachable, + }; + + Assert.Equal(expected, SegmentedArrayHelper.CalculateSegmentShift(segmentSize)); + } + + [Theory] + [InlineData(1024)] + [InlineData(2048)] + [InlineData(4096)] + [InlineData(8192)] + [InlineData(16384)] + [InlineData(32768)] + [InlineData(65536)] + public void CalculateOffsetMask(int segmentSize) + { + var expected = segmentSize switch + { + 1024 => 0x3FF, + 2048 => 0x7FF, + 4096 => 0xFFF, + 8192 => 0x1FFF, + 16384 => 0x3FFF, + 32768 => 0x7FFF, + 65536 => 0xFFFF, + _ => throw ExceptionUtilities.Unreachable, + }; + + Assert.Equal(expected, SegmentedArrayHelper.CalculateOffsetMask(segmentSize)); + } + } +} diff --git a/src/Workspaces/CoreTest/Collections/SegmentedArrayTests.cs b/src/Workspaces/CoreTest/Collections/SegmentedArrayTests.cs new file mode 100644 index 0000000000000..9016c1e863a17 --- /dev/null +++ b/src/Workspaces/CoreTest/Collections/SegmentedArrayTests.cs @@ -0,0 +1,210 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis.Shared.Collections; +using Xunit; + +namespace Microsoft.CodeAnalysis.UnitTests.Collections +{ + public class SegmentedArrayTests + { + public static IEnumerable TestLengths + { + get + { + yield return new object[] { 1 }; + yield return new object[] { 10 }; + yield return new object[] { 100 }; + yield return new object[] { SegmentedArray.TestAccessor.SegmentSize / 2 }; + yield return new object[] { SegmentedArray.TestAccessor.SegmentSize }; + yield return new object[] { SegmentedArray.TestAccessor.SegmentSize * 2 }; + yield return new object[] { 100000 }; + } + } + + private static void ResetToSequence(SegmentedArray array) + { + for (var i = 0; i < array.Length; i++) + { + array[i] = (IntPtr)i; + } + } + + [Fact] + public void TestDefaultInstance() + { + var data = default(SegmentedArray); + Assert.Null(data.GetTestAccessor().Items); + + Assert.True(data.IsFixedSize); + Assert.False(data.IsReadOnly); + Assert.False(data.IsSynchronized); + Assert.Equal(0, data.Length); + Assert.Null(data.SyncRoot); + + Assert.Throws(() => data[0]); + Assert.Throws(() => ((IReadOnlyList)data)[0]); + Assert.Throws(() => ((IList)data)[0]); + Assert.Throws(() => ((IList)data)[0] = IntPtr.Zero); + Assert.Throws(() => ((IList)data)[0]); + Assert.Throws(() => ((IList)data)[0] = IntPtr.Zero); + + Assert.Equal(0, ((ICollection)data).Count); + Assert.Equal(0, ((ICollection)data).Count); + Assert.Equal(0, ((IReadOnlyCollection)data).Count); + + Assert.Throws(() => data.Clone()); + Assert.Throws(() => data.CopyTo(Array.Empty(), 0)); + Assert.Throws(() => ((ICollection)data).CopyTo(Array.Empty(), 0)); + + var enumerator1 = data.GetEnumerator(); + Assert.Throws(() => enumerator1.MoveNext()); + + var enumerator2 = ((IEnumerable)data).GetEnumerator(); + Assert.Throws(() => enumerator1.MoveNext()); + + var enumerator3 = ((IEnumerable)data).GetEnumerator(); + Assert.Throws(() => enumerator1.MoveNext()); + + Assert.Throws(() => ((IList)data).Add(IntPtr.Zero)); + Assert.Throws(() => ((ICollection)data).Add(IntPtr.Zero)); + Assert.Throws(() => ((ICollection)data).Clear()); + Assert.Throws(() => ((IList)data).Insert(0, IntPtr.Zero)); + Assert.Throws(() => ((IList)data).Insert(0, IntPtr.Zero)); + Assert.Throws(() => ((IList)data).Remove(IntPtr.Zero)); + Assert.Throws(() => ((ICollection)data).Remove(IntPtr.Zero)); + Assert.Throws(() => ((IList)data).RemoveAt(0)); + Assert.Throws(() => ((IList)data).RemoveAt(0)); + + Assert.Throws(() => ((IList)data).Clear()); + Assert.Throws(() => ((IList)data).Contains(IntPtr.Zero)); + Assert.Throws(() => ((ICollection)data).Contains(IntPtr.Zero)); + Assert.Throws(() => ((IList)data).IndexOf(IntPtr.Zero)); + Assert.Throws(() => ((IList)data).IndexOf(IntPtr.Zero)); + } + + [Fact] + public void TestConstructor1() + { + Assert.Throws("length", () => new SegmentedArray(-1)); + + Assert.Empty(new SegmentedArray(0)); + Assert.Same(Array.Empty(), new SegmentedArray(0).GetTestAccessor().Items); + } + + [Theory] + [MemberData(nameof(TestLengths))] + public void TestConstructor2(int length) + { + var data = new SegmentedArray(length); + Assert.Equal(length, data.Length); + + var items = data.GetTestAccessor().Items; + Assert.Equal(length, items.Sum(item => item.Length)); + + for (var i = 0; i < items.Length - 1; i++) + { + Assert.Equal(SegmentedArray.TestAccessor.SegmentSize, items[i].Length); + Assert.True(items[i].Length <= SegmentedArray.TestAccessor.SegmentSize); + } + } + + [Theory] + [MemberData(nameof(TestLengths))] + public void TestBasicProperties(int length) + { + var data = new SegmentedArray(length); + + Assert.True(data.IsFixedSize); + Assert.False(data.IsReadOnly); + Assert.False(data.IsSynchronized); + Assert.Equal(length, data.Length); + Assert.Same(data.GetTestAccessor().Items, data.SyncRoot); + + Assert.Equal(length, ((ICollection)data).Count); + Assert.Equal(length, ((ICollection)data).Count); + Assert.Equal(length, ((IReadOnlyCollection)data).Count); + } + + [Theory] + [MemberData(nameof(TestLengths))] + public void TestIndexer(int length) + { + var data = new SegmentedArray(length); + ResetToSequence(data); + + for (var i = 0; i < length; i++) + { + data[i] = (IntPtr)i; + } + + for (var i = 0; i < length; i++) + { + Assert.Equal((IntPtr)i, data[i]); + } + + for (var i = 0; i < length; i++) + { + ref var value = ref data[i]; + Assert.Equal((IntPtr)i, data[i]); + value = IntPtr.Add(value, 1); + + Assert.Equal((IntPtr)(i + 1), value); + Assert.Equal((IntPtr)(i + 1), data[i]); + } + + ResetToSequence(data); + for (var i = 0; i < length; i++) + { + Assert.Equal((IntPtr)i, ((IReadOnlyList)data)[i]); + data[i] = IntPtr.Add(data[i], 1); + Assert.Equal((IntPtr)(i + 1), ((IReadOnlyList)data)[i]); + } + + ResetToSequence(data); + for (var i = 0; i < length; i++) + { + Assert.Equal((IntPtr)i, ((IList)data)[i]); + ((IList)data)[i] = IntPtr.Add(data[i], 1); + Assert.Equal((IntPtr)(i + 1), ((IList)data)[i]); + } + + ResetToSequence(data); + for (var i = 0; i < length; i++) + { + Assert.Equal((IntPtr)i, ((IList)data)[i]); + ((IList)data)[i] = IntPtr.Add(data[i], 1); + Assert.Equal((IntPtr)(i + 1), ((IList)data)[i]); + } + } + + /// + /// Verify that indexing and iteration match for an array with many segments. + /// + [Fact] + public void TestIterateLargeArray() + { + var data = new SegmentedArray(1000000); + Assert.True(data.GetTestAccessor().Items.Length > 10); + + for (var i = 0; i < data.Length; i++) + { + data[i] = Guid.NewGuid(); + Assert.NotEqual(Guid.Empty, data[i]); + } + + var index = 0; + foreach (var guid in data) + { + Assert.Equal(guid, data[index++]); + } + + Assert.Equal(data.Length, index); + } + } +} diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Collections/SegmentedArrayHelper.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Collections/SegmentedArrayHelper.cs new file mode 100644 index 0000000000000..79109a037920c --- /dev/null +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Collections/SegmentedArrayHelper.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Diagnostics; + +namespace Microsoft.CodeAnalysis.Shared.Collections +{ + internal static class SegmentedArrayHelper + { + /// + /// Calculates the maximum number of elements of size which can fit into an array + /// which has the following characteristics: + /// + /// The array can be allocated in the small object heap. + /// The array length is a power of 2. + /// + /// + /// The size of the elements in the array. + /// The segment size to use for small object heap segmented arrays. + internal static int CalculateSegmentSize(int elementSize) + { + // Default Large Object Heap size threshold + // https://github.com/dotnet/runtime/blob/c9d69e38d0e54bea5d188593ef6c3b30139f3ab1/src/coreclr/src/gc/gc.h#L111 + const int Threshold = 85000; + + var segmentSize = 2; + while (ArraySize(elementSize, segmentSize << 1) < Threshold) + { + segmentSize <<= 1; + } + + return segmentSize; + + static int ArraySize(int elementSize, int segmentSize) + { + // Array object header, plus space for the elements + return (2 * IntPtr.Size) + (elementSize * segmentSize); + } + } + + /// + /// Calculates a shift which can be applied to an absolute index to get the page index within a segmented array. + /// + /// The number of elements in each page of the segmented array. Must be a power of 2. + /// The shift to apply to the absolute index to get the page index within a segmented array. + internal static int CalculateSegmentShift(int segmentSize) + { + var segmentShift = 0; + while (0 != (segmentSize >>= 1)) + { + segmentShift++; + } + + return segmentShift; + } + + /// + /// Calculates a mask, which can be applied to an absolute index to get the index within a page of a segmented + /// array. + /// + /// The number of elements in each page of the segmented array. Must be a power of 2. + /// The bit mask to obtain the index within a page from an absolute index within a segmented array. + internal static int CalculateOffsetMask(int segmentSize) + { + Debug.Assert(segmentSize == 1 || (segmentSize & (segmentSize - 1)) == 0, "Expected size of 1, or a power of 2"); + return segmentSize - 1; + } + } +} diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Collections/SegmentedArray`1.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Collections/SegmentedArray`1.cs new file mode 100644 index 0000000000000..f8f73eb2d2770 --- /dev/null +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Collections/SegmentedArray`1.cs @@ -0,0 +1,399 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.Shared.Collections +{ + /// + /// Defines a fixed-size collection with the same API surface and behavior as an "SZArray", which is a + /// single-dimensional zero-based array commonly represented in C# as T[]. The implementation of this + /// collection uses segmented arrays to avoid placing objects on the Large Object Heap. + /// + /// The type of elements stored in the array. + internal readonly struct SegmentedArray : ICloneable, IList, IStructuralComparable, IStructuralEquatable, IList, IReadOnlyList + { + /// + /// The number of elements in each page of the segmented array of type . + /// + /// + /// The segment size is calculated according to , performs the IL operation + /// defined by . ECMA-335 defines this operation with the following note: + /// + /// sizeof returns the total size that would be occupied by each element in an array of this type – + /// including any padding the implementation chooses to add. Specifically, array elements lie sizeof + /// bytes apart. + /// + private static readonly int s_segmentSize = SegmentedArrayHelper.CalculateSegmentSize(Unsafe.SizeOf()); + + /// + /// The bit shift to apply to an array index to get the page index within . + /// + private static readonly int s_segmentShift = SegmentedArrayHelper.CalculateSegmentShift(s_segmentSize); + + /// + /// The bit mask to apply to an array index to get the index within a page of . + /// + private static readonly int s_offsetMask = SegmentedArrayHelper.CalculateOffsetMask(s_segmentSize); + + private readonly int _length; + private readonly T[][] _items; + + public SegmentedArray(int length) + { + if (length < 0) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + if (length == 0) + { + _items = Array.Empty(); + _length = 0; + } + else + { + _items = new T[(length + s_segmentSize - 1) >> s_segmentShift][]; + for (var i = 0; i < _items.Length - 1; i++) + { + _items[i] = new T[s_segmentSize]; + } + + // Make sure the last page only contains the number of elements required for the desired length. This + // collection is not resizeable so any additional padding would be a waste of space. + // + // Avoid using (length & s_offsetMask) because it doesn't handle a last page size of s_segmentSize. + var lastPageSize = length - ((_items.Length - 1) << s_segmentShift); + + _items[^1] = new T[lastPageSize]; + _length = length; + } + } + + private SegmentedArray(int length, T[][] items) + { + _length = length; + _items = items; + } + + public bool IsFixedSize => true; + + public bool IsReadOnly => false; + + public bool IsSynchronized => false; + + public int Length => _length; + + public object SyncRoot => _items; + + public ref T this[int index] + { + get + { + return ref _items[index >> s_segmentShift][index & s_offsetMask]; + } + } + + int ICollection.Count => Length; + + int ICollection.Count => Length; + + int IReadOnlyCollection.Count => Length; + + T IReadOnlyList.this[int index] => this[index]; + + T IList.this[int index] + { + get => this[index]; + set => this[index] = value; + } + + object? IList.this[int index] + { + get => this[index]; + set => this[index] = (T)value!; + } + + public object Clone() + { + var items = (T[][])_items.Clone(); + for (var i = 0; i < items.Length; i++) + { + items[i] = (T[])items[i].Clone(); + } + + return new SegmentedArray(Length, items); + } + + public void CopyTo(Array array, int index) + { + for (var i = 0; i < _items.Length; i++) + { + _items[i].CopyTo(array, index + (i * s_segmentSize)); + } + } + + void ICollection.CopyTo(T[] array, int arrayIndex) + { + for (var i = 0; i < _items.Length; i++) + { + ICollection collection = _items[i]; + collection.CopyTo(array, arrayIndex + (i * s_segmentSize)); + } + } + + public Enumerator GetEnumerator() + => new Enumerator(this); + + int IList.Add(object? value) + { + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + void ICollection.Add(T value) + { + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + void IList.Clear() + { + // Matches System.Array + // https://github.com/dotnet/runtime/blob/e0ec035994179e8ebd6ccf081711ee11d4c5491b/src/libraries/System.Private.CoreLib/src/System/Array.cs#L279-L282 + foreach (IList list in _items) + { + list.Clear(); + } + } + + void ICollection.Clear() + { + // Matches `((ICollection)new T[1]).Clear()` + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + bool IList.Contains(object? value) + { + foreach (IList list in _items) + { + if (list.Contains(value)) + return true; + } + + return false; + } + + bool ICollection.Contains(T value) + { + foreach (ICollection collection in _items) + { + if (collection.Contains(value)) + return true; + } + + return false; + } + + int IList.IndexOf(object? value) + { + for (var i = 0; i < _items.Length; i++) + { + IList list = _items[i]; + var index = list.IndexOf(value); + if (index >= 0) + { + return index + i * s_segmentSize; + } + } + + return -1; + } + + int IList.IndexOf(T value) + { + for (var i = 0; i < _items.Length; i++) + { + IList list = _items[i]; + var index = list.IndexOf(value); + if (index >= 0) + { + return index + i * s_segmentSize; + } + } + + return -1; + } + + void IList.Insert(int index, object? value) + { + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + void IList.Insert(int index, T value) + { + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + void IList.Remove(object? value) + { + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + bool ICollection.Remove(T value) + { + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + void IList.RemoveAt(int index) + { + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + void IList.RemoveAt(int index) + { + throw new NotSupportedException(CompilerExtensionsResources.NotSupported_FixedSizeCollection); + } + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + int IStructuralComparable.CompareTo(object? other, IComparer comparer) + { + if (other is null) + return 1; + + // Matches System.Array + // https://github.com/dotnet/runtime/blob/e0ec035994179e8ebd6ccf081711ee11d4c5491b/src/libraries/System.Private.CoreLib/src/System/Array.cs#L320-L323 + if (!(other is SegmentedArray o) + || Length != o.Length) + { + throw new ArgumentException(CompilerExtensionsResources.ArgumentException_OtherNotArrayOfCorrectLength, nameof(other)); + } + + for (var i = 0; i < Length; i++) + { + var result = comparer.Compare(this[i], o[i]); + if (result != 0) + return result; + } + + return 0; + } + + bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer) + { + if (other is null) + return false; + + if (!(other is SegmentedArray o)) + return false; + + if ((object)_items == o._items) + return true; + + if (Length != o.Length) + return false; + + for (var i = 0; i < Length; i++) + { + if (!comparer.Equals(this[i], o[i])) + return false; + } + + return true; + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + _ = comparer ?? throw new ArgumentNullException(nameof(comparer)); + + // Matches System.Array + // https://github.com/dotnet/runtime/blob/e0ec035994179e8ebd6ccf081711ee11d4c5491b/src/libraries/System.Private.CoreLib/src/System/Array.cs#L380-L383 + var ret = 0; + for (var i = Length >= 8 ? Length - 8 : 0; i < Length; i++) + { + ret = Hash.Combine(comparer.GetHashCode(this[i]!), ret); + } + + return ret; + } + + internal TestAccessor GetTestAccessor() + => new TestAccessor(this); + + public struct Enumerator : IEnumerator + { + private readonly T[][] _items; + private int _nextItemSegment; + private int _nextItemIndex; + private T _current; + + public Enumerator(SegmentedArray array) + { + _items = array._items; + _nextItemSegment = 0; + _nextItemIndex = 0; + _current = default!; + } + + public T Current => _current; + object? IEnumerator.Current => Current; + + public void Dispose() + { + } + + public bool MoveNext() + { + if (_items.Length == 0) + return false; + + if (_nextItemIndex == _items[_nextItemSegment].Length) + { + if (_nextItemSegment == _items.Length - 1) + { + return false; + } + + _nextItemSegment++; + _nextItemIndex = 0; + } + + _current = _items[_nextItemSegment][_nextItemIndex]; + _nextItemIndex++; + return true; + } + + public void Reset() + { + _nextItemSegment = 0; + _nextItemIndex = 0; + _current = default!; + } + } + + internal readonly struct TestAccessor + { + private readonly SegmentedArray _array; + + public TestAccessor(SegmentedArray array) + { + _array = array; + } + + public static int SegmentSize => s_segmentSize; + + public T[][] Items => _array._items; + } + } +} diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems index ad62c07b78fd2..9d8cc4e706d9b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems @@ -175,6 +175,8 @@ + + diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensionsResources.resx b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensionsResources.resx index 7cc05f26fb78e..e745a7aa3c7b7 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensionsResources.resx +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensionsResources.resx @@ -270,4 +270,13 @@ Specified sequence has duplicate items + + Segment size must be power of 2 greater than 1 + + + Object is not a array with the same number of elements as the array to compare it to. + + + Collection was of a fixed size. + \ No newline at end of file diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.cs.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.cs.xlf index 99f5196f84d8a..85852734fe3cc 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.cs.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.cs.xlf @@ -17,6 +17,11 @@ Element se stejným klíčem, ale odlišnou hodnotou už existuje. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I Začíná na I @@ -102,6 +107,11 @@ Členové bez pole {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Uspořádat direktivy using @@ -157,6 +167,11 @@ Veřejné nebo chráněné pole {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items Zadané pořadí obsahuje duplicitní položky. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.de.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.de.xlf index 4f029d8975fa7..210b3a8ad2e05 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.de.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.de.xlf @@ -17,6 +17,11 @@ Es ist bereits ein Element mit dem gleichen Schlüssel, jedoch einem anderen Wert vorhanden. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I Beginnt mit I @@ -102,6 +107,11 @@ Nicht-Feldmember {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Using-Direktiven organisieren @@ -157,6 +167,11 @@ Öffentliches oder geschütztes Feld {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items Die angegebene Sequenz weist doppelte Elemente auf. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.es.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.es.xlf index a6b6e91f3d22e..4d0838dcd5b50 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.es.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.es.xlf @@ -17,6 +17,11 @@ Ya existe un elemento con la misma clave pero un valor distinto. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I Empieza por I @@ -102,6 +107,11 @@ Miembros que no son un campo {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Organizar instrucciones Using @@ -157,6 +167,11 @@ Campo público o protegido {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items La secuencia especificada tiene elementos duplicados. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.fr.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.fr.xlf index ce82881aa0220..030d8b4147fda 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.fr.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.fr.xlf @@ -17,6 +17,11 @@ Il existe déjà un élément utilisant la même clé mais une autre valeur. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I Commence par I @@ -102,6 +107,11 @@ Membres autres que des champs {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Organiser les instructions Using @@ -157,6 +167,11 @@ Champ public ou protégé {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items La séquence spécifiée comporte des éléments dupliqués diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.it.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.it.xlf index 536efaf38d664..b22f656d1fd0c 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.it.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.it.xlf @@ -17,6 +17,11 @@ Esiste già un elemento con la stessa chiave ma valore diverso. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I Inizia con I @@ -102,6 +107,11 @@ Membri non di campo {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Organizza using @@ -157,6 +167,11 @@ Campo pubblico o protetto {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items La sequenza specificata contiene elementi duplicati diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ja.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ja.xlf index cce973c31518d..f07b713f316a1 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ja.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ja.xlf @@ -17,6 +17,11 @@ キーが同じで値が異なる要素が既に存在します。 + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I I で始まる @@ -102,6 +107,11 @@ フィールド以外のメンバー {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings using の整理 @@ -157,6 +167,11 @@ パブリックまたは保護されたフィールド {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items 指定されたシーケンスには重複する項目があります diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ko.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ko.xlf index e7f5c5605153e..fae02c00919f7 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ko.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ko.xlf @@ -17,6 +17,11 @@ 키가 같지만 값이 다른 요소가 이미 있습니다. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I I로 시작 @@ -102,6 +107,11 @@ 필드가 아닌 멤버 {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Using 구성 @@ -157,6 +167,11 @@ 공용 또는 보호된 필드 {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items 지정된 시퀀스에 중복 항목이 있습니다. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.pl.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.pl.xlf index 989a377a354f3..4bc2101db1d89 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.pl.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.pl.xlf @@ -17,6 +17,11 @@ Element z tym samym kluczem, ale inną wartością, już istnieje. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I Rozpoczyna się znakiem I @@ -102,6 +107,11 @@ Składowe inne niż pola {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Organizuj użycia @@ -157,6 +167,11 @@ Pole publiczne lub chronione {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items Określona sekwencja zawiera zduplikowane elementy diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.pt-BR.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.pt-BR.xlf index e33efda05aabf..c315169e52930 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.pt-BR.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.pt-BR.xlf @@ -17,6 +17,11 @@ Um elemento com a mesma chave, mas um valor diferente já existe. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I Começa com I @@ -102,6 +107,11 @@ Membros Sem Campo {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Organizar Usos @@ -157,6 +167,11 @@ Campo Protegido ou Público {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items A sequência especificada tem itens duplicados diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ru.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ru.xlf index 7e6dcb498ccec..84f812259ac24 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ru.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.ru.xlf @@ -17,6 +17,11 @@ Элемент с таким ключом, но другим значением уже существует. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I Начинается с I @@ -102,6 +107,11 @@ Не являющиеся полем члены {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Упорядочение Using @@ -157,6 +167,11 @@ Открытое или защищенное поле {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items Указанная последовательность содержит повторяющиеся элементы. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.tr.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.tr.xlf index 8270d7a28e71d..a2bebac8565d2 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.tr.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.tr.xlf @@ -17,6 +17,11 @@ Aynı anahtara, ancak farklı bir değere sahip olan bir öğe zaten var. + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I I ile başlar @@ -102,6 +107,11 @@ Alan Olmayan Üyeler {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings Kullanımları Düzenle @@ -157,6 +167,11 @@ Genel veya Korunan Alan {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items Belirtilen dizide yinelenen öğeler var diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.zh-Hans.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.zh-Hans.xlf index f7e39091dda64..c26ef2a75c051 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.zh-Hans.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.zh-Hans.xlf @@ -17,6 +17,11 @@ 已存在键相同但值不同的元素。 + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I 以 I 开始 @@ -102,6 +107,11 @@ 非字段成员 {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings 组织 Using @@ -157,6 +167,11 @@ 公共或受保护的字段 {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items 指定的序列有重复项 diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.zh-Hant.xlf b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.zh-Hant.xlf index 1b13a6d25d654..2f13058974365 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.zh-Hant.xlf +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/xlf/CompilerExtensionsResources.zh-Hant.xlf @@ -17,6 +17,11 @@ 已經有相同索引鍵但不同值的項目。 + + Object is not a array with the same number of elements as the array to compare it to. + Object is not a array with the same number of elements as the array to compare it to. + + Begins with I 以 I 開頭 @@ -102,6 +107,11 @@ 非欄位成員 {locked:field} + + Collection was of a fixed size. + Collection was of a fixed size. + + Organize usings 組合管理 Using @@ -157,6 +167,11 @@ 公用或受保護欄位 {locked: public}{locked: protected}{locked:field} + + Segment size must be power of 2 greater than 1 + Segment size must be power of 2 greater than 1 + + Specified sequence has duplicate items 指定的序列具有重複項目